成员指针转普通指针时的空指针左值解引用constexpr合法性疑问
编译期成员指针转换与constexpr合法性问题
背景
我有一个类,内部包含多个运行时构造的自定义结构体成员;同时存在一个编译期元组,用于存储成员指针与对应名称的配对。需要在编译期完成两项检查:
- 每个成员指针和名称仅能被使用一次
- 自定义结构体需验证自身在元组中存在对应条目(结构体本身知晓自己的成员指针)
但使用元组会大幅增加编译时间,因此我希望在编译期改用void*数组替代异构数据结构来标识这些成员。
尝试解决的思路
我了解到解引用nullptr并非总是未定义行为,还查阅了CWG issue #315,其中明确:p->f()会被重写为(*p).f(),当p为空指针时,*p本身不会触发错误——除非该左值被转换为右值(我的场景中不存在这种转换)。
我想利用这一规则将成员指针转换为普通指针(无需实际解引用,仅用于比较同一类中不同类型的成员指针),并编写了示例代码。这段代码可在MSVC编译通过,但无法在Clang或GCC上编译。不过我测试了CWG issue #315中提及的类似代码,它在这三个编译器上都能正常编译。
核心疑问
我在第一个示例中使用的构造,是否应该被允许在constexpr表达式中使用?毕竟constexpr不允许存在未定义行为。
特殊现象
还有两个有趣的现象:
- 给类添加虚析构函数后,MSVC和Clang可编译通过,但GCC直接崩溃;
- 移除虚析构函数并将类改为模板类后,GCC和MSVC能编译,但Clang会报错。
内容的提问来源于stack exchange,提问作者Broothy
相关产品推荐
相关产品推荐

