我一直在调试一个特别阴险的错误,我现在认为这是由于包含(或不包含)不同标头时的不同行为引起的意外更改引起的。
这不完全是我的代码结构,但让我们来看看这个场景:
#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");
这肯定会完成工作,但没有充分的理由在运行时执行此任务,因为它完全在编译时确定。这只是我想在编译时看到的东西。
话虽如此,在这种情况下,使用打印(或记录或甚至抛出异常)可能是可以接受的事情,因为我不会真正关心减慢或混淆可疑代码。但是,如果我有两个代码路径,这两个代码路径都很重要,那就不适用了。我只想在编译时知道哪一个被激活。我不得不担心在程序开始时运行执行预处理器条件打印的代码。
这实际上只是一个冗长的问题,“我可以通过使用预处理器指令在编译期间将字符串回显到输出吗?”
答案 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