简体   繁体   English

在没有预处理器的情况下展开C / C ++函数宏

[英]Expand C/C++ function macros without preprocessor

How would I test/expand all the function macros, in a C/C++ file, without running it through a preprocessor? 如何在C / C ++文件中测试/扩展所有函数宏,而不通过预处理器运行它? 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. 我不想运行预处理器,因为文件中的所有包含使得“gcc -E <>”输出真的很难看,我只想要几个简单的宏扩展而没有所有的开销。

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. 如果您事先知道情况并非如此,那么我建议您只需编写一个脚本来删除包含,然后通过预处理器运行它。

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. 它们都是真的,但IMO却与日常编程的现实相冲突。

In fact, working on old C project where macros were mostly simply used as functions this became of crucial importance for me. 事实上,在处理宏C项目的旧C项目中,这对于我来说至关重要。 Generating all preprocessed files with /P works but is overkilling and time taking. 使用/ P生成所有预处理文件但是过度使用和耗时。 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 1 Onl,inux只需使用GDB和他的扩展宏功能2在Windows上我使用https://www.jetbrains.com/resharper-cpp/集成到Visual Studio中

So, Yes, in a practical sense, it is possible. 所以,是的,从实际意义上讲,它是可能的。

Protect the #include s from getting expanded, run the preprocessor textually, remove the # 1 "<stdint>" etc. junk the textual preprocessor generates and reexpose the protected #include s. 保护#include不被扩展,以文本方式运行预处理器,删除文本预处理器生成的# 1 "<stdint>"等垃圾并# 1 "<stdint>"受保护的#include

This shell command does it: 这个shell命令执行它:

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). (上面你可以看到2个反斜杠延续线+ 1个三字形(?? / == \\)反斜杠延续线)。

If you wish, you can protect #if s #ifdef s #ifndef s #endif s and #else s the same way. 如果你愿意,你可以用同样的方式保护#if s #ifdef s #ifndef s #endif s和#else s。

Suppose you want to see file.c. 假设您要查看file.c. If it contains the function main, you would need to change the name of that function for this to work. 如果它包含main函数,则需要更改该函数的名称才能生效。 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM