Alan W. Irwin wrote:
> On 2008-12-14 14:02-0800 Alan W. Irwin wrote:
> 
>> [...]This patch is only part of the story.
> 
> --- drivers/xfig.c      2008-12-14 14:40:29.000000000 -0800
> +++ drivers/xfig.c~     2008-12-14 12:31:45.000000000 -0800
> @@ -414,7 +414,7 @@
>   flushbuffer(PLStream *pls)
>   {
>     PLDev *dev = pls->dev;
> -  int i = 0;
> +  short i = 0;
> 
>     if (count == 0)
>       return;
> 
> If you put the above patch on top of the previous one, everything now
> works fine with example 27.  The resulting file size is reasonable (3.7M)
> and gives reasonable looking results with xfig.  However, could some
> C expert here interpret

> *(buffptr + count++) = x1;

For sake of clarity later I will use the variable K instead of count.
ie *(buffptr + K++) = x1

T
The short answer 
----------------
The expression  is equivalent to
1.  short* tempPtr = buffptr+K    
2.  K = K+1
3.  *tempPtr = x1

Expression 1 is evaluated using Pointer arithmetic and points to an address K 
short ints from buffptr  
Expression 2 comes from applying the post increment operator ++ to K
Expression 3 stores the value x1 at the address tempPtr.


The longer answer
-----------------

This is equivalent to 
  *tempPtr  = x1
where tempPtr is evaluated as (buffptr + K++)

Ignoring the ++ operator for the moment
the expression  (buffptr + K ) is an example of Pointer arithmetic.
 
In pointer arthmetic, as buffptr is of type short, the result of the 
expression (buffptr + K) is a pointer which is the address K short 
integers from buffptr. 

eg if buffptr is 9000, a short integer is 2 bytes long  and K is 36
the address returned is 9000 +36*2 ie 9072

In general if buffptr is a pointer of type T (buffptr + K) returns 
the address
     buffptr + K*sizeof(T) 

eg  if buffptr is a double*
     (buffptr + K) = buffptr+K*sizeof(double)
                   = buffptr+K*8

For completeness returning to the ++ operator ie K++

The ++ follows the K which means it is the post increment operator.
This means use the current value of K in the expression (buffptr + K) 
and then increment it. eg if K is 10 the expression (buffptr + K)
 is evaluated as (buffptr +10). Then K is incremented.

Finally having evaluated tempPtr = buffptr + K
  *tempPtr = x1 
stores the value of x1 at the address tempPtr
 
> For the svn trunk version, count is a short (the source of the original
> problem), but I am concerned that if you turn it into an int (as demanded by
> example 27) some implicit casting is going on in statements like above that
> may not work properly for all compilers.

> If you add an int to a pointer to a short is the result always a pointer to
> a short? 
Yes

> What is the syntax for doing all casting explicitly with the above
> statement (so I will better understand it in future)?
It would be  

  *( (short*)(buffptr + (int)count++) ) = x1

(Perhaps the int should be a long or long long or int64t on 64bit machines)

However once you understand pointer arithmetic there should be no need
for explicit casting as the resulting pointer retains the same type as
the orginal pointer.

More importantly you would make the code fragile. In the event
that someone changed the type of buffptr and x1 they would have to
change all the statements that were explicitly typed.

Alternatively the code could be rewritten to use pointers instead of count
so the expressions would become 
    *insertPtr++ = x1
    *insertPtr++ = y1
etc.


Xfig Example 27 bug now fixed
-------------------
Returning to the bug shown in example 27 I think you have fixed the bug.
As you discovered, short ints count and bufflen were overflowing and
wrapping round to negative numbers.

After your first fix and prior to your second fix (making i an int as
well) the while loop in function flushbuffer would have gone into an
infinite loop filling the disk.

The loop is 
   i=0
   while (i<count) {
      ...
      i+=2
   }

For large values of (int) count, i being a short would overflow and
wrap around to a negative number and never reach count.


Kind regards


Terrence


      

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel

Reply via email to