【问题标题】:Declaration in if statement weird behaviour (C++) [duplicate]if 语句中的声明奇怪的行为(C++)[重复]
【发布时间】:2016-11-13 04:38:07
【问题描述】:

我有以下代码:

int X = 1;
if (int X = X)
{
    printf("%d\n", X);
    if (int X = X)
    {
       printf("%d\n", X);
    }
}

我的期望是 X 应该是 1, 1。但是,输出是:

1818935350
32767

有人知道这里发生了什么吗?使用 clang-800.0.42.1 编译

编辑:我尝试了以下代码并稍作调整,现在它的行为符合我的预期。

int X = 1;
if (int Y = X)
{
    printf("%d\n", Y);
    if (int Z = X)
    {
        printf("%d\n", Z);
    }
}

一种猜测是,当您在 if 语句内的声明的 RHS 上使用变量时,它可能不是指在父范围内声明的同名变量,而是指正在定义的变量...

【问题讨论】:

  • 去掉 if 语句中 X 之前的 'int'。此外,如果您想进行比较,您需要使用== 而不是== 设置 X 的值。但是,很难在这里看到您要完成的工作。也许给一些想要的输入和输出
  • @bpgeck 这不是我打算做的。我想检查在 if 语句中使用声明时的行为。
  • @Avi Berger 是的,我知道,但不管你信不信。我遇到了一个与此类似的问题。我需要一些将扩展为 if 语句的宏,并且我希望它们自动引用父范围内具有相同名称的宏......似乎这是不可能的。
  • @ShafikYaghmour 不错的参考资料,以前不知道 :)

标签: c++ clang++


【解决方案1】:

当您说 int X = X 时,两个 X 指的是同一个 int。也就是说,您在该行中声明的那个。因此,您正在使用自身初始化 X,这是未定义的行为,因为它(当然)尚未初始化。你用 1 初始化的 X 永远不会在你的代码中打印出来,因为它是在父作用域中声明的,并被内部作用域中的那些遮蔽。

【讨论】:

  • 我很惊讶编译器允许这样做。
  • @benjamin Lindley。看我的编辑,和你猜的一样。
  • @A.斯通:这不是猜测。
  • @A.Stone - 您的编辑不足为奇。这里指出的真正问题是变量的范围。
  • @BenjaminLindley。对不起...
【解决方案2】:

在 C 中,这个 if (int X = X) 是完全错误的,因为 if 语句需要一个控制表达式 - 但不是一个声明。

6.8.4.1 if 语句

if 语句的控制表达式应为标量类型。

我不确定clang,但gcc 给这段代码一个明显的错误(不是警告),即使没有任何编译器标志(即没有 -Wall -Wextra

错误:'int'之前的预期表达式

【讨论】:

  • 可能只有C++,可以试试clang++还是g++?
  • @A.Stone 我用 C++ 测试过。没有报错但是没有进入if语句
  • @bpgeck 这很奇怪,因为它确实会在我的机器上打印出东西。
  • 如果它没有进入 if 块,可能是因为 X 在您的测试中得到值 0,因此表达式的计算结果为 false。
  • @BenjaminLindley 它实际上无法在gcc 中编译,但可以使用g++。正如您指出的那样,原因是阴影。
【解决方案3】:

改变所有 ( Int X =X) 到 (X) 它正在创建新变量并可能返回存储在该位置的旧数据。

【讨论】:

  • 我不想在这里做任何事情,只是为了测试它的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-29
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
相关资源
最近更新 更多