reinterpret_cast<char*>(myTypePtr) 是否假设指向一个数组?
Is reinterpret_cast<char*>(myTypePtr) assumed to point to an array?
我们知道 char*
可以为任何东西起别名:根据 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. [...]
n4659 草案 [6.10, (8.8)] 中没有粗体字的声明。
由于对不指向同一数组元素的指针进行指针运算是未定义的,我们真的可以仅使用 reinterpret_cast
访问第一个字节以外的字节吗?
或者也许 std::memcpy
必须用于该目的?
auto ptr = reinterpret_cast<char*>(myTypePtr);
标准允许这种转换,原因是:
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 ]
因此,转换等同于:
assume myTypePtr
has no any cv qualifier.
auto ptr = static_cast<char*>(static_cast<void*>(myTypePtr))
并且您可以取消引用 myTypePtr
以访问对象内的值(指针指向),原因是:
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.
如果myTypePtr
不是char类型数组的对象,只要你对ptr
应用加法,就会导致未定义的行为,原因是:
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.
因为myTypePtr
的元素不是char类型。因此,将加法应用于 ptr
会导致未定义的行为。
Or maybe std::memcpy must be used for that purpose?
是的,如果myTypePtr
指向的对象遵守以下规则:
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.
或
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.
但是,很遗憾,我们无法根据当前标准实施这样的 memcpy
。
As std::as_bytes
and std::as_writable_bytes
essentially depend on such usage (which is specified in [span.objectrep]),我想我们可以假设它是受支持的,即使根据 C++17/20(和最新的工作草案)它不是真的。
此缺陷已被 P1839 揭示,遗憾的是,尚未解决。
我们知道 char*
可以为任何东西起别名:根据 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
, orunsigned char
: this permits examination of the object representation of any object as an array of bytes. [...]
n4659 草案 [6.10, (8.8)] 中没有粗体字的声明。
由于对不指向同一数组元素的指针进行指针运算是未定义的,我们真的可以仅使用 reinterpret_cast
访问第一个字节以外的字节吗?
或者也许 std::memcpy
必须用于该目的?
auto ptr = reinterpret_cast<char*>(myTypePtr);
标准允许这种转换,原因是:
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 ]
因此,转换等同于:
assume
myTypePtr
has no any cv qualifier.
auto ptr = static_cast<char*>(static_cast<void*>(myTypePtr))
并且您可以取消引用 myTypePtr
以访问对象内的值(指针指向),原因是:
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.
如果myTypePtr
不是char类型数组的对象,只要你对ptr
应用加法,就会导致未定义的行为,原因是:
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.
因为myTypePtr
的元素不是char类型。因此,将加法应用于 ptr
会导致未定义的行为。
Or maybe std::memcpy must be used for that purpose?
是的,如果myTypePtr
指向的对象遵守以下规则:
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.
或
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.
但是,很遗憾,我们无法根据当前标准实施这样的 memcpy
。
As std::as_bytes
and std::as_writable_bytes
essentially depend on such usage (which is specified in [span.objectrep]),我想我们可以假设它是受支持的,即使根据 C++17/20(和最新的工作草案)它不是真的。
此缺陷已被 P1839 揭示,遗憾的是,尚未解决。