You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CWG3046 [dcl.enum] Reading non-representable value from enumeration without fixed underlying type via common initial sequence rule. #732
#include<iostream>
#include<type_traits>enum E { E0 } e;
enum F { F0, F1, F2, F3 };
static_assert(std::is_same_v<std::underlying_type_t<E>, std::underlying_type_t<F>>);
structA { E e; };
structB { F f; };
union U {
A a;
B b;
} u;
booltest() {
return u.a.e == 2;
}
auto ptest = test;
intmain() {
u.b.f = F2;
std::cout << ptest();
}
Assuming the static_assert passes, then because the two enumerations have the same underlying type, they are layout-compatible and therefore it is permitted to use the inactive u.a.e to read the active u.b.f corresponding to it in the common initial sequence. The read should happen as if u.b.f was nominated, meaning it should read the value 2 even if E is not able to represent that value. And therefore this program must print 1.
Is this intentional? It prevents the implementation from optimizing the body of test to return false; as it otherwise could because E can't represent a value of 2. Is the implementation required to special case this enumeration read through union access?
Anyway, the "the behavior is as if the corresponding member of T1 were nominated" part in [class.mem.general] p30 looks defective for this example.
Maybe we can say "as if every possibly recursive subobject of the T2 member of a scalar type had the same object representation as the corresponding subobject of the T1 member"? Then we can infer that there's UB due to invalid object representation ([conv.lval] p3.4).
I don't think it's necessary to talk about object representations. We can just say that two enumerations are not layout-compatible if their ranges are not the same.
We could be even more strict (while remaining C-compatible) by also requiring both enumerations to have the same number of enumerators, with corresponding enumerators in declaration order having the same value. However, that change would not be necessary for resolving this issue, and goes a bit into design territory.
changed the title [-][dcl.enum] Reading non-representable value from enumeration without fixed underlying type via common initial sequence rule.[/-][+]CWG3046 [dcl.enum] Reading non-representable value from enumeration without fixed underlying type via common initial sequence rule.[/+]on Jul 28, 2025
I think both the conditions of same underlying type and same value range are required. I do not see anything forcing the implementation to choose the same underlying type only because the value ranges are the same.
Oh, I found that it was expressed in #39 (comment) that it seems plausible to make an enumeration type layout-compatible with its underlying type.
But the current approach of CWG3046 either conflicts with such intent or potentially makes layout-compatibility not a transitive relationship (after achieving the aforementioned layout-compatibility).
Activity
frederick-vs-ja commentedon Jul 28, 2025
Anyway, the "the behavior is as if the corresponding member of
T1were nominated" part in [class.mem.general] p30 looks defective for this example.Maybe we can say "as if every possibly recursive subobject of the
T2member of a scalar type had the same object representation as the corresponding subobject of theT1member"? Then we can infer that there's UB due to invalid object representation ([conv.lval] p3.4).t3nsor commentedon Jul 28, 2025
I don't think it's necessary to talk about object representations. We can just say that two enumerations are not layout-compatible if their ranges are not the same.
We could be even more strict (while remaining C-compatible) by also requiring both enumerations to have the same number of enumerators, with corresponding enumerators in declaration order having the same value. However, that change would not be necessary for resolving this issue, and goes a bit into design territory.
jensmaurer commentedon Jul 28, 2025
CWG3046
[-][dcl.enum] Reading non-representable value from enumeration without fixed underlying type via common initial sequence rule.[/-][+]CWG3046 [dcl.enum] Reading non-representable value from enumeration without fixed underlying type via common initial sequence rule.[/+]keinflue commentedon Jul 28, 2025
I think both the conditions of same underlying type and same value range are required. I do not see anything forcing the implementation to choose the same underlying type only because the value ranges are the same.
frederick-vs-ja commentedon Nov 26, 2025
Oh, I found that it was expressed in #39 (comment) that it seems plausible to make an enumeration type layout-compatible with its underlying type.
But the current approach of CWG3046 either conflicts with such intent or potentially makes layout-compatibility not a transitive relationship (after achieving the aforementioned layout-compatibility).
jensmaurer commentedon Nov 29, 2025
Adjusted CWG3046 to continue to require "same underlying type".
This is at least conservatively correct; if someone wants more, that's probably a feature paper.