Is reinterpret_cast<char*>(myTypePtr) assumed to point to an array?

喜夏-厌秋 提交于 2020-07-08 01:12:00

问题


We know that char* can alias anything: According to cppreference

Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true: [...] AliasedType is std::byte, char, or unsigned char: this permits examination of the object representation of any object as an array of bytes. [...]

The statement in boldface is not present in n4659 draft [6.10, (8.8)]. Since doing pointer arithmetic on pointers that don't point to elements of the same array is undefined, can we really access bytes other than the first one using only reinterpret_cast? Or maybe std::memcpy must be used for that purpose?


回答1:


auto ptr = reinterpret_cast<char*>(myTypePtr);

The standard permit this conversion, due to:

An object pointer can be explicitly converted to an object pointer of a different type.73 When a prvalue v of object pointer type is converted to the object pointer type “pointer to cv T”, the result is static_­cast<cv T*>(static_­cast<cv void*>(v)). [ Note: Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value.  — end note ]

So, the conversion is equivalent to:

assume myTypePtr has no any cv qualifier.

auto ptr = static_­cast<char*>(static_­cast<void*>(myTypePtr))

And you are permitted to dereference myTypePtr to access the value within the object(the pointer point to), due to:

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

  • a char, unsigned char, or std​::​byte type.

If myTypePtr is not an object of array of char type, as long as you applied addition to ptr, It will result in undefined behavior, due to:

When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements,86 the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[j + p] if 0 ≤ i+j≤n ; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i - j] if 0 ≤ i - j≤n ; otherwise, the behavior is undefined.

For addition or subtraction, if the expressions P or Q have type “pointer to cv T”, where T and the array element type are not similar, the behavior is undefined.

Because the element of myTypePtr is not of type char. Hence applying addition to ptr result in undefined behavior.


Or maybe std::memcpy must be used for that purpose?

Yes, If the object to which myTypePtr point subject to the following rules:

For any object (other than a base-class subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes ([intro.memory]) making up the object can be copied into an array of char, unsigned char, or std​::​byte ([cstddef.syn]).43 If the content of that array is copied back into the object, the object shall subsequently hold its original value.

OR

For any trivially copyable type T, if two pointers to T point to distinct T objects obj1 and obj2, where neither obj1 nor obj2 is a base-class subobject, if the underlying bytes ([intro.memory]) making up obj1 are copied into obj2,44 obj2 shall subsequently hold the same value as obj1.

However, It's unfortunately we can't implement such a memcpy subject to the current standard.



来源:https://stackoverflow.com/questions/62676422/is-reinterpret-castcharmytypeptr-assumed-to-point-to-an-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!