I found this C code example, and I am absolutely puzzled:
#include <stdio.h> #define M(a,b) a%:%:b main() { int a=1, b=2, ab[]={10,20}, c; printf( "%d", M(a,b)<:a:> ); printf( "%d", M(a,b)<:a:>?a:b ); printf( "%d", c=M(a,b)<:a:>?a:b ); }
Could someone explain what this is supposed to do? It doesn't even compile in Visual Studio, but I ran it online (on ideone.com) and it printed 2011
, which also added to the confusion.
It's making use of C digraphs which were amendments to the C standard in 1994 and therefore part of the C99 standard. Swapping the digraphs out with their actual characters, you get:
#include <stdio.h> #define M(a,b) a##b main() { int a=1, b=2, ab[]={10,20}, c; printf( "%d", M(a,b)[a] ); printf( "%d", M(a,b)[a]?a:b ); printf( "%d", c=M(a,b)[a]?a:b ); }
So, keep in mind that a##b
will merge together the input into a single identifier. Since the macro is just passed a
and b
, the result is just ab
, so you effectively have:
main() { int a=1, b=2, ab[]={10,20}, c; printf( "%d", ab[a] ); printf( "%d", ab[a]?a:b ); printf( "%d", c=ab[a]?a:b ); }
The assignment to c
is not really relevant, so we can get rid of that:
main() { int a=1, b=2, ab[]={10,20}; printf( "%d", ab[a] ); printf( "%d", ab[a]?a:b ); printf( "%d", ab[a]?a:b ); }
Now, let's get rid of the ternary operator (?:
), because we can work it out statically (ab[a]
is always true because a
is 1 and ab[1]
is 20, i.e. non-zero):
main() { int a=1, b=2, ab[]={10,20}; printf( "%d", ab[a] ); printf( "%d", a ); printf( "%d", a ); }
Now, replace variables with their actual values, i.e. ab[a]
with 20
and a
with 1
main() { int a=1, b=2, ab[]={10,20}; printf( "%d", 20 ); printf( "%d", 1 ); printf( "%d", 1 ); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With