Bar*_*rry 51 c++ language-lawyer c++11 c++17
cppreference †声明:
具有普通默认构造函数的对象可以通过
reinterpret_cast在任何适当对齐的存储上使用来创建,例如在分配有的存储器上std::malloc.
这意味着以下是明确定义的代码:
struct X { int x; };
alignas(X) char buffer[sizeof(X)]; // (A)
reinterpret_cast<X*>(buffer)->x = 42; // (B)
Run Code Online (Sandbox Code Playgroud)
以下是三个问题:
X开始的生命周期是什么时候?如果在线(B),它是否被视为获取存储?如果在线(A),如果有一个分支(A)和(B)有条件地构建一个X或其他一些pod,Y怎么办?†请注意,这是一个旧链接.针对这个问题,措辞发生了变化.它现在写道:
但是,与C不同,通过简单地重新解释适当对齐的存储来创建具有普通默认构造函数的对象,例如分配的内存
std::malloc:placement-new是正式引入新对象并避免潜在的未定义行为所必需的.
T.C*_*.C. 33
没有任何X对象,无论是生活还是其他,所以假装有一个导致未定义的行为.
[intro.object]/1在创建对象时详尽说明:
一个目的是通过一个定义创建([basic.def]),通过一个 新的表达式([expr.new])中,当隐式地改变联合的活性件([class.union]),或者当一个临时对象创建([conv.rval],[class.temporary]).
采用P0137R1时,本段是"对象"一词的定义.
是否有X对象的定义?没有.有新表达吗?没有.有工会吗?没有.您的代码中是否有一个语言结构可以创建一个临时X对象?没有.
无论[basic.life]关于具有空洞初始化的对象的生命周期是什么都无关紧要.要申请,您必须首先拥有一个对象.你没有.
C++ 11具有大致相同的段落,但不将其用作"对象"的定义.尽管如此,解释是一样的.另一种解释 - 在获得合适的存储空间后立即将[basic.life]视为创建对象 - 意味着您正在创建Schrödinger的对象*,这与N3337 [intro.object]/6相矛盾:
如果一个是另一个的子对象,或者如果至少一个是零大小的基类子对象并且它们是不同类型的,则不是位字段的两个对象可以具有相同的地址; 否则,他们应有不同的地址.
*对于类型T,具有适当对齐和尺寸的存储是按照定义存储的,具有适当的对齐和尺寸,适用于尺寸和对齐要求等于或小于的尺寸和对齐要求的其他类型T.因此,该解释意味着同时获得存储在所述存储器中创建具有不同类型的无限对象集,所有对象都具有相同的地址.
基于p0593r6,我相信OP中的代码是有效的并且应该被很好地定义。新的措辞基于追溯应用于 C++98(含)所有版本的 DR,允许隐式对象创建,只要创建的对象定义良好(重言式有时可以解决复杂定义),请参阅 \xc2\xa7 6.7 .2.11 对象模型[intro.object] ):
\n\n\n\n\n\n隐式创建的对象,其地址是存储区域的起始地址,并生成指向该对象的指针值,如果该值会导致程序定义行为[... ]
\n
| 归档时间: |
|
| 查看次数: |
1812 次 |
| 最近记录: |