使用 ifdef 包含文件会导致多个定义
Including files with ifdef resulting in multiple definitions
我正在尝试理解 ifdef
指令 + 包括文件,虽然它在我看来很有意义,但似乎并不像我想象的那么简单:我得到了一个“多个定义”错误。
我想做的是让编译器根据是否定义了某些文件来包含某些文件。
我有a.cpp
和b.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.cpp
或 b.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.cpp
和 b.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 并不是做我想做的事情的正确方法,应该使用构建系统。
不可否认,它在我心中仍然有点奇怪,但也许有一天我会看到它。由于项目很小,我想我会为此编写一个简单的构建脚本。
我正在尝试理解 ifdef
指令 + 包括文件,虽然它在我看来很有意义,但似乎并不像我想象的那么简单:我得到了一个“多个定义”错误。
我想做的是让编译器根据是否定义了某些文件来包含某些文件。
我有a.cpp
和b.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.cpp
或 b.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.cpp
和 b.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 并不是做我想做的事情的正确方法,应该使用构建系统。
不可否认,它在我心中仍然有点奇怪,但也许有一天我会看到它。由于项目很小,我想我会为此编写一个简单的构建脚本。