I'd like to add a little explanation to the most endorsed example provided by @Ryan. Great example BTW.
For the expansion of HELLO( 54545 ) and HELLO( 0 ), this is how a C preprocessor does expansion for them:
HELLO( 54545 ) ; ->
JOIN( HELLO, CHECK0( 54545 ) ); ->
JOIN( HELLO, SECOND( JOIN( HIDDEN, 54545 ), 1, unused ) ); ->
JOIN( HELLO, SECOND( JOIN_EXPAND( HIDDEN, 54545 ), 1, unused ) ); ->
JOIN( HELLO, SECOND( HIDDEN54545, 1, unused ) ); ->
JOIN( HELLO, EXPAND( SECOND_EXPAND( HIDDEN54545, 1, unused ) ) ); ->
JOIN( HELLO, EXPAND( 1 ) ); ->
JOIN( HELLO, 1 ); ->
HELLO1;
HELLO( 0 ) ; ->
JOIN( HELLO, CHECK0( 0 ) ); ->
JOIN( HELLO, SECOND( JOIN( HIDDEN, 0 ), 1, unused ) ); ->
JOIN( HELLO, SECOND( JOIN_EXPAND( HIDDEN, 0 ), 1, unused ) ); ->
JOIN( HELLO, SECOND( HIDDEN0, 1, unused ) ); ->
JOIN( HELLO, SECOND( unused, 0, 1, unused ) ); ->
JOIN( HELLO, EXPAND( SECOND_EXPAND( unused, 0, 1, unused ) ) ); ->
JOIN( HELLO, EXPAND( 0 ) ); ->
JOIN( HELLO, 0 ); ->
HELLO0;
The difference lies in the expansion of JOIN_EXPAND(), where HIDDEN54545 is generated for HELLO( 54545 ), whilst HIDDEN0 is generated for HELLO( 0 ), which in turn is replaced by 'unused, 0' in further expansion, leading to the final difference.