Expand C/C++ function macros without preprocessor

牧云@^-^@ 提交于 2019-12-08 17:32:11

问题


How would I test/expand all the function macros, in a C/C++ file, without running it through a preprocessor? For example, is there a program or method which would change this:

#include <iostream>
#define AAA(a) cout << "function "  << a << endl
using namespace std;
int main(){
AAA(12);
}

into this?

#include <iostream>
using namespace std;
int main(){
cout << "function " << 12 << endl;
}

I don't want to run through preprocessor because all the includes in the files make the "gcc -E <>" output really ugly, I just want a couple simple macro expansions without all the overhead.


回答1:


No, it's not possible. Your included headers could include macros that you want to expand in the body, for example. Or did you mean to not expand any macros that come from headers? The preprocessor has absolutely no way of distinguishing what you want from what you don't want in this case.

If you know in advance this is not the case, then I recommend simply writing a script to remove the includes and then run that through the preprocessor.




回答2:


I heard all possible negative answers on the topic:

  • macros can only be expanded not evaluated
  • processor should parse also include files
  • nested macros can be over-complicated
  • conditional preprocessing can be tricky
  • macros are evil just avoid them
  • etc etc....

They are all true, but IMO they collide with the reality of everydays programming.

In fact, working on old C project where macros were mostly simply used as functions this became of crucial importance for me. Generating all preprocessed files with /P works but is overkilling and time taking. I just needed a tool that expands a simple macro defined a few lines above or at maximum in other file.

How to do that?

1 Onl,inux simply use GDB and his expand macros capabilities 2 On windows I use https://www.jetbrains.com/resharper-cpp/ integrated into Visual Studio

So, Yes, in a practical sense, it is possible.




回答3:


Protect the #includes from getting expanded, run the preprocessor textually, remove the # 1 "<stdint>" etc. junk the textual preprocessor generates and reexpose the protected #includes.

This shell command does it:

sed 's|^\([ \t]*#[ \t]*include\)|magic_fjdsa9f8j932j9\1|' | cpp | \
     sed 's|^magic_fjdsa9f8j932j9||; /^# [0-9]/d'

as long as you keep the include word together instead of doing crazy shit like

#i\
ncl\
u??/
de <iostream>

(above you can see 2 backslash continuation lines + 1 trigraph (??/ == \ ) backslash continuation line).

If you wish, you can protect #ifs #ifdefs #ifndefs #endifs and #elses the same way.




回答4:


Suppose you want to see file.c. If it contains the function main, you would need to change the name of that function for this to work. The following prints the file to stdout, only with moderate added ugliness.

#include "file.c"
#include <stdio.h>

#define X(...) #__VA_ARGS__

void print_file( char* s )
{
   // a loop here to move through s until some identifier is found
   // in the original file, say a comment that says: //___START___HERE___
   while(*s){
      if( *s=='{' | *s=='}' | *s=='#' ) printf("\n");
      printf("%c",*s);
      if( *s==';' ) printf("\n");
      }
}

int main(int argc, char* argv[])
{
    print_file(X(
    #include "file.c"
    ));
    return 0;
}


来源:https://stackoverflow.com/questions/28932534/expand-c-c-function-macros-without-preprocessor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!