This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Assignment operator


> From: Zoltan Kocsi <zoltan@bendor.com.au>
> Date: Tue, 12 Oct 1999 15:45:41 +1000 (EST)
> To: Mike Stump <mrs@mail.wrs.com>

>  > If GNU C accesses it, that is a bug.  
>  
> Well, unfortunately, it is not a bug, it is a feature, which is in
> accordance to the current and future ANSI C standard. On the other
> hand, it would be in accordance with the standard if it did not
> access the LHS. The standard leaves it to the implementor. This is
> actually independent of the possible qualifiers of the LHS.

I am afraid you lost me on that one.  If you meant to say that GNU C
is allowed to access it by the standard, then we will simply have
disagree.  I found the C standard to be exceptionally clear on this
point.

>  > > If this was not the case, then of course, the usual strcpy construct
>  > 
>  > >    while ( *a++ = *b++ );
>  > >    
>  > > would not work since strcpy is defined to terminate on the source 
>  > > string. Egcs, for example generates read-back of '*a' even if it 
>  > > is not volatile, therefore if you try to copy the string to a
>  > > write-only or volatile buffer, egcs will blow into your face. 
>  > 
>  > Sorry, the signature of strcpy does not contain volatile.  The
>  > implementation is free to optimize it in ways you cannot begin to
>  > understand (and it does).  Get used to it.  So, since strcpy has zero
>  > to do with volatile, we can skip everything you said about it.

> Well, this is not exactly true.

> strcpy() has nothing to do with volatile but it is defined to stop
> when the '\0' in the *source* string is processed.
>         move.b (%a1)+,(%a0)    //   *dst = *src++;
>         tst.b (%a0)+           // while ( *dst++ );
>  
> As you can see, it will terminate when it reads back a '\0' from 
> the *target* string. 

Please cite the standard where it guarantees that *dst is different
from *src.  I wasn't aware of that requirement.  If they fail to be
different, then the optimizer is free to optimize *src into *dst.

Let me quote from the standard:

1 The semantic descriptions in  this  International  Standard  define  a
  parameterized  nondeterministic  abstract machine.  This International
  Standard  places  no  requirement  on  the  structure  of   conforming
  implementations.   In  particular,  they  need not copy or emulate the
  structure of the abstract machine.  Rather, conforming implementations
  are required to emulate (only) the observable behavior of the abstract
  machine as explained below.3)                                           |
  __________________________
  3) This provision is sometimes  called  the  as-if  rule,  because  an
  implementation is free to disregard any requirement of the Standard as
  long as the result is  as if the requirement had been obeyed,  as  far
  as can be determined from the observable behavior of the program.

I predict you will fail to find the requirement.

>  > > In addition, consider the following cases:
>  > 
>  > >   char a, c;
>  > >   volatile char * volatile b; 
>  > 
>  > >   a = *b = c;
>  > 
>  > > You get 'c', fetch 'b', store the value of 'c' to '*b'. Now the
>  > > standard says "... the value of the left hand operand ...". The left
>  > > hand operand is *b. Since b is volatile, you should re-fetch 'b' as
>  > > well,

Oh, sorry, I misunderstood your point, my fault.  I was thinking *b.
No b should not be refetched.  For the same reason that *foo() should
not call foo twice.  I tried to find the wording in the paper, but
didn't locate it.  If it fails to be there, this is a bug in the
standard.  The wording would be something like, address
expressions are only calculated once.

>  > > No, you don't. The compiler has every right to generate as many write
>  > > and read accesses to volatile objects as it likes, even in the simple
>  > > x = 0; construct. 
>  > 
>  > Hogwash.

> Might be, but true. The C standard

I already spoke to the point of volatile and C, no need to repeat it.
In the above, I was talking about the semantics that gcc will
implement and the semantics required by ANSI C++.

> currently does not tell you that you can't access an object more
> times or less times than it occurs in an expression

Let me quote from the standard:

6 The observable behavior of the abstract machine  is  its  sequence  of
  reads   and   writes  to  volatile  data

There it is, in black and white. What do you think the words mean?

> Is that so ? The C standard says this, in the definition of volatile:

Yeah, you missed the `If GNU C accesses it, that is a bug.  If that is
the only language you're talking about, you can stop reading (for the
most part).' at the top.  What I wrote is from the C++ side.  I should
have made that clearer, sorry for failing to do that.

>  > You're confused, the type of memcpy isn't a pointer to a volatile
>  > character.  This has zero to do with what we are talking about.

> What's even more scary is that it has every right to do so.

Right.

> With or without volatile qualifiers, actually.

Well, with volatile, in C, it can't access.  For C++ and volatile, I
agree.

>  > Hogwash, get real.  Let's pick a sparc, and let's pick 32 bit ints
>  > (aligned).  The machine will issue a single load or store for the int,
>  > and you can be sure.  I would call that very portable programming.

> You mean it is guaranteed by the standard ?

I'll go out on a limb, and say sure.  Though, I reserve the right to
surprise you with what the C++ standard says.  For x=a; it says there
will be one read to a, and one write to x.  No more, no less, and in
that exact order.  No other possibility exists.  What you're thinking
is that `one read' isn't defined.  That is right, it isn't, this is
where a 16 port maintainer gets to define one 32 bit read as two 16
bit read bus cycles, with a little luck, he will even define which
subword is read first.

You might be able to nit pick, and claim the exact wording doesn't say
that in exacting detail, but I would claim this is what the words
written mean.

>  > volatile int i;

> I would still argue with you in a few details.

> On one hand, if 'i' is a memory mapped hardware register,

This isn't the example I posted, not the example I was talking about.
For different examples, I have different answers.

> for example, then it is questionable whether the answer '1' would
> turn out.  This is of course nitpicking but it amuses unqualified
> personnel.

:-)  We agree.  I have fun with this stuff, I hope you are...

> The real problem is that the compiler has every right to read 'i'
> after it has written the 1 into it and read 'i' more than one times 
> before calling printf().

Again I was talking about C++.  No.  See above.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]