C语言 未使用函数的函数原型



我正在处理一段将用于多个项目的代码,我刚刚意识到如果函数的调用受到 if 的保护,我只能拥有函数原型(没有实际实现(。样本:

#ifndef __TEST_H
#define __TEST_H
uint32_t test_init(void);
#if CONFIG_TEST
bool is_test_supported(void);
#else
static inline bool is_test_supported(void)
{
    return false;
}
#endif
#endif

在我有的 c 文件中

...
if (is_test_supported())
    test_init();
...

在未定义CONFIG_TEST的系统上,上面的代码仍然可以正常编译。我想这是因为编译器足够聪明,可以理解代码路径永远不会执行,这是否正确,这种行为是可移植的吗?编译器是叮当的。

编辑:更正了函数名称上的一些错误...

不能依靠简单的 C if来删除函数调用。碰巧编译器优化了测试

if(test_is_supported())

if(false)

通过内联,然后进一步优化后续test_init()作为死代码输出。

但是不能保证这些优化。例如,如果您在没有优化的情况下进行编译,则很有可能不会进行优化,并且将生成函数调用。在这种情况下,即使链接器从未执行,它也需要函数的定义,否则它将失败。

更安全的方法是使用#if完全删除代码:

#if CONFIG_TEST
if(test_is_supported())
    test_init();
#endif

这将保证if和后续代码在未定义CONFIG_TEST时根本不会被编译(即,如果未定义test_init()(。

形式上,函数test_init用于代码中,并且定义是语言所必需的。

但是,智能编译器可能会找出受if保护的分支永远不会执行并消除对test_init的调用。如果编译器消除了对该函数的所有调用,则典型实现可能无法诊断问题,因为实际上并未使用该函数。具有外部链接的实体的"缺失定义"问题通常在链接阶段被诊断出来。当链接器无法将函数调用与函数定义匹配时,将报告此错误。如果没有调用,则无需匹配任何内容。

但是,同样,这不是您可以依赖的。在语言级别,没有"静态如果"这样的功能。从形式上讲,C 语言不允许你不定义这样的函数,即使它们受到在编译时已知条件的if的保护。

最新更新