C 与 C++ 中 Type Punning 的陷阱

Type Punning in C and C++

我曾因 Type Punning 导致一个难以追踪的 Bug:指针转换在 -O0 下运行正常,却在 -O2 优化级别下静默失效。C 和 C++ 在此问题上存在本质差异,C 中 union 和 memcpy 是安全的,而指针转换虽看似有效,实则违反严格别名规则,属于未定义行为。C++ 编译器更激进地假设不同类型不重叠,导致代码在优化后行为异常。若你正在编写底层代码,务必避免依赖指针转换进行类型转换,改用 union 或 memcpy 才能确保行为可预测。

在 C 中,类型只是解释内存的一种方式;而在 C++ 中,类型是一等公民,编译器可以假设不同类型永远不会重叠。
  1. eqvinox

    “C 与 C++ 有何不同”一节下方包含的示例在 C 和 C++ 中都是未定义行为(而且完全没有解释“为什么”C 和 C++ 会有不同)。这篇文章整体没错,但这一部分简直……

    (感觉有点像 LLM 生成的垃圾内容,但老实说我也不确定。)

  2. scoopr

    我刚看了视频 [0],其中论证说如果你能用 consteval 处理某事,那它就必须没有未定义行为,这听起来很有说服力,至少对于这类底层辅助函数是这样。

    不幸的是,memcpy 似乎不是 constexpr,所以不能这样用,但 std::bit_cast 确实可以作为 constexpr 使用 [1],所以我认为在 C++ 中这现在应该是首选用法。它同样不允许使用 union。

    [0] https://www.youtube.com/watch?v=-LAXqqqX274

    [1] https://godbolt.org/z/xGzjTMGvv

  3. antiloper

    > 这里的 C 与 C++ 之分确实险恶

    这有什么“确实”的?

同日更多故事

2026-09-22