【问题标题】:Error with C++ syntax, compiler doesn't warn or error for int v = func(&v);C++ 语法错误,编译器不会对 int v = func(&v); 发出警告或错误
【发布时间】:2018-06-26 23:23:41
【问题描述】:

我刚刚在最后一天调试了一些东西,但最终我发现了一条有问题的线路。这条线的路径不是很清楚,我一看到它就有一个慢动作的手掌......

int v = func(&v);   // why am I allowed to do this.

这不应该产生某种“定义前使用的变量”警告吗?这非常烦人,因为没有编译器错误或警告?当然,语法下没有红色 suiggly 线 :(。所以我直接跳过它...

奇怪的是,它在大多数情况下都有效,直到被发现.. 我猜对 UB 很幸运?

诚然,我对编译器复杂性的了解并不多,所以我可能遗漏了一些明显的东西,但在我看来,我只是在定义它之前使用了一个 var,可以说我在声明它之前使用了它!

为什么这是有效的 C++ 语法?

【问题讨论】:

  • 是的,这很奇怪,但为什么不应该它是有效的?编译器首先看到int v,所以在看到&v时知道v的类型和存储,所以它知道v的存储位置以及在调用func()时如何获取它的地址.它可能是有效代码,具体取决于func() 对来自&v 的指针所做的实际操作(想到了C time() 函数,它通过返回值和输出参数,如果已分配)。抱歉,我不是语言律师,所以我不能引用使这个(il)法律代码以一种或另一种方式产生的规范。
  • Is passing a C++ object into its own constructor legal? 密切相关,这是合法的……你可以在这里使用v,如果你只使用它的地址,它可能是有效的。 The point of declaration for a name is immediately after its complete declarator and before its initializer
  • “为什么这是有效的 C++ 语法?”因为它是有效的 C 语法并且 C++ 继承了它
  • @lfgtm 如果func 的定义在同一个翻译单元中并且启用了优化,您可能会收到这样的警告。
  • @lfgtm 不同之处在于,在您的示例中,分配给 g 的值未定义。但是,传递给func&v 的值是正确且定义明确的。不管你的错误是什么,这一定只是其中的一部分,因为这并没有错。

标签: c++ syntax visual-studio-2017


【解决方案1】:

变量名在其声明符出现后就在作用域内。代码不是未定义的行为本身;使用尚未初始化的变量的地址即可。

这在C++17 6.3.2 Point of declaration [basic.scope.pdecl] 部分的1 段落中进行了介绍(释义):

名称的声明点紧跟在它的完整声明器之后和它的初始化器(如果有的话)之前。

还有一个有效(虽然不是很聪明)代码的具体示例:

unsigned char x = x;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-23
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多