草庐IT

c++ - 使用 clang 的功能检查宏来检测 std::launder 的存在

我必须使用不同版本的clang编译相同的代码。由于代码包含一些c++17功能,并非每个版本的clang都支持这些功能,因此我想在编译时检查它们是否受支持。据我所知,clang的featurecheckingmacros是正确的方法。我的问题特别出现在std::launder上。我创建了这个最小的例子:#include"iostream"#if__has_builtin(__builtin_launder)voidtest(){inti=42;std::cout如果我使用clang++-std=c++1z-stdlib=libc++-Wall-pedantictest3.cpp&&./a

c++ - 使用 std::launder 从指向非事件对象的指针获取指向事件对象成员的指针?

这个问题跟在这个one之后让我们考虑这个示例代码:structsso{union{struct{char*ptr;charsize_r[8];}large_str;charshort_str[16];};boolis_short_str()const{return*std::launder(short_str+15)=='\0';//UB?}};如果short_str不是事件成员,则在没有std::launder的情况下取消引用指针将是UB。让我们考虑一下ABI已明确指定,并且我们知道size_r[7]与short_str[15]位于同一地址。当short_str不是union体的活跃

c++ - 为什么 std::launder 是一个 constexpr 函数?

我想知道为什么std::launder是一个constexpr函数。有没有可以在编译时使用的用例? 最佳答案 因为绝对没有理由不这样做。它实际上只是对编译器具有一些特殊附加含义的恒等函数。它不能失败,不能有副作用。使它成为constexpr不需要任何成本,而且您永远不知道它什么时候会派上用场。 关于c++-为什么std::launder是一个constexpr函数?,我们在StackOverflow上找到一个类似的问题: https://stackoverfl

c++ - std::launder 和严格的别名规则

考虑这段代码:voidf(char*ptr){autoint_ptr=reinterpret_cast(ptr);//(&i));}voidexample_2(){alignas(alignof(int))charstorage[sizeof(int)];new(&storage)int;f(storage);}来自example_1的调用的兴趣行:Q1:在调用方,char指针是我们整数指针的别名。这是有效的。但是将其转换回int是否也有效?我们知道int在其生命周期内存在,但考虑到该函数是在另一个翻译单元中定义的(未启用链接时优化)并且上下文未知。然后所有编译器看到的是:int指针想

c++ - 使用 std::launder 从指向非事件 union 成员的指针获取指向事件 union 成员的指针?

考虑这个union:unionA{inta;struct{intb;}c;};c和a不是layout-compatibles类型,因此无法读取b的值通过a:Ax;x.c.b=10;x.a+x.a;//undefinedbehaviour(UB)对于试验1和试验2,请参阅thisquestion试验3现在让我们使用std::launder对于它似乎不是故意的:Ax;x.a=10;autop=&x.a;//(1)x.c.b=12;//(2)p=std::launder(p);//(2')*p+*p;//(3)UB?可以std::launder改变什么?根据[ptr.launder]:tem

c++ - 可以使用 std::launder 将对象指针转换为其封闭数组指针吗?

当前标准草案(大概是C++17)在[basic.compound/4]中说:[Note:Anarrayobjectanditsfirstelementarenotpointer-interconvertible,eventhoughtheyhavethesameaddress.— endnote ]所以指向对象的指针不能是reinterpret_cast'd获取它的封闭数组指针。现在,有std::launder,[ptr.launder/1]:template[[nodiscard]]constexprT*launder(T*p)noexcept;Requires:prepresent

c++ - std::launder 如何影响容器?

考虑以下固定大小vector的简化且不完整的实现:templateclassVec{T*start,*end;public:T&operator[](ssize_tidx){returnstart[idx];}voidpop(){end--;end->~T();}templatevoidpush(U...args){new(end)T{std::forward(args)...};end++;}};现在考虑下面的T:structT{constinti;};以及以下用例:Vecv;v.push(1);std::cout索引运算符使用start指针来访问对象。此时的对象被pop销毁,另一个

c++ - std::launder alternative pre c++17

它类似于std::optional,但不存储额外的bool。用户必须确保只有在初始化后才能访问。templateunionFakeOptional{//Couldbeanormalstructinwhichcasewillneedstd::alignedstorageobject.FakeOptional(){}//DoesnotconstructTtemplatevoidemplace(Args&&...args){new(&t)T{std::forward(args)...};}voidreset(){t.~T();}operatorbool()const{returntrue;}

c++ - 可以使用 std::launder 将对象指针转换为其封闭数组指针吗?

当前的标准草案(大概是C++17)在[basic.compound/4]中说:[Note:Anarrayobjectanditsfirstelementarenotpointer-interconvertible,eventhoughtheyhavethesameaddress.— endnote ]所以指向对象的指针不能是reinterpret_cast'd获取其封闭的数组指针。现在,有std::launder,[ptr.launder/1]:template[[nodiscard]]constexprT*launder(T*p)noexcept;Requires:prepresen

c++ - 在标准布局对象(例如,使用 offsetof)中进行指针运算时,我们是否需要使用 std::launder?

此问题是对Isaddingtoa"char*"pointerUB,whenitdoesn'tactuallypointtoachararray?的后续问题。在CWG1314,CWG确认使用unsignedchar指针在标准布局对象中执行指针运算是合法的。这似乎意味着类似于链接问题中的一些代码应该按预期工作:structFoo{floatx,y,z;};Foof;unsignedchar*p=reinterpret_cast(&f)+offsetof(Foo,z);//(*)*reinterpret_cast(p)=42.0f;(为了更清楚,我已将char替换为unsignedchar。
12