Typedef 在第一个函数定义后不起作用?

Typedef doesn't work after the first function definition?

所以我正在处理一些 Arduino(IDE 版本 1.8.9,FWIW)代码,我发现如果将 typedef 放在函数定义之后似乎不起作用。例如,以下草图无法使用 error: 'foo' does not name a type 进行编译,但如果您删除第一行,则没有问题。

bool baz() { return false; }
typedef uint32_t foo;
foo bar() { return 1; }

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

这是我不熟悉的 typedef 工作原理的一些细微差别,Arduino 特有的一些奇怪之处,还是只是一个错误?

(请注意,uint32_t 的具体选择在这里并不重要;相同的行为发生在任何类型上。)

Arduino 工具链包括一个预处理器,它试图使编写 C++ 更容易。 Arduino 的预处理器所做的其中一件事是在文件顶部插入草图中所有函数的声明。这意味着传递给 g++ 的实际 C++ 代码如下所示:

#include <Arduino.h>
#line 1 "E:\Documents\Arduino\sketch_jun16a\sketch_jun16a.ino"
#line 1 "E:\Documents\Arduino\sketch_jun16a\sketch_jun16a.ino"
#line 1 "E:\Documents\Arduino\sketch_jun16a\sketch_jun16a.ino"
bool baz();
#line 3 "E:\Documents\Arduino\sketch_jun16a\sketch_jun16a.ino"
foo bar();
#line 5 "E:\Documents\Arduino\sketch_jun16a\sketch_jun16a.ino"
void setup();
#line 10 "E:\Documents\Arduino\sketch_jun16a\sketch_jun16a.ino"
void loop();
#line 1 "E:\Documents\Arduino\sketch_jun16a\sketch_jun16a.ino"
bool baz() { return false; }
typedef uint32_t foo;
foo bar() { return 1; }

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

如您所见,foo bar(); 是在您的 typedef 引入名称 foo 之前声明的。

要解决此问题,请添加您自己的 bar 声明。 Arduino 的预处理器只会添加你自己没有声明的函数声明:

bool baz() { return false; }
typedef uint32_t foo;
foo bar();
foo bar() { return 1; }

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

至于为什么当 typedef 是草图的第一行时这不是问题:看起来 Arduino 的预处理器提升了 typedefusing 声明以及现有的函数声明和 class 定义直到文件顶部,在它添加的函数声明之前,但前提是它们出现在任何函数定义之前(不包括 class 内联定义的成员函数 class 定义).