52

After a typo, the following expression (simplified) compiled and executed:

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

of course, the 0 shouldn't be there.

Why does it compile, and what does the expression mean?

The original (simplified) should look like this:

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

none of this does compile:

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

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

if((1 == 2) || null (-4 > 2))
  printf("Hello");
Donald Duck
  • 8,409
  • 22
  • 75
  • 99
huebe
  • 465
  • 4
  • 8
  • 3
    I've just tried this and got [warning C4353](http://msdn.microsoft.com/en-us/library/2a68558f.aspx): "nonstandard extension used: constant 0 as function expression. Use '__noop' function intrinsic instead" – Rup Jul 25 '13 at 12:51
  • 3
    i got `error: called object ‘0’ is not a function` – Dayal rai Jul 25 '13 at 12:52
  • 3
    This has already been answered at http://stackoverflow.com/questions/2198950/why-is-void-0-a-no-operation-in-c-and-c – Panagiotis Kanavos Jul 25 '13 at 12:53

6 Answers6

26

It looks like this is a Visual C++ extension to support a particular 'no function defined' idiom. From the warning C4353 page:

// 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();
}

the intention being that DBPRINT is a no-op. The warning suggests #define DBPRINT __noop instead, using VC's __noop extension instead.

If you view the assembly listing for your output you'll see the second clause is omitted, even in debug mode.

Rup
  • 33,765
  • 9
  • 83
  • 112
14

Guess it was interpreted as

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

where NULL is a function-pointer, by default returning int... What at actually happens in runtime is platform-dependent

Lorinczy Zsigmond
  • 1,749
  • 1
  • 14
  • 21
  • The importance of type-safety... C++11 renders things more secure with this kind of problems by introducing another type of NULL value – Marco A. Jul 25 '13 at 19:59
9

Visual Studio 2012 gives you the following warning:

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

it is a non-standard way to insert a "no operation" assembler instruction at that point of expression evaluation

Remco Boom
  • 131
  • 2
8

In fact it is Microsoft specific.

For debug purpose, you can use __noop intrinsic, it specifies that the function and the parameters will no be evaluated.

In your case, Microsoft compiler thinks you are trying to use 0 to do the same, that's why it works but for example, on VS2012 it gives the warning :

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

See this for more informations : http://msdn.microsoft.com/en-us/library/2a68558f(v=vs.71).aspx

Pierre Fourgeaud
  • 14,290
  • 1
  • 38
  • 62
  • The important thing is, that the parameters don't get evaluated as well. – huebe Jul 26 '13 at 06:27
  • What does such noop-ed function return? `if((1 == 2) || 0 (-4 > 2))` requests a boolean. Is it some random number from a register? – Kane Jun 20 '14 at 16:16
1

In ubuntu it is showing error

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

o/p

niew1.c:3:19: error: called object â0â is not a function
pradipta
  • 1,718
  • 2
  • 13
  • 24
0

Probably 0 is casted to a function pointer here. Explicit cast may look like this:

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

However, I have no guesses about what function 0 is casted to in implicitly in your example.

Ivan Smirnov
  • 4,365
  • 19
  • 30