52

在一个错字之后,编译并执行了以下表达式(简化):

if((1 == 2) || 0 (-4 > 2))
  printf("Hello");

当然,0 不应该在那里。

为什么会编译,表达式是什么意思?

原始(简化)应如下所示:

if((1 == 2) || (-4 > 2))
  printf("Hello");

这些都不编译:

if((1 == 2) || true (-4 > 2))
  printf("Hello");

if((1 == 2) || 1 (-4 > 2))
  printf("Hello");

if((1 == 2) || null (-4 > 2))
  printf("Hello");
4

6 回答 6

26

看起来这是一个支持特定“未定义函数”习语的 Visual C++ 扩展。从警告 C4353页面:

// C4353.cpp
// compile with: /W1
void MyPrintf(void){};
#define X 0
#if X
   #define DBPRINT MyPrint
#else
   #define DBPRINT 0   // C4353 expected
#endif
int main(){
    DBPRINT();
}

意图DBPRINT是没有操作。警告建议#define DBPRINT __noop改为使用 VC 的__noop扩展。

如果您查看输出的汇编列表,您将看到第二个子句被省略,即使在调试模式下也是如此。

于 2013-07-25T12:56:41.537 回答
14

猜猜它被解释为

if((1 == 2) || NULL (-4 > 2))
  printf("Hello");

其中 NULL 是一个函数指针,默认返回 int... 在运行时实际发生的情况取决于平台

于 2013-07-25T12:53:19.317 回答
9

Visual Studio 2012 为您提供以下警告:

警告 C4353:使用了非标准扩展:常量 0 作为函数表达式。使用 '__noop' 内部函数代替

在表达式求值点插入“无操作”汇编指令是一种非标准方式

于 2013-07-25T12:55:56.373 回答
8

事实上,它是Microsoft 特有的。

出于调试目的,您可以使用__noop内在函数,它指定不会评估函数和参数。

在您的情况下,Microsoft 编译器认为您正在尝试使用 0 来做同样的事情,这就是它起作用的原因,但例如,在 VS2012 上它会发出警告:

warning C4353: nonstandard extension used: constant 0 as function expression.  Use '__noop' function intrinsic instead.

有关更多信息,请参阅此:http: //msdn.microsoft.com/en-us/library/2a68558f (v=vs.71).aspx

于 2013-07-25T12:58:20.647 回答
1

在ubuntu中显示错误

int main()
{
 if((1 == 2) || 0 (-4 > 2))
      printf("Hello");
}

o/p

niew1.c:3:19: error: called object â0â is not a function
于 2013-07-25T12:53:48.103 回答
0

可能0在这里被转换为函数指针。显式转换可能如下所示:

if((1 == 2) || ((int (*)(int)) 0) (-4 > 2)) 
      printf("Hello");

但是,我无法猜测0在您的示例中隐式转换为什么函数。

于 2013-07-25T12:55:55.380 回答