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
Consider whether or not reinterpret_cast<const int**>((const int(*)[])0) is valid, which requires that the type const int(*)[] does not cast away constness in a conversion to the type const int** due to [expr.reinterpret.cast]/2. This has three possible values of n for different-qualification decompositions to consider with T1 being const int(*)[] and T2 being const int**:
n=0, cv01 and cv02 are both empty, U1 is the type const int(*)[], and U2 is the type const int**. Changing each cvi1 to cvi2 has no effect here, so a qualification conversion is valid.
n=1, cv01 and cv02 are both empty, P01 and P02 are both "pointer to", cv11 is either const or empty, cv12 is empty, U1 is either the type int[] or the type const int[], and U2 is the type const int*. If [conv.qual] Adding const with pointers to arrays in the qualification-combined type #987 is resolved as not allowing U1 to be the type const int[] then U1 is definitely the type int[] and cv11 is definitely const. Otherwise, if U1 is the type int[] then cv11 must be const. If U1 is the type int[] then changing cv11 to cv12 does have an effect here and causes the qualification conversion to be invalid. If U1 is the type const int[] and cv11 is empty then changing each cvi1 to cvi2 has no effect here, so a qualification conversion is valid. If U1 is the type const int[] and cv11 is const then changing cv11 to cv12 removes the const but it is unclear whether or not the const is actually removed from the resulting type because U1 is still const, so it is unclear whether or not the qualification conversion is valid.
n=2, cv01 and cv02 are both empty, P01 and P02 are both "pointer to", P11 is "array of unknown bound of", P12 is "pointer to", cv11 and cv21 are either both empty or both const, cv12 is empty, cv22 is either const or empty, U1 is either the type int or const int, and U2 is either the type int or const int. If [conv.qual] Adding const with pointers to arrays in the qualification-combined type #987 is resolved as not allowing either U1 or U2 to be the type const int, then U1 and U2 are definitely both the type int. Otherwise, if U1 is the type int then cv11 and cv21 must both be const, and if U2 is the type int then cv22 must be const (this second if is not intended to be dependent upon the first if). If U1 is the type int and cv22 is const then changing cv11 to cv12 removes the const but it is unclear whether or not the const is actually removed from the resulting type because cv21 is still const, so it is unclear whether or not the qualification conversion is valid. If U1 is the type int and cv22 is empty then changing cv11 and cv21 to cv12 and cv22 respectively does have an effect here and causes the qualification conversion to be invalid. If U1 is the type const int and cv11 and cv21 are both empty then changing each cvi1 to cvi2 has either no effect or redundantly adds const, so a qualification conversion is valid. If U1 is the type const int and cv11 and cv21 are both const then changing cv11 to cv12 removes the const and changing cv21 to cv22 removes a second const if cv22 is empty but it is unclear whether or not the const is actually removed from the resulting type because U1 is still const and if cv22 is const then the const of cv12 will remain, so it is unclear whether or not the qualification conversion is valid.
Second, consider the whether or not the reverse reinterpret_cast<const int(*)[]>((const int**)0) is valid. This has three possible values of n for different qualification-decompositions to consider with T1 being const int** and T2 being const int(*)[]:
n=0, cv01 and cv02 are both empty, U1 is the type const int**, and U2 is the type const int(*)[]. Changing each cvi1 to cvi2 has no effect here, so a qualification conversion is valid.
n=1, cv01 and cv02 are both empty, P01 and P02 are both "pointer to", cv11 is empty, cv12 is either const or empty, U1 is the type const int*, and U2 is either the type int[] or the type const int[]. If [conv.qual] Adding const with pointers to arrays in the qualification-combined type #987 is resolved as not allowing U2 to be the type const int[] then U2 is definitely the type int[] and cv12 is definitely const. Otherwise, if U2 is the type int[] then cv12 must be const. In any scenario changing each cvi1 to cvi2 has no effect here or adds const, so a qualification conversion is valid.
n=2, cv01 and cv02 are both empty, P01 and P02 are both "pointer to", P11 is "pointer to", P12 is "array of unknown bound of", cv11 is empty, cv21 is either const or empty, cv12 and cv22 are either both empty or both const, U1 is either the type int or const int, and U2 is either the type int or const int. If [conv.qual] Adding const with pointers to arrays in the qualification-combined type #987 is resolved as not allowing either U1 or U2 to be the type const int, then U1 and U2 are definitely both the type int. Otherwise, if U1 is the type int then cv21 must be const, and if U2 is the type int then cv12 and cv22 must both be const (this second if is not intended to be dependent upon the first if). If cv12 and cv22 are both const then changing each cvi1 to cvi2 does have an effect here and causes the qualification conversion to be valid. If U1 is the type int and cv12 and cv22 are both empty then changing cv21 to cv22 does have an effect here and causes the qualification conversion to be invalid. If U1 is the type const int, cv21 is empty, and cv12 and cv22 are both empty then changing each cvi1 to cvi2 has no effect here, so a qualification conversion is valid. If U1 is the type const int, cv21 is const, and cv12 and cv22 are both empty then changing cv21 to cv22 removes the const but it is unclear whether or not the const is actually removed from the resulting type because U1 is still const, so it is unclear whether or not the qualification conversion is valid.
There is disagreement among implementations as to whether or not these casts are valid. What was the intent for these two cases? Specifically, if one const is removed from an array type in a qualification-decomposition of it where const is specified multiple times does that actually remove the const or does it need to be removed from all levels for the const to actually be removed?
Full name of submitter (unless configured in github; will be published with the issue): Jay Ghiron
Reference (section label): [expr.const.cast]/6
Issue description:
Consider whether or not
reinterpret_cast<const int**>((const int(*)[])0)is valid, which requires that the typeconst int(*)[]does not cast away constness in a conversion to the typeconst int**due to [expr.reinterpret.cast]/2. This has three possible values of n for different-qualification decompositions to consider with T1 beingconst int(*)[]and T2 beingconst int**:const int(*)[], and U2 is the typeconst int**. Changing each cvi1 to cvi2 has no effect here, so a qualification conversion is valid.int[]or the typeconst int[], and U2 is the typeconst int*. If [conv.qual] Adding const with pointers to arrays in the qualification-combined type #987 is resolved as not allowing U1 to be the typeconst int[]then U1 is definitely the typeint[]and cv11 is definitely const. Otherwise, if U1 is the typeint[]then cv11 must be const. If U1 is the typeint[]then changing cv11 to cv12 does have an effect here and causes the qualification conversion to be invalid. If U1 is the typeconst int[]and cv11 is empty then changing each cvi1 to cvi2 has no effect here, so a qualification conversion is valid. If U1 is the typeconst int[]and cv11 is const then changing cv11 to cv12 removes the const but it is unclear whether or not the const is actually removed from the resulting type because U1 is still const, so it is unclear whether or not the qualification conversion is valid.intorconst int, and U2 is either the typeintorconst int. If [conv.qual] Adding const with pointers to arrays in the qualification-combined type #987 is resolved as not allowing either U1 or U2 to be the typeconst int, then U1 and U2 are definitely both the typeint. Otherwise, if U1 is the typeintthen cv11 and cv21 must both be const, and if U2 is the typeintthen cv22 must be const (this second if is not intended to be dependent upon the first if). If U1 is the typeintand cv22 is const then changing cv11 to cv12 removes the const but it is unclear whether or not the const is actually removed from the resulting type because cv21 is still const, so it is unclear whether or not the qualification conversion is valid. If U1 is the typeintand cv22 is empty then changing cv11 and cv21 to cv12 and cv22 respectively does have an effect here and causes the qualification conversion to be invalid. If U1 is the typeconst intand cv11 and cv21 are both empty then changing each cvi1 to cvi2 has either no effect or redundantly adds const, so a qualification conversion is valid. If U1 is the typeconst intand cv11 and cv21 are both const then changing cv11 to cv12 removes the const and changing cv21 to cv22 removes a second const if cv22 is empty but it is unclear whether or not the const is actually removed from the resulting type because U1 is still const and if cv22 is const then the const of cv12 will remain, so it is unclear whether or not the qualification conversion is valid.Second, consider the whether or not the reverse
reinterpret_cast<const int(*)[]>((const int**)0)is valid. This has three possible values of n for different qualification-decompositions to consider with T1 beingconst int**and T2 beingconst int(*)[]:const int**, and U2 is the typeconst int(*)[]. Changing each cvi1 to cvi2 has no effect here, so a qualification conversion is valid.const int*, and U2 is either the typeint[]or the typeconst int[]. If [conv.qual] Adding const with pointers to arrays in the qualification-combined type #987 is resolved as not allowing U2 to be the typeconst int[]then U2 is definitely the typeint[]and cv12 is definitely const. Otherwise, if U2 is the typeint[]then cv12 must be const. In any scenario changing each cvi1 to cvi2 has no effect here or adds const, so a qualification conversion is valid.intorconst int, and U2 is either the typeintorconst int. If [conv.qual] Adding const with pointers to arrays in the qualification-combined type #987 is resolved as not allowing either U1 or U2 to be the typeconst int, then U1 and U2 are definitely both the typeint. Otherwise, if U1 is the typeintthen cv21 must be const, and if U2 is the typeintthen cv12 and cv22 must both be const (this second if is not intended to be dependent upon the first if). If cv12 and cv22 are both const then changing each cvi1 to cvi2 does have an effect here and causes the qualification conversion to be valid. If U1 is the typeintand cv12 and cv22 are both empty then changing cv21 to cv22 does have an effect here and causes the qualification conversion to be invalid. If U1 is the typeconst int, cv21 is empty, and cv12 and cv22 are both empty then changing each cvi1 to cvi2 has no effect here, so a qualification conversion is valid. If U1 is the typeconst int, cv21 is const, and cv12 and cv22 are both empty then changing cv21 to cv22 removes the const but it is unclear whether or not the const is actually removed from the resulting type because U1 is still const, so it is unclear whether or not the qualification conversion is valid.There is disagreement among implementations as to whether or not these casts are valid. What was the intent for these two cases? Specifically, if one const is removed from an array type in a qualification-decomposition of it where const is specified multiple times does that actually remove the const or does it need to be removed from all levels for the const to actually be removed?