You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

成员指针转普通指针时的空指针左值解引用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 18:25:18