【问题标题】:What does this mean? int foo = foo + 4;这是什么意思? int foo = foo + 4;
【发布时间】:2011-03-27 16:42:57
【问题描述】:
#include <iostream>

int main(int argc, char** args) {
  int foo = foo + 4;
  std::cout << foo << std::endl;
}

还有一个后续问题,是否有一个编译器标志来阻止这种事情?我发现 -Wall 有时会起作用,最好完全阻止它。

My compiler:  
g++ -v  
Using built-in specs.  
Target: i486-linux-gnu  
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu  
Thread model: posix  
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)  

【问题讨论】:

  • 一个编译器标志来阻止什么样的事情?
  • 您的问题到底是什么?为什么不初始化 foo?
  • int foo = foo + 4; 没有任何意义。你写的时候是什么意思?
  • 我不确定,但我猜int foo = foo + 4; 是未定义的行为,因为读取了未初始化变量的值。
  • 这是我编写的程序的一个错误。当我添加 -Wall 时,它没有生成警告。所以基本上我想知道我是否可以出于好奇而阻止它发生,为什么它甚至被允许。

标签: c++


【解决方案1】:

不,没有保证可以阻止这种事情。变量的名称在其初始化程序中可见是 C++ 和 C 的一个组成部分。它允许您执行以下操作:

T *t = malloc(sizeof(*t));

C++ 问题列表中有一份问题报告要求在简单情况下进行诊断,但目前不需要编译器来诊断您的情况。

in a different context 也是有效的。

编辑:澄清 - 你的 sn-p 的行为是未定义的:你正在读取一个未初始化变量的值。编译器不需要对此进行诊断并不意味着定义了行为。

【讨论】:

    【解决方案2】:
    int foo = foo + 4;
    

    这是未定义的行为。有些编译器会自动将局部变量的空间归零,而其他编译器可能不会,因此 foo 可能包含堆栈的垃圾

    【讨论】:

    • @Nawaz:@Johannes 的回答说得对:未定义的行为
    • @BlackBear:嗯..你是对的。我试图撤消我的反对票,但为此你必须编辑你的帖子,因为它不允许我撤消!
    • @Nawaz:已编辑。如果您仍然无法撤消您的反对票,请支持答案;)
    • 没有。没有编辑它不会让我做任何事情,撤消以及投票。但现在我两者都做了。所以要快乐:D
    【解决方案3】:

    我敢打赌这意味着未定义的行为。

    编辑:参见answer to another question的引文。

    编辑:很可能,RHS 中的值取自堆栈中未初始化的内存位置,将 4 添加到其中,结果用于初始化。

    【讨论】:

    • @Nawaz:这并没有说明答案有什么问题。顺便说一句,我提供的链接引用证明了答案。
    • @Vlad:嗯..你是对的。我试图撤消我的反对票,但为此你必须编辑你的帖子,因为它不允许我撤消!
    【解决方案4】:

    要从 gcc 获得针对此特定代码的警告,您需要 -Wuninitialized-Wall 包括此)-O(或任何高于 0 的优化级别)。

    原因是 gcc 无法诊断未初始化变量的使用,除非它进行数据流分析,并且在禁用优化时不进行数据流分析。并且默认禁用优化。

    【讨论】:

      【解决方案5】:

      我希望任何中途体面的编译器都会在其默认配置中针对 int foo = foo + 4; 发出警告。好的人可以选择完全拒绝它,因为它是“使用未初始化的变量”和/或接受它的任何特定出现,程序员完全了解正在发生的事情并且不担心意外行为。

      例如,我经常写 int toggle = toggle ^ 1 在编译器不那么挑剔的日子里,如果我想要的只是一个我不在乎的切换开关它以 TRUE 或 FALSE 开头。现在我可能会写 static bool toggle=TRUE;切换=^切换

      【讨论】:

        猜你喜欢
        • 2016-07-28
        • 1970-01-01
        • 2014-05-06
        • 1970-01-01
        • 2012-09-17
        • 2014-05-06
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        相关资源
        最近更新 更多