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

寻求含const_cast的未定义行为示例:GCC优化前后输出不同

优化对含未定义行为程序的影响示例

一、修改你原程序的可行变体

你的原程序中,编译器可能因为constant()是无副作用的纯函数,即使在-O0下也做了常量传播,导致优化前后输出一致。可以调整代码,让编译器无法在-O0时确定p的常量值,但优化时能通过未定义行为假设做常量折叠:

拆分编译单元实现

  1. 创建blind.cpp文件:
void blind(int const* p) { ++*const_cast<int*>(p); }
  1. 主程序main.cpp:
#include <iostream>

// 声明blind,不定义在本单元,避免编译器内联优化
extern void blind(int const*);

// 给constant函数添加微小副作用,阻止-O0下的常量传播
int constant() {
    static int cnt = 0;
    return cnt++;
}

int main()
{
    int const p = constant();
    blind(&p);
    std::cout << p << std::endl;
    return 0; 
}

编译运行结果

  • 未优化编译:g++ -O0 main.cpp blind.cpp -o test,运行输出1(未优化时直接读取内存中被修改后的值)
  • 开启-O3优化:g++ -O3 main.cpp blind.cpp -o test_opt,运行输出0(编译器认为const变量p的值不会被修改,直接用constant()返回的初始值做常量输出)

二、经典有符号整数溢出示例(优化前后输出不同且不崩溃)

有符号整数溢出属于C++未定义行为,编译器会基于“溢出不会发生”的假设做优化,导致优化前后行为差异:

#include <iostream>

int check_overflow(int x) {
    if (x > 0) {
        x += 1000000000; // 当x足够大时,此处触发有符号整数溢出
    }
    // 编译器优化时会假设x>0时x+1e9仍>0,直接返回1
    return x > 0 ? 1 : 0;
}

int main() {
    // 假设int为32位,最大值为2147483647,2000000000+1000000000=3000000000超过最大值
    std::cout << check_overflow(2000000000) << std::endl;
    return 0;
}

编译运行结果

  • 未优化编译(-O0):运行输出0(实际溢出后x变为负数,返回0)
  • 开启-O3优化:运行输出1(编译器基于“无溢出”假设,认为x+1e9后仍>0,直接返回1)

内容的提问来源于stack exchange,提问作者ABu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 08:17:32