使用隐式声明隐藏助手功能

时间:2019-01-20 10:54:35

标签: c macros header

根据指定的here C对它不知道的函数进行隐式声明。因此,我倾向于利用它来隐藏实现细节。我定义了以下头文件:

#ifndef TEST_H
#define TEST_H

#define PRINT(msg) \
    do{\
        _print_info_msg(msg);\
        printf(msg);\
    } while(0)

#endif //TEST_H

和相应的C文件:

#include "test.h"

void _print_info_msg(const char *str){
    printf("INFO: printing %s\n", str);
}

在编译此代码时,编译器会警告implicit declaration of function ‘_print_info_msg’ [-Wimplicit-function-declaration]

我看到的好处是,我们不会向包含_print_info_msg的任何人直接公开辅助函数(test.h),但我们利用了链接器,因此提供了_print_info_msg实现

我不确定这种方法...甚至有意义吗?对我来说,这看起来很丑陋,但这是我为隐式声明找到的唯一“用例”。

1 个答案:

答案 0 :(得分:3)

TL; DR:您让自己容易受到错误的攻击,并没有真正隐藏任何东西。

C自C99以来就没有隐式声明规则,甚至在不建议使用之前,它都不建议使用。它禁用了对函数参数的静态类型检查,并使我们在多个方面都可以接受未定义的行为。

不要使用它!该编译器警告仅仅是为了不破坏旧代码库,但这应该是一个错误。实际上,当要求编译器提供最严格的一致性模式时,错误。

除此之外,您还没有真正隐藏任何东西。该宏必须出现在头文件中,因此将使每个翻译单元都知道该符号。您没有隐藏任何类似的东西。更不用说该符号必须具有外部链接(否则您的程序也不会链接)。

因此,只需在宏之后或之前添加一个函数声明,以确保即使由本世纪的编译器编译,您的代码也是正确的。

哦,在文件范围内带有下划线的标识符保留给实现(您的工具链)。这意味着您不能使用带下划线的文件范围标识符,以免出现鼻恶魔。最好重命名_print_info_msg