如何避免C中的未定义符号

我正尝试在C中创建一个模块化项目。我正在为嵌入式ARM CPU编写固件。 它由不同的部分组成,由于内存限制,不能同时编译。

简化,假设我有一个模块A,它管理固件的所有可选部分,每个模块都在其模块中编码(B,C,D等等)

在模块AI中使用#ifdef子句:

#ifdef USE_B
  #include "B.h"
#endif

#ifdef USE_C
  #include "C.h"
#endif

...

然后,除此之外,我只需#define我想包含的模块的关键字。

我在文件Zc中有一些全局变量应该停留在那里。 由于我的目标是最大限度地减少内存使用,所以我将它们的声明放在#ifdef中

#ifdef USE_B
  uint8_t usedonlybyb;
#endif

#ifdef USE_C
  uint8_t usedonlybyc;
#endif

...

会发生什么是即使文件B和文件C在编译时与项目的其他部分完全断开连接,在编译结束时,我会为外部变量“usedonlybyx”得到“未定义符号”错误,这些错误无法通过禁用的模块。

我想保留在模块Z中声明的usedonlybyx变量,因为那个是通用设置模块。

有没有一种优雅的方式来抑制这些错误,并且仍然能够在我的范围内取得成功?

我应该简单地将整个模块B,C ...放在#ifdef / #endif中吗?


更简单的解决方案是在#ifdef USE_B#endif内的bhbc文件中包含整个实现和声明。 其他模块也一样。 这样,一个模块的所有条件编译都是孤立的,并且不必在使用#include "bh"其他代码中。

// b.h
#ifdef USE_B
// declarations and include guards
#endif

// b.c
#ifdef USE_B
// definitions
#endif

// a.c
#include "b.h" // <- no USE_B needed here

您可以尝试将B和C模块拆分为离散库组件,确保这些库使用的全局变量都包含在它们中。 这可能需要将变量的extern声明移动到库接口文件,或者根据需要提供访问器方法。

另外,如果你使用的是GCC,编译器有一个以__attribute__((weak))形式的语言扩展,它将声明一个'即时未定义'的'任何其他'版本的将保持链接器快乐的变量。

链接地址: http://www.djcxy.com/p/73587.html

上一篇: how to avoid undefined symbols in C

下一篇: Declare a variable that is Defined in a struct