在 Arduino IDE 中定义 #if #else #endif 中的变量



我希望有人能阐明为什么这段代码不能在Arduino IDE中编译(使用1.0.5)。以下代码仅在 DEBUG=1 时编译,但如果设置为 0,则不编译。

我希望实现的只是一种在交换 LED 驱动程序时使用相同的代码的简单方法,只需在重新编译和上传之前翻转 DEBUG 位。

注意:此示例是要在 IDE 中编译的完整代码(不需要其他代码)。

问题代码:

#define DEBUG 0 //DEBUG=1 works, DEBUG=0 causes compiler error
#if DEBUG == 1
  int x = 123;
  //Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
#else
  int x = 567;
  //Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();
#endif
void setup() {  }
void loop() {  }

错误:

core.a(main.cpp.o): In function `main':
C:arduinohardwarearduinocoresarduino/main.cpp:11: undefined reference to `setup'
C:arduinohardwarearduinocoresarduino/main.cpp:14: undefined reference to `loop'

原因是Arduino IDE很糟糕。在引擎盖下,它生成这样的 c 代码

#define DEBUG 0 //DEBUG=1 works, DEBUG=0 causes compiler error
#if DEBUG == 1
  int x = 123;
  //Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
#else
  int x = 567;
  //Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();
#endif
void setup() {  }
void loop() {  }

因此,如果 debug==0,编译器将看不到生成的函数原型。只需将编译器输出设置为详细,然后自己查看构建目录中生成的代码即可。

所有这些痛苦的解决方案是找到一些方法来阻止IDE弄乱你的东西。我过去在函数原型上遇到了一些类似的问题,我用TRICK17宏解决了这些问题(有关详细信息,请参阅此处)。我不会进入这个宏的混乱实现,因为到目前为止我找到了一个非常优越的解决方案。

  • IDE 不知道命名空间
  • 因此,它不会触及命名空间内的任何内容
  • 允许
  • 使用空命名空间名称,这将建立匿名命名空间。此命名空间中的实体不需要前缀来寻址它们。

因此,新的解决方案是

namespace {
// name of namespace left empty --> this is the anonymous namespace
// now the IDE will not mess with our stuff
#define DEBUG 0 //DEBUG=1 works, DEBUG=0 causes compiler error
#if DEBUG == 1
  int x = 123;
  //Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
#else
  int x = 567;
  //Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();
#endif
}
void setup() {  }
void loop() {  }

好的!在Udo的帮助下想通了。

发生了什么:当Arduino IDE编译时,它会自动为您*.ino文件中的所有函数创建所有标头声明。我假设当它这样做时,它必须在遇到的第一个变量上触发。但是,如果您按照我所做的操作,并且在代码中的第一个变量上使用 #if,#else 指令并省略它,那么它将无法为 loop、setup、foo、bar() 等创建所有正确的声明。如果第一个变量是"可见的",它就会正确创建所有内容。

解决方案:在代码顶部的 #if,#else 内容之前创建一个无意义的变量。

现在工作的例子:

byte nonsense_var = 0;  //this line solves everything!
#define DEBUG 0         //DEBUG=1 works, DEBUG=0 works now!
#if DEBUG == 1
    Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
#else
    Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();
#endif
void setup() {  }
void loop() {  }

也只是一个分号工作(而不是一个完整的var声明)

;  //this line ALSO solves everything!
#define DEBUG 0         //DEBUG=1 works, DEBUG=0 works now!
#if DEBUG == 1
    Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
#else
    Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();
#endif
void setup() {  }
void loop() {  }

最新更新