gpt4 book ai didi

c - 将源代码多次传递到 cpp

转载 作者:行者123 更新时间:2023-11-30 15:30:49 25 4
gpt4 key购买 nike

基本上,我试图将源代码两次传递给 gcc 的 cpp,然后直接传递给 gcc 的 c 编译器。

至于为什么,我相信有些东西永远无法在宏中内联。

这是一个例子:

/* say i want to make an inline definition that can be inserted to any other macros */
#include <stdio.h>

#define DEF_X #define X 22

int main(void)
{
DEF_X
printf("%u", X);

return 1;
}

然后简单地编译: gcc $MY_DIR/test_multi_pass.c -o $MY_DIR/test.exe

当然,这不会起作用,因为当你编译它时(无论是否在 gcc 中)它会被预处理,然后直接传递给编译器(至少官方是这样):

    # 1 "d:/Projects/Research/tests/test_multi_pass.c"
# 1 "<command-line>"
# 1 "d:/Projects/Research/tests/test_multi_pass.c"
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 1 3
# 19 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 3
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/_mingw.h" 1 3
# 32 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/_mingw.h" 3
# 33 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/_mingw.h" 3
# 20 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 2 3
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stddef.h" 1 3 4
# 213 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stddef.h" 3 4
typedef unsigned int size_t;
# 325 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stddef.h" 3 4
typedef short unsigned int wchar_t;
# 354 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stddef.h" 3 4
typedef short unsigned int wint_t;
# 27 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 2 3

# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stdarg.h" 1 3 4
# 40 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stdarg.h" 3 4
typedef __builtin_va_list __gnuc_va_list;
# 29 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 2 3
# 129 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 3

ETC_ETC_ETC_IGNORED_FOR_BREVITY_BUT_LOTS_OF_DECLARATIONS

int main(void)
{
#define X 22
printf("%u", X);

return 1;
}

现在关注上面预处理文件的最底部。

纯粹来说,就c编译器而言,“#define X 22”不是有效的语法,任何编译器都可能会说有一个杂散的“#”。

所以我尝试了一些技巧:

cpp /$MY_DIR/test_multi_pass.c | cpp

输出是:

    # 1 "<stdin>"
# 1 "<command-line>"
# 1 "<stdin>"
# 1 "d:/Projects/Research/tests/test_multi_pass.c"
# 1 "<command-line>"
# 1 "d:/Projects/Research/tests/test_multi_pass.c"
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 1 3
# 19 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 3
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/_mingw.h" 1 3
# 32 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/_mingw.h" 3
# 33 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/_mingw.h" 3
# 20 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 2 3
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stddef.h" 1 3 4
# 213 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stddef.h" 3 4
typedef unsigned int size_t;
# 325 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stddef.h" 3 4
typedef short unsigned int wchar_t;
# 354 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stddef.h" 3 4
typedef short unsigned int wint_t;
# 27 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 2 3

# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stdarg.h" 1 3 4
# 40 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/include/stdarg.h" 3 4
typedef __builtin_va_list __gnuc_va_list;
# 29 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 2 3
# 129 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 3

ETC_ETC_ETC_IGNORED_FOR_BREVITY_BUT_LOTS_OF_DECLARATIONS

int main(void)
{

printf("%u", 22);
return 1;
}

现在它完全按照我们想要的方式完成,并将 X 定义为 22。这并不完全是我打算在我的代码库中使用的方式(我会将其与 #undef 等耦合),但相当说明了这种尝试清楚。

然后我尝试了:

gcc -o $MY_DIR/test.exe < cpp /$MY_DIR/test_multi_pass.c | cpp

我知道在GCC中,启动编译后,由cpp进行预处理,然后c编译器对代码进行语法分析(将i​​变成抽象语法树),然后安静调用再次使用预处理器来处理所有程序集命名(对于链接器)等等。

因此,至少在gcc中,一段代码要经过两次预处理。因此,上一个文件可能再次与预处理的下一次迭代采用相同的格式(希望它不会引入更多额外的代码来进一步破坏代码) future 的预处理)。

所以也许我们可以对其进行4次预处理(因为我们事先对其进行了两次预处理)。因此,上面的黑客攻击。

但是它给出了什么:

sh: cpp: No such file or directory
# 1 "<stdin>"
# 1 "<command-line>"
# 1 "<stdin>"

现在,这是 cpp 无法对其进行 4 次预处理的根本错误还是我刚刚输入了错误的 CLI 命令?

最佳答案

GCC 仅预处理您的源代码一次。如果它在构建过程中稍后多次调用预处理器,那是无关紧要的,因为它在该阶段进行的预处理不是您的源代码;而是您的源代码。它是生成的汇编代码或其他东西。

如果您希望在实际编译之前在源代码上运行两次预处理器,您可以手动运行一次预处理器,然后在输出上正常运行 GCC(这将自动执行另一次预处理器传递)。例如:

cpp foo.cpp.in -o foo.cpp
gcc -c foo.cpp

然而,对于一个不清楚的问题,这种双重预处理是一个相当尴尬的解决方案。可能有更好的方法来完成您实际想要完成的任何事情。

<小时/>

顺便说一句,你的命令的原因

gcc -o $MY_DIR/test.exe < cpp /$MY_DIR/test_multi_pass.c | cpp

不起作用的是您将gcc标准输出流输入到cpp中。您的意思是“编译我的程序,并对编译器打印到屏幕上的任何消息运行 cpp”。将 |任何命令末尾的 cpp 表示预处理其输出,而不是其输入。

关于c - 将源代码多次传递到 cpp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25336905/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com