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

时间:2015-01-27 18:32:46

标签: arduino arduino-ide

我希望有人可以解释为什么这段代码无法在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:\arduino\hardware\arduino\cores\arduino/main.cpp:11: undefined reference to `setup'
C:\arduino\hardware\arduino\cores\arduino/main.cpp:14: undefined reference to `loop'

3 个答案:

答案 0 :(得分:4)

原因是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,编译器将不会看到生成的函数原型。只需将编译器输出设置为verbose,并查看构建目录中生成的代码。

解决所有这些痛苦的办法是找到一些方法来阻止IDE弄乱你的东西。我在过去使用TRICK17宏解决了函数原型的一些类似问题(详见here)。我不会进入这个宏的混乱实现,因为现在我发现了一个非常优秀的解决方案。

  • 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() {  }

答案 1 :(得分:1)

OK!在Udo的帮助下弄清楚了。

发生了什么事: 当Arduino IDE编译时,它会自动为* .ino文件中的所有函数创建所有标题声明。我假设当它这样做时,它必须触发遇到的第一个变量。但是如果你做了我所做的事情并且在代码中使用第一个变量上的#if,#else指令并省略它,那么它将无法为循环,设置创建所有正确的声明, 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() {  }

答案 2 :(得分:0)

也只是一个分号工作(而不是例如完整的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() {  }