什么是“真实的”;或“10;” C ++中的语句是什么意思,如何使用它?

时间:2009-07-09 08:21:12

标签: c++ compiler-construction

在C ++中,可以编写以下任何语句:

10;
true;
someConstant; //if this is really an integer constant

或类似

int result = obtainResult();
result; // looks totally useless

如果在某些配置中扩展为空字符串的宏稍后与result一起使用,后者可用于抑制编译器警告“变量已初始化但未引用”(VC ++中的C4189)变量。像这样:

int result = obtainResult();
result;
assert( result > 0 ); // assert is often expanded into an empty string in Release versions of code

这些陈述的含义是什么?除编译器警告抑制外,如何使用它们?

9 个答案:

答案 0 :(得分:26)

这种陈述是对其他语言部分如何运作的逻辑扩展。考虑使用一个返回值的函数,例如int foo()会产生一些副作用。有时你只想要那些副作用发生,所以你写foo();作为陈述。

现在,虽然这看起来与10;不完全相同,但函数调用迟早会评估为int,并且没有任何事情发生在int上,就像使用10;一样。

同一问题的另一个例子是,由于您可以执行a = b = 10;,这意味着b = 10必须评估为10,因此您无法在不生成值的情况下进行分配被压制。

能够将这样的值写为语句只是构建语言的一种逻辑方式,但对于您提出的情况,为它提供编译器警告甚至是个好主意。

除非您使用它来抑制编译器警告;)

答案 1 :(得分:7)

这些语句(在C ++语法中称为表达式语句)是有效的,因为它们是表达式。

表达式是计算某种值的所有构造,例如

  • 3 + 5
  • someVariable
  • someFunctionCall(2)
  • someVar + = 62
  • val> 53

我认为,为了保持语法简单,他们决定不区分那些实际上有副作用的表达式(例如函数调用或赋值)和那些没有副作用的表达式。

答案 2 :(得分:3)

这样的声明什么都不做,很可能会被任何体面的编译器优化掉。

删除未使用的变量警告可能很有用,但对于某些编译器,您可能会收到语句无效警告。

答案 3 :(得分:1)

除了编译器警告抑制之外,它们没有实际用途,并且通常编译器将忽略任何没有副作用的此类常量值语句。

答案 4 :(得分:0)

虽然合法但我认为这些陈述令人困惑,应该避免,即使是为了抑制警告。对我来说,使用类似的东西来抑制警告更为合理:

int result = 0;
result = obtainResult();
assert (result > 0);

答案 5 :(得分:0)

它们是将被评估的表达式,假设编译器没有对它们进行优化。至于“意义”,我不确定你的意思是什么!

答案 6 :(得分:0)

在C和C ++中,评估只是表达式的语句。

表达式可能无用的事实是无害的,并且启用优化器可能导致根本没有生成代码。但是,正如您所观察到的,它通常被视为变量的 use

请注意,仅包含表达式的语句非常常见。例如,一个简单的函数调用就是一个。在printf("hello, world.\n");中,printf()的返回值被忽略,但仍然调用该函数并且它的预期效果(文本输出)发生。

此外,变量赋值x = 3;也是由简单表达式组成的语句,因为赋值是一个运算符,除了修改左值的副作用外,还返回一个值。

答案 7 :(得分:0)

在某些嵌入式环境中,访问只读寄存器会产生副作用,例如:清除它。

写int temp = IV;清除它会导致警告,因为没有使用temp,在这种情况下我会写IV;

答案 8 :(得分:0)

我同意马格努斯的回答。有一件事让我感到困惑:你为什么要用这个废话

int result = obtainResult();
result; // looks totally useless

摆脱编译器警告?在我的拙见中,更糟糕的是在这种情况下不要发出警告。 result变量仍未使用 - 您只是“扫过地毯下的污垢”。这种“单独变量”的方法看起来好像缺少某些东西(我是否意外删除了某些内容?)。你为什么不用

(void)obtainResult();

首先?它向任何想要阅读您的代码的人保证,您不关心返回结果。很难将这种“意外”置于其中。显然,这不会生成任何编译器警告。