使用 ifdef 包含文件会导致多个定义

Including files with ifdef resulting in multiple definitions

我正在尝试理解 ifdef 指令 + 包括文件,虽然它在我看来很有意义,但似乎并不像我想象的那么简单:我得到了一个“多个定义”错误。

我想做的是让编译器根据是否定义了某些文件来包含某些文件。

我有a.cppb.cpp,两者功能相同,但逻辑略有不同:

a.cpp

int aFunction(int apples){
    return apples * 10;
}

b.cpp

int aFunction(int apples){
    return apples * 0.1;
}

我主要是想这样做:

#ifdef USE_B
#pragma message "Using b"
#include "b.cpp"
#else
#pragma message "Using a"
#include "a.cpp"
#endif

然后在我的实际代码中,调用它

aFunction(5);

我曾假设编译器会读取这些指令,并且 select a.cppb.cpp 因此编译后的源代码将仅包含 implementation/instance of [=22] =].

但它正在做一些我不太理解的事情并导致“多重定义”错误。

更多错误如下:

sketch\b.cpp.o (symbol from plugin): In function `aFunction(int)':

(.text+0x0): multiple definition of `aFunction(int)'

sketch\a.cpp.o (symbol from plugin):(.text+0x0): first defined here

不太清楚为什么它在定义 USB_B 时甚至查看 a.cpp

我已经定义了它:

#define USE_B 1

(旁注:不确定是否重要,但我在 arduino 环境中工作)。



已添加thoughts/reasoning

看来我在预处理器、编译和链接过程中有点混乱。我承认,这不是我太熟悉的东西。 (感谢您清理让我想起这个的标签)

对我来说,这很有效并实现了我的目标:

#define USE_B 1

#ifdef USE_B
#pragma message "Using b"
int aFunction(int apples){      return apples * 0.1;    } // contents of b.cpp
#else
#pragma message "Using a"
int aFunction(int apples){      return apples * 10;     } // contents of a.cpp
#endif

void main(){
    aFunction(5);
}

如果我定义 USE_B,那么只有 aFunction 的 'b' 版本会进入生成的源(我假设在预处理器过程之后),因此只有aFunction 的其中一个版本已编译。

据我了解,#include 指令的工作方式就好像它是 'copying and pasting' 包含文件的内容到 #include 指令所在的位置。也许我在这里错了?这主要是我感到困惑的地方,如果 #include 通过将 a.cppb.cpp 的内容复制到我的主文件中来工作,我不应该得到类似于上面的内容吗? (同样,对我来说效果很好)

除了 #include 源文件之外,您可以做的是 Microsoft 用来绑定其两个 API 版本(xxxA()xxxW()函数):

#ifdef USE_B
#pragma message "Using b"
#define aFunction aFunctionB
#else
#pragma message "Using a"
#define aFunction aFunctionA
#endif

并在实施中

a.cpp

int aFunctionA(int apples){
    return apples * 10;
}

b.cpp

int aFunctionB(int apples){
    return apples * 0.1;
}

并在您的实际代码中调用它

aFunction(5);

经过一番挖掘,似乎整个过程中有一些我不理解的地方。无论如何,似乎共识(从这里的回复和我在其他地方可以读到的内容)是使用 pre-processor 并不是做我想做的事情的正确方法,应该使用构建系统。

不可否认,它在我心中仍然有点奇怪,但也许有一天我会看到它。由于项目很小,我想我会为此编写一个简单的构建脚本。