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

时间:2012-06-26 22:57:32

标签: 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

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

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

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

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

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

之类的事情
#ifndef SOME_DEFINE
    printf("SOME_DEFINE not defined!!\n");

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

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

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

2 个答案:

答案 0 :(得分:18)

如果使用#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
$ 

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

$ cat days_in_month.c
#include <stdio.h>
#error "ugly!"
...

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

$ make days_in_month
cc     days_in_month.c   -o days_in_month
days_in_month.c:2:2: warning: #warning "ugly!" [-Wcpp]
$ head days_in_month.c 
#include <stdio.h>
#warning "ugly!"

答案 1 :(得分:4)

根据我所寻找的内容回答更多内容:https://stackoverflow.com/a/3826876/340947

抱歉@sarnold