如何“取消声明”函数原型或隐藏函数原型或#uninclude头

时间:2013-10-08 00:08:03

标签: c include header-files c-preprocessor

我希望函数A()调用B()作为内联宏,但我不希望B()对全世界可见。我只希望A()可见,如果用户意外使用B(),我想要编译错误。

我知道如何在没有内联的情况下做到这一点:

// a.h
void A(void);

// a.c
#include "b.h"
void A(void) { B(); }

如果我#include "a.h",那么我可以访问A()但不能访问B()。没关系;这就是我想要的。

现在我想做同样的事情,但通过将B内联到A来降低一个级别的调用复杂性,但我想隐藏B

// a.h
#include "b.h"
#define A() B()
#uninclude "b.h"   <----This is bogus, but I want the equivalent.


// main.c
#include "a.h"
A();  <-- ok
B();  <-- undefined function

这适用于低级固件,其中调用开销确实有所不同,但我不想放弃高级代码管理只是为了提高效率。在C ++中,这是微不足道的,但我正在寻找cpp hacks在纯C中执行它。

(在我的例子中,a表示HAL,b表示BSP。HAL是特定于处理器的,而BSP是特定于板(PCB)的

3 个答案:

答案 0 :(得分:1)

如果你这样做:

#define B A
#include "b.h"
#undef B

这会将“b.h”中B的定义更改为A的定义。这需要b.h定义B,而不仅仅是声明它,这可能不是您想要的。

然后,在显示这些行的文件中,代码可以使用A(使用A()等调用),但B的声明不在范围内。因此,尝试使用B会导致编译器错误。 (b.h中的其他声明将在范围内。)

答案 1 :(得分:1)

#define A() (B)()
#define B() syntax error

撰写B()的人会收到报告的语法错误(以某种形式或形式)。 撰写A()的人将生成对(B)()的调用,这是正常的。

当然,这并不能阻止有人在代码中写(B)(),但这只有80%。

答案 2 :(得分:1)

如果唯一的声明b.hB的声明,而不是定义,那么您可以在a.h中执行此操作:

// a.h
static inline void A(void)
{
    #undef _B__H_  //need this if you have more than one of these inline declarations
    #include "b.h"
    B();
}

假设b.h看起来像这样:

// b.h
#ifndef _B_H_
#define _B_H_
void B(void);
#endif

然后B的声明仅在A范围内。

a.c中,请务必在 b.h之前加入a.h (或执行#undef _B_H_以强制重新加载b.h)。否则,您将收到有关不兼容范围的警告或错误。 (a.h在本地范围包含b.h,而a.c在文件范围包含b.h,然后忽略所有剩余的本地范围包含。)

如果b.h进行其他声明,只要它们在函数体的范围内是可接受的,这也会有效。