【问题标题】:C++ const compiler optimizationC++ const 编译器优化
【发布时间】:2013-01-23 01:04:26
【问题描述】:

假设我有以下代码:

int foo () {
    int const x = 0;
    return x;
}

是否允许编译器将 x 移动到全局范围?

在下面的场景中呢? res2 可以根据优化而变化吗?

std::set<int const *> addrs;

int foo () {
    int const x = 0;
    addrs.insert(&x);
    return addrs.size();
}

void bar () {
    int res1 = foo();
    int res2 = foo();
}

【问题讨论】:

  • 我想编译器每次调用都会用0替换第一个。
  • 不,编译器不能将 x 移动到全局范围。但我不认为这正是你的意思。
  • 第二个例子的问题是什么?
  • 编译器会将您的代码转换为中间代码,其中范围的含义与前端形式不同。这个问题毫无意义。

标签: c++ constants compiler-optimization


【解决方案1】:

不,编译器不能在全局范围内移动它,因为变量没有在全局范围内声明。范围与存储不同。范围表示可以从哪里访问变量 - 将其移动到全局范围意味着可以从任何地方访问它,这里不是这种情况。

程序的第二部分展示了未定义的行为addrs 在函数退出后包含悬空指针。因为std::set 在插入时比较现有指针,所以这是非法的。所以我会说是的,res2 可能会有所不同,但由于 UB,而不是您怀疑的原因。

【讨论】:

  • 我认为除非取消引用其中一个指针,否则它不会显示 UB。
  • @VladLazarenko 确实如此。您不能比较数组之外的指针(或结束后的指针)。此外,除了对无效指针赋值之外的操作是非法的(包括复制)——我知道这是违反直觉的,但确实如此。
  • @LuchianGrigore:您可以使用std::less 而不是&lt; 来比较不相关的指针,因此您可以将它们存储在一个集合中。但是您的第二个原因(指针无效)足以使行为未定义。
猜你喜欢
  • 2014-02-21
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
  • 2010-12-13
  • 2012-04-11
  • 2012-12-11
  • 1970-01-01
相关资源
最近更新 更多