23

我一直在调试一个特别隐蔽的错误,我现在认为它是由包含(或不包含)不同标头时的不同行为引起的意外更改引起的。

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

#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 提交并缩小了错误的原因,无数次编译和运行我的代码,但在几个小时后才发现导致错误所需的唯一区别是包含看起来完全良性和不相关的标题。

也许这是为什么预处理器基本上很烂的一个很好的论据。

但我喜欢它。预处理器很酷,因为它可以让我们创建快捷方式。只是这些捷径中的一些,如果不小心使用,会咬我们的屁股。

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

据我所知,确定是否定义了 SOME_DEFINE 的直接方法是执行类似的操作

#ifndef SOME_DEFINE
    printf("SOME_DEFINE not defined!!\n");

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

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

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

4

2 回答 2

23

如果使用该#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!"
于 2012-06-26T23:01:26.353 回答
4

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

对不起@sarnold

于 2012-07-01T03:27:42.303 回答