I was messing around with C and discovered an apparent bug in GCC:
#include <stdio.h>
int y = (1, 2);
int main()
{
return 0;
}
in gcc gives error: initializer element is not constant
while it works fine in clang. And as expected, putting the declaration inside the main()
function also works with both compilers.
The parentheses are necessary, as otherwise gcc would be correct in disallowing the comma operator.
Despite the gcc code snippet looking like this:
3 | int y = (1, 2);
| ^
the parentheses are not the problem. int y = (1 + 2);
works fine.
I know that the comma operator is never necessary in constant expressions, as there should never be any side effects, but it's still odd that GCC sees it as an error instead of just printing warning: expression result unused
(which it also does).
Is this a bug?
Per the standard, comma operator is not allowed in constant expressions, but clang admits it in most (but not all) contexts. For example:
int a = (1,2); //accepts
int b[(1,2)]; // warns: VLA folded to constant size array
_Static_assert((1,2), "oops!"); // fails
struct
{
int c : (1,2); // accepts
int d [(1,2)]; // warns: VLA folded to constant size array
} e;
enum { FOO = (1,2) }; //accepts
int _Alignas((2,16)) f; // fails
int* g = (1,0); // warns: integer to pointer conversion
// so this is not a null pointer constant,
// but still a constant expression (because the
// initialisation is accepted)!
gcc rejects all of these constructs.
The standard does allow an implementation to accept other forms of constant expressions though, but it isn't clear if these other forms should be documented or how they should be admitted in different contexts.
There is a clang bug about clang sometimes treating comma as allowed in constant expressions.