我可以让C++预处理器在编译期间发送输出吗?

Ste*_* Lu 19 c++ c-preprocessor

我一直在调试一个特别阴险的错误,我现在认为这是由于包含(或不包含)不同标头时的不同行为引起的意外更改引起的.

这不完全是我的代码结构,但让我们来看看这个场景:

#include "Newly_created_header_which_accidentally_undefines_SOME_DEFINE.h"

// ...

#ifdef SOME_DEFINE
    code_which_i_believe_i_am_always_running();
#else 
    code_which_fails_which_i_have_forgotten_about(); // runtime error stack traces back here, but I don't know this... or maybe it's some strange linker error
#endif
Run Code Online (Sandbox Code Playgroud)

我搜索了我的git提交并缩小了bug的原因,无数次地编译和运行我的代码,只是在几个小时之后发现导致bug的唯一区别是包含看起来完全是良性的不相关的标题.

也许这是一个很好的论据,为什么预处理器基本上只是糟透了.

但我喜欢它.预处理器很酷,因为它可以让我们制作快捷方式.只是这些快捷方式中的一些,如果不小心使用,会让我们陷入困境.

所以在这个时刻,如果我可以使用一个指令#echo "Running old crashy code",这将有助于我在编译期间能够看到这一点,所以我可以立即提示我开始调查为什么没有定义SOME_DEFINE.

据我所知,确定SOME_DEFINE是否定义的直接方法是做类似的事情

#ifndef SOME_DEFINE
    printf("SOME_DEFINE not defined!!\n");
Run Code Online (Sandbox Code Playgroud)

这肯定会完成工作,但没有充分的理由在运行时执行此任务,因为它完全在编译时确定.这只是我想在编译时看到的东西.

话虽这么说,在这种情况下,使用打印(或记录或甚至抛出异常)可能是可以接受的事情,因为我不会真正关心减慢或混乱可疑代码.但是,如果我有两个代码路径,这两个代码路径都很重要,那就不适用了.我只想在编译时知道哪一个被激活.我不得不担心在程序开始时运行执行预处理器条件打印的代码.

这实际上只是一个冗长的方式来问一个问题,"我可以使用预处理器指令在编译期间将字符串回显到输出吗?"

sar*_*old 20

如果使用该#error指令,将直接打印输出并且编译将停止:

$ make days_in_month
cc     days_in_month.c   -o days_in_month
days_in_month.c:2:2: error: #error "ugly!"
make: *** [days_in_month] Error 1
$ 
Run Code Online (Sandbox Code Playgroud)

这可能不是您想要的,但它可以快速完成工作.

$ cat days_in_month.c
#include <stdio.h>
#error "ugly!"
...
Run Code Online (Sandbox Code Playgroud)

如果您希望继续处理,可以使用#warning:

$ make days_in_month
cc     days_in_month.c   -o days_in_month
days_in_month.c:2:2: warning: #warning "ugly!" [-Wcpp]
Run Code Online (Sandbox Code Playgroud)
$ head days_in_month.c 
#include <stdio.h>
#warning "ugly!"
Run Code Online (Sandbox Code Playgroud)


Ste*_* Lu 5

在这里找到符合我所寻找内容的更多答案:https : //stackoverflow.com/a/3826876/340947

抱歉@sarnold