简体   繁体   English

在C ++ 14中,未指定的指针转换如何表现?

[英]How does an unspecified pointer conversion behave in C++14?

The result of some pointer casts are described as unspecified. 某些指针强制转换的结果被描述为未指定。 For example, [expr.static.cast]/13: 例如,[expr.static.cast] / 13:

A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T,” [...] If the original pointer value represents the address A of a byte in memory and A satisfies the alignment requirement of T, then the resulting pointer value represents the same address as the original pointer value, that is, A. The result of any other such pointer conversion is unspecified . 类型为“指向cv1 void的指针”的prvalue可以转换为类型为“指向cv2 T的指针”的prvalue [...]如果原始指针值表示内存中字节的地址A并且A满足对齐要求然后,结果指针值表示与原始指针值相同的地址,即A. 未指定任何其他此类指针转换的结果

My question is: in the case where alignment is not satisfied, what are the possible results? 我的问题是:在比对不满足要求的情况下,有哪些可能的结果?

For example, are the following results permitted? 例如,是否允许以下​​结果?

  • a null pointer 空指针
  • an invalid pointer value (ie pointer which does not point to allocated storage of size T ) 无效的指针值(即指向不指向大小为T分配存储的指针)
  • a valid pointer to a T in a completely separate part of memory 在完全独立的内存部分中指向T的有效指针

Code sample for reference: 代码示例供参考:

#include <iostream>

int main(int argc, char **argv)
{
    int *b = (int *)"Hello, world";   // (1)

    *b = -1;                           // (2)
    std::cout << argc << '\n';
}

Line (1) triggers my above quote from [expr.static.cast]/13 because it is a reinterpret_cast which is covered by [expr.reinterpret.cast]/7 which defines the conversion in terms of static_cast ing through void * . (1)行从[expr.static.cast] / 13触发我的上述引用,因为它是[expr.reinterpret.cast] / 7所涵盖的reinterpret_cast ,它定义了static_cast ing到void *的转换。

If the unspecified result may be an invalid pointer value, then line (1) may cause a hardware trap. 如果未指定的结果可能是无效的指针值,则第(1)可能会导致硬件陷阱。 (Reference: N4430 which clarifies similar wording that was in C++14 and C++11). (参考: N4430 ,它澄清了C ++ 14和C ++ 11中的类似措辞)。

Corollary question: is there any case in which line 1 would cause undefined behaviour? 推论问题:是否有任何情况下第 1行会导致未定义的行为? (I don't think so at this stage; since C++14 invalid pointer value reading is implementation-defined or causes a hardware trap). (我不认为在这个阶段;因为C ++ 14无效指针值读取是实现定义的或导致硬件陷阱)。


Also interesting is that line (2) would in most cases be undefined behaviour due to strict aliasing violation (and perhaps other reasons too), however if the unspecified result may be &argc then this program could output -1 without triggering undefined behaviour! 同样有趣的是,在大多数情况下,由于严格的别名违规(也可能是其他原因),第(2)会是未定义的行为,但是如果未指定的结果可能是&argc则此程序可以输出-1而不会触发未定义的行为!

My question is: in the case where alignment is not satisfied, what are the possible results? 我的问题是:在不满足对齐的情况下,可能的结果是什么?

As far as I can tell N4303: Pointer safety and placement new partially answers this question, although somewhat indirectly. 据我所知N4303:指针安全性和位置新部分地回答了这个问题,虽然有点间接。 This paper refers to CWG issue 1412: Problems in specifying pointer conversions which brought about the changes to [expr.static.cast]/13 that you reference, specifically adding: 本文引用了CWG问题1412:指定指针转换的问题,这些转换导致您引用的[expr.static.cast] / 13的更改,特别是添加:

[...]If the original pointer value represents the address A of a byte in memory and A satisfies the alignment requirement of T, then the resulting pointer value represents the same address as the original pointer value, that is, A. The result of any other such pointer conversion is unspecified.[...] [...]如果原始指针值表示存储器中字节的地址A并且A满足T的对齐要求,则结果指针值表示与原始指针值相同的地址,即A.结果任何其他此类指针转换未指定。[...]

In reference to this change N4303 says ( emphasis mine ): 关于这一变化, N4303说( 强调我的 ):

Prior to the adoption of the resolution for DR 1412 [CWG1412], the value of bp is unspecified at the point of its initialization and its subsequent passing to operator new via the new-expression. 在采用DR 1412 [CWG1412]的分辨率之前,bp的值在其初始化时未指定,并且随后通过new-expression传递给operator new。 Said pointer may be null, insufficiently aligned or otherwise dangerous to use. 所述指针可以是空的,不充分地对齐或者使用其他危险。

So an unspecified conversion can results in: 因此,未指定的转换可能会导致:

  • A null pointer 空指针
  • An insufficiently aligned pointer 指针不完全对齐
  • A pointer that is dangerous to use 一个危险的指针

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM