【问题标题】:I have 2 pieces of c++ code that should work the same [duplicate]我有 2 段 c++ 代码应该工作相同 [重复]
【发布时间】:2019-06-10 19:06:12
【问题描述】:

这是第一段代码,输出 44:

const int a[] = {3};
int* b = (int*)&a[0];
*b = 4;
cout << a[0] << *b;

这是第二个,输出 34:

const int a = 3;
int* b = (int*)&a;
*b = 4;
cout << a << *b;

我不知道为什么会有差异。你们能解释一下吗?

【问题讨论】:

  • 未定义行为未定义。不要试图在其中找到逻辑。
  • 您正在修改您声明为 const 的变量。因此,您的程序具有未定义的行为。绝对不是他们“应该以同样的方式工作”的情况。事实上,你离这个目标已经很远了。
  • *b = 4; 正在尝试修改在两种情况下定义为 const 的对象(const int aconst int a[1])。这两个程序都可以毫无理由地为所欲为。编辑:通常编译器会阻止您尝试这样做,但(int*) 明确告诉编译器要管好自己的事并忽略您的错误。
  • 删除转换为int*,您的编译器可能会友好地告诉您:invalid conversion from ‘const int*’ to ‘int*’ 在这两种情况下。
  • @SolcanMihai 你能找到的任何逻辑都取决于你使用的编译器的细节。不同的编译器很可能会对这些程序产生不同的结果。所有 C++ 标准都必须说行为是未定义的。

标签: c++ pointers constants


【解决方案1】:

指向声明为const 的变量的指针只能分配给也声明为const 的指针。你违反了规则,理想情况下你的编译器应该阻止你这样做。

gccclangMSVC 都不能防止这样的错误,并且如 cmets 中所述,您有未定义的行为,而不是至少一个警告。但是zapcc 编译器会使您的程序因Segmentation fault 而崩溃。

【讨论】:

    【解决方案2】:

    除了通过使用强制转换来绕过编译器检查以更改 const 变量的值来调用“未定义行为”之外,观察到的结果可以用编译器可能进行的优化来解释:

    在第一种情况下,您声明了一个 const array,它可能最终以数据形式存储在 RAM 中的某个位置。

    在第二种情况下,您有一个标量 const 值,编译器可能决定只使用在输出中编译时已知的常量的 value,而不是从内存位置。这种优化也称为constant propagation。 如果您没有在代码中获取 a 的地址,那么它的值可能甚至不会在数据 RAM 中分配一个位置。

    【讨论】:

      猜你喜欢
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 1970-01-01
      • 1970-01-01
      • 2020-05-16
      • 2015-07-27
      • 2016-10-01
      相关资源
      最近更新 更多