N
Netocrat
Any comments on the correctness of the statements 1, 2a, 2b, 3 and 4 in
the code below?
If they are correct, then the definition of an object as well as that of
an lvalue is broken in C99 by the following reasoning:
foo() does not return an object, so the return of foo() conceptually is
not stored, yet we are able to obtain a pointer to one of its member
elements, therefore it must be stored, therefore foo() does return an
object, which is a contradiction.
6.5.2.2#5 prevents us from storing and later using foo().ar anyhow, but
C99 seems to be confused about whether conceptually a function returns
something that is stored (Stan Tobias's concept of a temporary variable)
or is just a value.
Both gcc and como online compile this code in strict C99 mode, and both
fault in C90 mode. Como online accepts foo().ar as an isolated statement
but not as an argument to printf.
#include <stdio.h>
struct s {char ar[3];} foo(void)
{
struct s s = {"ab"};
return s;
}
int main (void)
{
/* 1. C90/C99 prohibit this because foo()'s return is not an
* object - 6.8.6.4#3 refers to "the value of the function call"
* rather than "the object returned by the function call". However
* by C99's broken definition it is unintentedly an lvalue */
/* &foo(); */
/* 2a. By C90 foo().ar is not an lvalue so we can't take its
* address.
* 2b. By C99's broken definition it is an lvalue but not an
* object. 6.5.2.3#1 specifically allows foo().ar and
* 6.5.2.3#3 confirms that it is an lvalue */
/* &foo().ar; */
/* 3. By C99, ar decays to char* because of a wording change in
* 6.3.2.1#3 from "lvalue that has type" to "expression that has
* type" so this is valid */
foo().ar;
/* 4. As for (3) */
&foo().ar[0];
/* With gcc in C99 mode this compiles, runs and prints the
* 2 ptrs */
printf("%p\n", (void *)&foo().ar[0]);
printf("%p\n", (void *)foo().ar);
return 0;
}
the code below?
If they are correct, then the definition of an object as well as that of
an lvalue is broken in C99 by the following reasoning:
foo() does not return an object, so the return of foo() conceptually is
not stored, yet we are able to obtain a pointer to one of its member
elements, therefore it must be stored, therefore foo() does return an
object, which is a contradiction.
6.5.2.2#5 prevents us from storing and later using foo().ar anyhow, but
C99 seems to be confused about whether conceptually a function returns
something that is stored (Stan Tobias's concept of a temporary variable)
or is just a value.
Both gcc and como online compile this code in strict C99 mode, and both
fault in C90 mode. Como online accepts foo().ar as an isolated statement
but not as an argument to printf.
#include <stdio.h>
struct s {char ar[3];} foo(void)
{
struct s s = {"ab"};
return s;
}
int main (void)
{
/* 1. C90/C99 prohibit this because foo()'s return is not an
* object - 6.8.6.4#3 refers to "the value of the function call"
* rather than "the object returned by the function call". However
* by C99's broken definition it is unintentedly an lvalue */
/* &foo(); */
/* 2a. By C90 foo().ar is not an lvalue so we can't take its
* address.
* 2b. By C99's broken definition it is an lvalue but not an
* object. 6.5.2.3#1 specifically allows foo().ar and
* 6.5.2.3#3 confirms that it is an lvalue */
/* &foo().ar; */
/* 3. By C99, ar decays to char* because of a wording change in
* 6.3.2.1#3 from "lvalue that has type" to "expression that has
* type" so this is valid */
foo().ar;
/* 4. As for (3) */
&foo().ar[0];
/* With gcc in C99 mode this compiles, runs and prints the
* 2 ptrs */
printf("%p\n", (void *)&foo().ar[0]);
printf("%p\n", (void *)foo().ar);
return 0;
}