gpt4 book ai didi

c++ - 如果另一个指针指向它的引用,为什么 const int 不会被编译器(通过符号表)优化?

转载 作者:行者123 更新时间:2023-11-30 03:19:52 26 4
gpt4 key购买 nike

这是对这个问题的回答的跟进:What kind of optimization does const offer in C/C++? (if any)

在投票最高的答案中,说明如下:

当你在你的程序中声明一个常量时,

int const x = 2;

编译器可以通过不为这个变量提供存储而是将其添加到符号表中来优化掉这个常量。因此,后续读取只需要间接访问符号表,而不是从内存中获取值的指令。

注意:- 如果您执行以下操作:-

const int x = 1;
const int* y = &x;

然后这将强制编译器为“x”分配空间。因此,这种优化程度对于这种情况是不可能的。

为什么会这样?看来您永远无法更改 x,不是吗?

最佳答案

恕我直言,Peter 在他的评论中提供了解释:

If a pointer is initialised to contain the address of a variable, and that pointer can be accessed from another compilation unit, then it would be reasonable for the compiler to allow for the possibility that the pointer IS dereferenced after being initialised in some compilation unit that is not visible to the compiler. One consequence of that is not optimising the pointer or the variable out of existence. There are numerous other reasoning approaches that might lead to the same outcome, depending on what code the compiler can actually see.

这也是我的想法。

const在 C++ 中有点困惑。看起来像是“constant”的缩写,其实是“read-only”的意思。

考虑到这一点,我从来没有想过为什么下面的代码在 C 中是合法的:

enum { N = 3 };
static int a[N]; /* legal in C: N is a constant. */

但这不是:

const int n = 3;
static int b[n]; /* illegal in C: n is a read-only variable */

当我切换到 C++ 时,我假设 C++ 的上述情况,直到我在与同事的讨论中意识到我错了。 (并不是说这破坏了我的任何书面代码,但我讨厌它是错误的。);-)

const int n = 3;
static int b[n]; // legal in C++

Const propagation是使其合法化的技术。

然而,即使使用 const 传播 const int x;仍然是一个可能被寻址的只读变量。

OP 提供了有关此主题的链接(这可能比上面的解释更好):

SO: why the size of array as a constant variable is not allowed in C but allowed in C++?

为了使这个答案功能齐全,我尝试准备了一个示例来说明差异:

#include <iostream>

const int x1 = 1;
static const int x1s = 11;
extern const int x1e = 12;

const int x2 = 2;
extern const int *const pX2 = &x2;

const int x3 = 3;
static const int *const pX3 = &x3;

int main()
{
// make usage of values (to have a side-effect)
std::cout << x1;
std::cout << x1s;
std::cout << x1e;
std::cout << x2;
std::cout << pX2;
std::cout << x3;
std::cout << pX3;
// done
return 0;
}

gcc 8.2 的结果与 -O3 :

; int main()
main:
; {
sub rsp, 8
; // make usage of values (to have a side-effect)
; std::cout << x1;
mov esi, 1
mov edi, OFFSET FLAT:_ZSt4cout
call _ZNSolsEi
; std::cout << x1s;
mov esi, 11
mov edi, OFFSET FLAT:_ZSt4cout
call _ZNSolsEi
; std::cout << x1e;
mov esi, 12
mov edi, OFFSET FLAT:_ZSt4cout
call _ZNSolsEi
; std::cout << x2;
mov esi, 2
mov edi, OFFSET FLAT:_ZSt4cout
call _ZNSolsEi
; std::cout << pX2;
mov esi, OFFSET FLAT:_ZL2x2
mov edi, OFFSET FLAT:_ZSt4cout
call _ZNSo9_M_insertIPKvEERSoT_
; std::cout << x3;
mov esi, 3
mov edi, OFFSET FLAT:_ZSt4cout
call _ZNSolsEi
; std::cout << pX3;
mov esi, OFFSET FLAT:_ZL2x3
mov edi, OFFSET FLAT:_ZSt4cout
call _ZNSo9_M_insertIPKvEERSoT_
; // done
; return 0;
; }
xor eax, eax
add rsp, 8
ret

恕我直言,最有趣的部分是全局变量:

; const int x3 = 3;
_ZL2x3:
.long 3
; extern const int *const pX2 = &x2;
pX2:
.quad _ZL2x2
; const int x2 = 2;
_ZL2x2:
.long 2
; extern const int x1e = 12;
x1e:
.long 12
  1. x1 , x1s , 和 pX3已被优化掉,因为它们是 const且未标注外部链接。

  2. x1epX2已分配,因为它们被标记为外部链接。

  3. x2已分配,因为它由 pX2 引用这是为外部链接而注明的。 (来自外部的东西可以通过 x2 访问 pX2。)

  4. x3对我来说是最棘手的。 pX3已被使用(在 std::cout << pX3; 中)。虽然,它的值本身是内联的,但它指的是 x3 .此外,虽然访问x3 (在 std::cout << x3; 中)也被内联,指针的使用 pX3&x3 初始化阻止优化此存储。

Live Demo on godbolt (它有一个漂亮的彩色双 View ,便于探索)

我对 clang 7.0.0 做了同样的事情结果是相似的。

(我也用 msvc v19.15 尝试过,但我无法(不够耐心)评估结果。)


关于4.,我另外试过:

const int x4 = 4;
static const int *const pX4 = &x4;

并添加到 main() :

  std::cout << x4;
// No: std::cout << pX4;

在这种情况下,没有分配存储空间——x4 也没有。也不是 pX4 . (pX4 被优化掉了,没有留下对 x4 的“引用”,这反过来也被优化掉了。)

这真是太棒了......

关于c++ - 如果另一个指针指向它的引用,为什么 const int 不会被编译器(通过符号表)优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53348432/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com