在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
这些陈述的含义是什么?除编译器警告抑制外,如何使用它们?
答案 0 :(得分:26)
这种陈述是对其他语言部分如何运作的逻辑扩展。考虑使用一个返回值的函数,例如int foo()
,也会产生一些副作用。有时你只想要那些副作用发生,所以你写foo();
作为陈述。
现在,虽然这看起来与10;
不完全相同,但函数调用迟早会评估为int,并且没有任何事情发生在int上,就像使用10;
一样。
同一问题的另一个例子是,由于您可以执行a = b = 10;
,这意味着b = 10
必须评估为10
,因此您无法在不生成值的情况下进行分配被压制。
能够将这样的值写为语句只是构建语言的一种逻辑方式,但对于您提出的情况,为它提供编译器警告甚至是个好主意。
除非您使用它来抑制编译器警告;)
答案 1 :(得分:7)
这些语句(在C ++语法中称为表达式语句)是有效的,因为它们是表达式。
表达式是计算某种值的所有构造,例如
我认为,为了保持语法简单,他们决定不区分那些实际上有副作用的表达式(例如函数调用或赋值)和那些没有副作用的表达式。
答案 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();
首先?它向任何想要阅读您的代码的人保证,您不关心返回结果。很难将这种“意外”置于其中。显然,这不会生成任何编译器警告。