gcc ESP32编译器给出“多重定义”错误

ecbunoof  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(181)

得到了一个我以前没有遇到过的新问题,当在VSCode下使用Espressif ESP 32 ESP-IDF标准设置时出现了这个问题。它使用GNU编译器。
我在共享同一名称的变量上遇到了“多重定义”错误,但这些变量应该是本地变量。
因此,我使用.c和.h文件对的方法。
在.c文件中,我在顶部执行此操作

#define IO_EXPANDER_C       //<<<This is a unique define for this file pair
#include "io-pca9539.h"

在我的.h文件中,我这样做:

#ifdef IO_EXPANDER_C
//----- INTERNAL ONLY MEMORY DEFINITIONS -----
uint8_t *NextReadDataPointer;

//----- INTERNAL & EXTERNAL MEMORY DEFINITIONS -----
//(Also defined below as extern)
int SomeVariableIWantAvailableGlobally;

#else
//----- EXTERNAL MEMORY DEFINITIONS -----
extern int SomeVariableIWantAvailableGlobally;

#endif

这是一个非常简单的系统,任何其他包含.h文件的.c文件(在其include语句上没有#define),都会获得其所有外部变量,而不是其局部变量。但是,在VSCode中使用我的基于ESP-IDF的项目进行编译时,我会遇到与“NextReadDataPointer”相关的“multiple definition of”错误
我在另一个文件对中使用了相同的变量名NextReadDataPointer,但是它从来没有在任何地方声明为extern,并且每个文件对都使用了一个单独的#define(IO_EXPANDER_C和LED_C)。
我以前从未见过C编译器这样做,就好像它把局部定义搞混了一样。#define应该只在声明它的文件中以及该文件中的任何include中有作用域。
更奇怪的是,如果项目已经构建,但函数只从共享相同局部变量名的文件对中的一个调用,则不会生成此错误;而只有从主应用程序的两个文件对调用函数时,才会生成此错误。
有人能解释一下GNU C编译器是否为标准的ESP-IDF项目做了一些时髦的事情吗?

lnvxswe2

lnvxswe21#

uint8_t *NextReadDataPointer;创建了一个在所有翻译单元上都可见的变量,即“private”的反义词。如果你在多个c文件中包含了这个头文件,并且链接器试图将它们链接在一起;它会看到冲突,你要找的关键字是static,例如static uint8_t *NextReadDataPointer;创建了一个变量,在翻译单元中不可见,如果只从其中一个文件调用函数,你不会看到问题的原因是,在这种情况下,链接器不会查看另一个文件。
就我个人而言,我会避免这种聪明的预处理器黑客攻击,因为很难看到文件是如何相互包含的,也很难调试由此产生的问题。我建议坚持标准的方式,在头文件中声明共享的东西,并将私有的东西保存在c文件中(前面有static)。

相关问题