Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用std::launder从指向非活动对象的指针获取指向活动对象成员的指针?_C++_Pointers_Language Lawyer_C++17_Unions - Fatal编程技术网

C++ 使用std::launder从指向非活动对象的指针获取指向活动对象成员的指针?

C++ 使用std::launder从指向非活动对象的指针获取指向活动对象成员的指针?,c++,pointers,language-lawyer,c++17,unions,C++,Pointers,Language Lawyer,C++17,Unions,这个问题紧随其后 让我们考虑这个示例代码: struct sso { union{ struct { char* ptr; char size_r[8]; } large_str; char short_str[16]; }; bool is_short_str() const{ return *std::launder(short_str+15)=='\0'; //UB? } }; 如果short\

这个问题紧随其后

让我们考虑这个示例代码:

struct sso
  {
  union{
    struct {
      char* ptr;
      char size_r[8];
      } large_str;
    char short_str[16];
    };

  bool is_short_str() const{
    return *std::launder(short_str+15)=='\0'; //UB?
    }
  };
如果
short\u str
不是活动成员,则在没有
std::launder的情况下取消对指针的引用将是UB。让我们考虑ABI是很好指定的,并且我们知道SsieZr(7)在与SuthOrthr(15)相同的地址。当
short\u str
不是联盟的活动成员时,
std::launder(short\u str+15)
是否返回指向
size\r[7]
的指针


注:我认为这是因为

如果对象Y位于Y所占用的存储器内,则可通过指向该对象Y的指针值访问存储字节;如果对象Y是数组元素,则可通过指针与Y互换的对象访问存储字节;如果对象Y是数组元素,则可通过直接包围的数组对象访问存储字节

让我们考虑ABI是很好指定的,并且我们知道SsieZr(7)在与StruthStru[ 15 ] < /P>相同的地址上。 这完全取决于担保的确切含义

编译器可以自由地保证

Sso.short_str[15]
可以访问和修改所有内容,即使
Sso.large\u str
当前处于活动状态,也可以准确获取您期望的语义

或者不提供这种保证是自由的

对于格式错误或表现出未定义行为的行为或程序没有限制

由于那里没有对象,
&Sso.short\u str[15]
指针不能与任何对象进行相互转换。不存在的对象与另一个对象没有“相同的地址”

流槽是根据指向预先存在的对象的指针定义的。然后销毁该指针,并创建一个具有相同地址的新对象(定义良好)
std::launder
然后,您可以获取指向不再存在的对象的指针,并获取指向现有对象的指针

你所做的不是那样。如果在接通时使用
&short\u str[15]
,则会有一个指向对象的指针。ABI可以说这个地址与
size\r[7]
的地址相同。现在,
std::launder
将在有效范围内

但是编译器可以更进一步,定义
short\u str[15]
引用与
size\r[7]
相同的对象,即使它不是活动的


我所能看到的最薄弱的ABI保证与您的资料保持一致,只有在您使用
short\u str[15]
的地址时才能起作用;稍后,您将使用
大的\u str
,然后您可以从
&short\u str[15]
清洗到
&size\r[7]
。与您的声明一致的最强ABI保证使得对
std::launder
的调用不是必需的。在中间的某个地方,代码> STD::Launt。< /P> @ AndyG,因为与SuthHySTR关联的存储是通过与<代码> SIEZYR 关联的存储,并且<<代码> SiZeR r>代码>在其生存期内。我几乎可以肯定我自己。不幸的是,我常常错得无法确定@AndyG,关于公共初始化序列的规则在这里不适用,因为它是“递减的”(第一个成员必须匹配,然后是第二个…),并且不适用于数组。请参见中的。@AndyG actual active realy mean在其生存期内:在联合中,如果非静态数据成员的名称引用的对象的生存期已开始,但尚未结束,则该成员处于活动状态。“活跃”并不意味着“活着的联盟的活着的对象”@AndyG“活跃”意味着一个对象是否在其生命周期内。在盯着[basic.life]看了一段时间后,这个片段似乎没有违反任何内容。@奥利夫:我认为
std::launder
不能隐式激活工会成员。我需要一个以“因为没有对象,…”开头的段落的论证,因为[basic.types]并不是说当对象在其生命周期内时必须生成指针才能实现指针的可转换。