I need help in debugging macro. Macroprocessor expands all the macros before compilation.
So after macro expansion, d1 and d2 should behave exactly same, but they don’t. Why?!
d1(1); will be expanded as it is. For d2(2); only d2(2) will be expanded and will have a semicolon at the end(which was not part of macro).
What is going wrong here? Please help.
Code -
#include
#define d1(i); cout<<i;
#define d2(i) cout<<i
using namespace std;
int main(void){
if(true==false) d1(1);
if(true==false) d2(2);
return 0;
}
Expected output -
Output -
1
Expected code after preprocessing -
{ code}
using namespace std;
int main(void){
if(true==false) cout<<1;
if(true==false) cout<<2;
return 0;
}
1 Like
ur define can be rewritten as
#define d1(i) ;cout << i;
after preprocessing it results:
if(true == false ) ; cout << 1;
if(true == false ) cout << 2 ;
and due to semicolon the statement completes and it finally cout << 1;
u made me really surprised, haha.
The define needs a ‘#’ , for eg #define d1(i);
Then you need to look at the semicolon ; in the define d2(i) line
In the end instead of using int main(void) , why not use just void main( ). you would not require any return type for that.
Another problem is that your expression would parse incorrectly if d2
is preceded or followed by an operator with higher precedence than <<
. You can prevent this by writing the macro as (cout << (i))
. Somewhat contrived example that shows the bug this can cause:
#include <cstdint>
#include <iostream>
#include <stdlib.h>
using std::cout;
using std::endl;
using std::uintptr_t;
#define d2(i) cout << i << ' '
#define d3(i) (cout << (i) << ' ')
int main(void)
{
cout.setf(cout.hex, cout.basefield);
cout.setf(cout.showbase);
cout << ((uintptr_t)(void*)&d2(0));
cout << endl;
cout << ((uintptr_t)(void*)&d3(0));
cout << endl;
return EXIT_SUCCESS;
}
The first line of output never displays i
followed by a space, because &
has higher precedence than <<
, so (uintptr_t)(void*)&d2(0)
is parsed as the unsigned quantity (uintptr_t)(void*)&cout
, the unsigned implementation-defined representation of the address of cout
, bitwise left-shifted by i
. The second line parses correctly, taking the address of the return value of d3(0)
after evaluating it.
If you don’t surround your argument with parentheses, you can run into trouble if you pass in an expression with lower precedence than the expressions surrounding it. What will d2(i << 1)
do? Also beware of passing in an expression with side-effects, such as x++
, as a macro parameter, and then not evaluating it once and only once!
In practice, you almost always want to use inline
functions rather than macros in C++. Rare exceptions are when you need to use macros such as __FILE__
and __LINE__
.