Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The range of representable values of compound types #5354

Closed
xmh0511 opened this issue Mar 21, 2022 · 7 comments
Closed

The range of representable values of compound types #5354

xmh0511 opened this issue Mar 21, 2022 · 7 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Mar 21, 2022

[expr.pre] p4 states

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

Consider these cases:

struct Type{
   int a = 0;
};
int main(){
   int a = 0;
   char c = *reinterpret_cast<char*>(&a);  // well-defined

   Type obj;
   char c = *reinterpret_cast<char*>(&obj); // UB or well-defined?
}

Since we just specify the range of representable values for fundamental types, as specified in subclause [basic.fundamental]. And, use a glvalue of type char to access the value of an object of any type is well-defined, according to [basic.lval] p11. For the first case, the value 0 is clear in the range of representable values for type char, thus it is well-defined. However, we didn't clearly specify the range of representable values for compound types. So, it is unclear whether the value of obj can be in the range of representable values for type char.

Maybe, we could clearly specify that in [basic.compound], as the following?

the value of an object of type cv1 T where discards the cv-qualification signature(if any) of T results in a type that is a compound type that is an object type is considered to be only in the range of representable values for cv2 U where cv1 T is similar to cv2 U.

And improve [expr.pre] p4 to

If during the evaluation of an expression, the result is not mathematically defined or its value is not in the range of representable values for its type, the behavior is undefined.

Since we define that an object holds a value of type T in [basic.types.general]. So, saying an object is not in the range of representable values for its type does not make sense.

@jensmaurer
Copy link
Member

No.

[expr.pre] only applies to built-in types. Your example is well-defined, because you're looking at the object representation of "obj", and [basic.fundamental] p7 says "For narrow character types, each possible bit pattern of the object representation represents a distinct value."

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 21, 2022

An object of type char is not pointer-interconvertible with an object of type Type, the pointer value still points to the original object obj.

For narrow character types, each possible bit pattern of the object representation represents a distinct value.

It just seems to phrase something regarding the object of narrow character types. For this issue, I discussed with @languagelawyer, he may have a different opinion.

@jensmaurer
Copy link
Member

Whatever is happening here, the intent of the wording here is certainly not to convert obj to a char type. As I said, we instead want to inspect the object representation and/or apply the aliasing exception for char.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 21, 2022

[expr.unary.op] p1 states

the result is an lvalue referring to the object or function to which the expression points.

The expression reinterpret_cast<char*>(&obj) points to obj, the result is an lvalue referring to obj(its evaluation determines the identity of an object). So, how would inspect the object representation?

@frederick-vs-ja
Copy link
Contributor

frederick-vs-ja commented Mar 21, 2022

[expr.unary.op] p1 states

the result is an lvalue referring to the object or function to which the expression points.

The expression reinterpret_cast<char*>(&obj) points to obj, the result is an lvalue referring to obj(its evaluation determines the identity of an object). So, how would inspect the object representation?

This is a known issue and may be resolved by P1839.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 21, 2022

This is a known issue and may be resolved by P1839.

Right, I have read that paper before. I think this may be a temporary fix before merging that paper. As specified in that paper, the current draft just thinks the second case is UB.

@jensmaurer
Copy link
Member

I think this may be a temporary fix before merging that paper.

Your suggested change would go in the wrong direction, because it suggests there is an int -> char conversion going on. The intent is that there is not, but I appreciate the status quo wording is unhelpful in that regard.

I'm not seeing a small fix proposed in this conversation that could be applied with little effort, and there is certainly nothing proposed here that might be construed as editorial.

As CWG chair, I notice that P1839 addresses the area of concern, so it seems wasteful to invest time into a core issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants