| Issue |
178349
|
| Summary |
(C23) Acessing a constexpr struct through the dot operator does not yield a constant.
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
bragabreno
|
```
#include <stdio.h>
#define comptime_if(predicate, on_true, on_false) \
_Generic \
( \
(char (*)[ 1 + !!(predicate) ]){0}, \
\
char (*)[2]: (on_true), \
char (*)[1]: (on_false) \
)
struct S { int x, y; };
constexpr struct S s = {0, 1};
int main(void)
{
int arr[s.y] = { };
static_assert(s.y);
comptime_if(s.x, puts("true\n"), puts("false\n"));
return 0;
}
```
On Clang, unlike GCC, accessing constexpr structs through the dot operator does not seem to yield a constant.
In the [example above](https://godbolt.org/z/fE787anhq), `arr` is a constant-sized array in GCC but, in Clang, it is a VLA that gets folded into the former (through an extension).
A similar thing happens to the _expression_ in `static_assert` (integer constant in GCC, but non-constant folded into constant in Clang).
This can be seen more clearly in the `comptime_if` macro: such a conversion does not happen there, so the `_Generic` operand has a VLA type which matches both `char (*)[1]` `char (*)[2]`, causing a compilation error (in Clang, but not in GCC).
If I understand it correctly [N3220](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf) seems to agree with the behavior of GCC:
§ 6.6p7:
> An identifier that is:
> — an enumeration constant,
> — a predefined constant, or
> — declared with storage-class specifier constexpr and has an object type,
> is a named constant, as is a postfix _expression_ that applies the . member access operator to a named
> constant of structure or union type, even recursively. For enumeration and predefined constants,
> their value and type are defined in the respective clauses; for constexpr objects, such a named
> constant is a constant _expression_ with the type and value of the declared object.
§ 6.6p13:
> A structure or union constant is a named constant or compound literal constant with structure or
> union type, respectively
§ 6.6p15:
> Starting from a structure or union constant, the member-access . operator may be used to form a
> named constant or compound literal constant as described previously in this subclause
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs