【发布时间】:2016-12-09 07:01:10
【问题描述】:
为了避免不可能的情况,可以将问题减少到两种情况。
案例 1
第一种(最简单的)情况是预处理器有机会检测到它的情况,即有一个预处理器指令取决于预定义的宏(在输入的第一行之前定义)与否。例如:
#ifdef FOO
#define BAR 42
#else
#define BAR 43
#endif
取决于FOO 是否被预定义。但是文件
#undef FOO
#ifdef FOO
#define BAR 42
#endif
没有。更难的情况是检测依赖项是否确实重要,而在上述情况下并不重要(因为FOO 或BAR 都不影响输出)。
案例 2
第二种(更难的)情况是成功编译取决于预定义的宏:
INLINE int fubar(void) {
return 42;
}
就预处理器而言,无论ENTRY_POINT 是否是预定义的,这都很好,但除非INLINE 被仔细定义,否则代码将无法编译。同样,在这种情况下,我们可以排除输出不受影响的情况,但我找不到这样的例子。这里的复杂之处在于示例中:
int fubar(void) {
return 42;
}
预定义的fubar 可以改变它的成功编译,因此可能需要将其限制为需要预定义符号才能成功编译的情况。
我猜这样的工具类似于预处理器(在第二种情况下是 C 解析器)。问题是是否有这样的工具?还是有只处理第一种情况的工具?还是根本没有?
【问题讨论】:
-
Tool-recs 是题外话,一般来说,你知道的,对吧?
-
@SouravGhosh 这不是关于工具的推荐,而是它的存在(当然,为了支持肯定的答案,可能必须给出一个例子)。
-
对于那些建议将其作为工具记录问题结束的人:要成为工具记录问题,至少需要 两个 这样的工具(这将回答这个问题)。如果只有一个这样的工具,那么推荐就不会太多,如果没有这样的工具,您会推荐哪一个?你仍然认为你支持你的说法,即这是一个工具记录问题吗?如果你这样做,那么我希望看到它们,因为它会回答这个问题。
-
所有包含标识符的东西都取决于该标识符是否被预定义为宏(除非它首先出现在 undef 或 define 指令中)。您的示例不仅依赖于
INLINE,还依赖于int、fubar、void和return。 -
C 编译器是最接近现实世界的替代方案,因为编译失败通常发生在缺少定义的宏附近。您可能会添加某种错误检查程序,在编译器报告的错误附近找到看起来像宏观的标记。但是,如果缺少宏定义导致生成有效但逻辑上不正确的代码,则这些都无济于事。像往常一样,潜在问题的解决方案是文档,而不是一些自动工具。在这种情况下,靠近源文件开头的一块信息丰富的 cmets 会很好。
标签: c c-preprocessor static-analysis