指针转换中的未定义行为及自定义偏移指针类的问题咨询
关于NullableOffsetPtr未定义行为及相关标准问题的修复与疑问
编辑:感谢各位精准解答,已解决“为什么”的问题与燃眉之急,但仍纠结“如何解决”的具体方案,以下是附加问题。
核心问题:NullableOffsetPtr优化级别依赖的未定义行为修复
我正在设计极简的NullableOffsetPtr偏移指针类,用于实现共享内存中的链表数据结构,以应对不同进程的虚拟地址偏移差异,设计灵感来自boost::interprocess::offset_ptr。首次测试显示输出结果依赖优化级别,疑似存在未定义行为(UB),请问如何修复?
示例代码如下:
#include <cstddef> #include <iostream> template<typename T> class NullableOffsetPtr { public: NullableOffsetPtr(T const* ptr) : offset_{ ptr == nullptr ? std::ptrdiff_t{1} : reinterpret_cast<std::byte const*>(ptr) - reinterpret_cast<std::byte const*>(this)} { } T* get() { return offset_ == 1 ? nullptr : reinterpret_cast<T*>(reinterpret_cast<std::byte*>(this) + offset_); } private: std::ptrdiff_t offset_; // Using units of bytes, as alignments of *this and *ptr may not match. }; class Sample { }; int main(int argc, char* argv[]) { Sample sample; NullableOffsetPtr<Sample> ptr{&sample}; std::cout << "(ptr.get() == &sample): " << (ptr.get() == &sample) << std::endl; std::cout << "ptr.get(): " << ptr.get() << std::endl; std::cout << "&sample : " << &sample << std::endl; return 0; }
在gcc编译器-O1及以上优化级别下,输出为:
(ptr.get() == &sample): 0 ptr.get(): 0x7ffe503cd42f &sample : 0x7ffe503cd42f
尽管指针值显示相同,但比较结果为false!我知道reinterpret_cast可能引发UB,但认为其使用符合reinterpret_cast的类型别名规则。
附加问题1:复合对象内指针加减的标准合法性
我理解expr.add#4.2限制指针+/-操作仅适用于同一数组元素的指针,但offsetof宏的存在说明同一复合对象内的指针也可操作,示例代码如下:
#include <iostream> struct Inner { int i1; int i2; }; struct Outer { int i1; int i2; Inner inner; }; int main(int argc, char* argv[]) { Outer outer; std::cout << "&outer.i2 - &outer.i1: " << &outer.i2 - &outer.i1 << std::endl; std::cout << "&outer.inner.i2 - &outer.i1: " << &outer.inner.i2 - &outer.i1 << std::endl; return 0; }
输出为:
&outer.i2 - &outer.i1: 1 &outer.inner.i2 - &outer.i1: 3
所有指针目标都在outer对象内,但无数组参与。expr.add#4.2中提到的“(possibly-hypothetical) array element”是否适用于此场景?该表述具体指什么?
附加问题2:boost::interprocess::offset_ptr的未定义行为规避
boost::interprocess::offset_ptr能在多大程度上避免UB?我看到与内联相关的“illegal but correct”说法,但不理解内联的关联,也不清楚是否存在可验证的广泛认可的“非法但正确”情况,能否给出建议?
内容的提问来源于stack exchange,提问作者Michael Steffens
相关产品推荐
相关产品推荐

