Liste des Groupes | Revenir à cl c |
Andrey Tarasevich <noone@noone.net> writes:Compilers don't have to follow the behaviour specified by the standard in a "direct translation" manner in order to be correct and conforming. They have to generate code that in the absence of any attempt to execute something with undefined behaviour, will give the same observable behaviour as a "direct translation" would.
On Sun 5/4/2025 6:48 AM, Tim Rentsch wrote:The last sentence there is not present in N1570. Apparently it was
>>One dark corner this feature has, is that in C (as opposed to C++) the>
result of an assignment operator is an rvalue, which can easily lead
to some interesting consequences related to structs with arrays
inside.
I'm curious to know what interesting consequences you mean here. Do
you mean something other than cases that have undefined behavior?
I'm referring to the matter of the address identity of the resultant
rvalue object. At first, "address identity of rvalue" might sound
strange, but the standard says that there's indeed an object tied to
such rvalue, and once we start applying array-to-pointer conversion
(and use `[]` operator), lvalues and addresses quickly come into the
picture.
>
The standard says in 6.2.4/8:
>
"A non-lvalue expression with structure or union type, where the
structure or union contains a member with array type [...]
refers to an object with automatic storage duration and temporary
lifetime. Its lifetime begins when the expression is evaluated and its
initial value is the value of the expression. Its lifetime ends when
the evaluation of the containing full expression ends. [...] Such an
object need not have a unique address."
https://port70.net/~nsz/c/c11/n1570.html#6.2.4p8
introduced later, in C17. (My appreciation to Keith Thompson for
reporting this.)
I wondering what the last sentence is intended to mean ("... need notAhh, I see now what your concern is.
have a unique address"). At the first sight, the intent seems to be
obvious: it simply says that such temporary objects might repeatedly
appear (and disappear) at the same location in storage, which is a
natural thing to expect.
But is it, perhaps, intended to also allow such temporaries to haveMy reading of the post-C11 standards is that they allow the "new"
addresses identical to regular named objects? It is not immediately
clear to me.
object to overlap with already existing objects, including both
declared objects and objects whose storage was allocated using
malloc().
And when I make the following experiment with GCC and ClangYeah.
>
#include <stdio.h>
>
struct S { int a[10]; };
>
int main()
{
struct S a, b = { 0 };
int *pa, *pb, *pc;
>
pa = &a.a[5];
pb = &b.a[5];
pc = &(a = b).a[5];
>
printf("%p %p %p\n", pa, pb, pc);
}
>
I consistently get the following output from GCC
>
0x7fff73eb5544 0x7fff73eb5574 0x7fff73eb5544
>
And this is what I get from Clang
>
0x7ffd2b8dbf44 0x7ffd2b8dbf14 0x7ffd2b8dbee4
>
As you can see, GCC apparently took C++-like approach to this
situation. The returned "temporary" is not really a separate temporary
at all, but actually `a` itself.
Meanwhile, in Clang all three pointers are different, i.e. ClangWhich in my reading of the standard is required under C11 rules.
decided to actually create a separate temporary object for the result
of the assignment.
I have reproduced your results under -std=c11 -pedantic, for both
gcc and clang.
I have a strong feeling that GCC's behavior is non-conforming. TheMy judgment is that the behavior under gcc is non-conforming if the
last sentence of 6.2.4/8 is not supposed to permit "projecting" the
resultant temporaries onto existing named objects. I could be wrong...
compilation was done using C11 semantics. Under C17 or later rules
the gcc behavior is allowed (and may have been what prompted the
change in C17, but that is just speculation on my part). In any
case I understand now what you were getting at. Thank you for
bringing this hazard to the group's attention.
I hope someone files a bug report for gcc using -std=c11 rules,
because what gcc does under that setting (along with -pedantic)
is surely at odds with the plain reading of the C11 standard,
for the situation being discussed here.
Editorial comment: here is yet another case where post-C11 changes
to the C standard seem ill advised, and another reason not to use
any version of the ISO C standard for C17 or later. And it's
disappointing that gcc -std=c11 -pedantic strays into the realm of
non-conforming behavior.
Les messages affichés proviennent d'usenet.