Typedef не работает после первого определения функции? - PullRequest
0 голосов
/ 16 июня 2019

Итак, я использую код Arduino (IDE версии 1.8.9, FWIW) и обнаружил, что typedefs не работают, если их поместить после определения функции.Например, следующий скриншот не компилируется с 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 здесь не имеет значения; такое же поведение происходит с любым типом.)

1 Ответ

4 голосов
/ 16 июня 2019

В набор инструментов Arduino входит препроцессор, который пытается упростить написание C ++. Препроцессор Arduino выполняет одну из функций - вставляет объявления для всех функций в вашем эскизе вверху файла. Это означает, что фактический код C ++, переданный в g ++, выглядит следующим образом:

#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 поднимает объявления typedef и using вместе с существующими объявлениями функций и определениями классов вплоть до начало файла, перед объявлениями функций, которые он добавляет, но только если они появляются перед какими-либо определениями функций (не считая функций-членов класса, определенных встроенными в определении класса).

...