Ошибка: function was not declared in this scope when using a library without classes
Я создал библиотеку функций, которая не имеет и не должна иметь класса. Чтобы внутри библиотеки были функции, которые можно вызывать только из самой библиотеки, вы просто записываете их в файл .cpp и полностью оставляете вне заголовочного файла. Вот .cpp файл библиотеки (заголовочный файл пустой):
#include "Lib.h"
// Определение foo1
static void foo1(){
foo2();
}
// Определение foo2
static void foo2() {}
При включении библиотеки в пустой скетч и его компиляции я получаю следующее сообщение об ошибке:
ошибка: 'foo2' не был объявлен в этой области
В чем здесь проблема?
@LukasFun, 👍0
Обсуждение1 ответ
Лучший ответ:
При создании библиотеки с функциями, не упомянутыми в заголовочном файле, внезапно становится актуальным порядок появления в файле .cpp. Чтобы функция могла использоваться другой функцией, ее необходимо сначала объявить.
Первой возможностью в этом примере было бы определение foo2
перед определением foo1
следующим образом:
#include "Lib.h"
// Определение foo2
static void foo2() {}
// Определение foo1
static void foo1(){
foo2();
}
Однако это не только плохая практика, но и не всегда работает. Если существует какая-либо рекурсивная процедура, которая заставляет функции вызывать друг друга, вы не можете определить их обе перед соответствующей другой одновременно.
Более элегантный и надежный способ сделать это — сначала объявить каждую функцию, как обычно, в заголовочном файле, а затем определить, что они на самом деле делают. Тогда файл .cpp этой библиотеки будет выглядеть следующим образом:
#include "Lib.h"
static void foo1(); // Объявление foo1
static void foo2(); // Объявление foo2
// Определение foo1
void foo1(){
foo2();
}
// Определение foo2
void foo2() {}
Примечание: Эти объявления (static void foo1()
и static void foot2()
называются предварительными объявлениями., @Michel Keijzers
- Ошибка: invalid application of 'sizeof' to incomplete type 'int []' при попытке вычислить размер массива в библиотеке
- Ошибка: "'lcd' does not name a type" при использовании библиотеки LiquidCrystal.
- Ошибка компиляции ESP8266: "previous declaration of 'HTTPMethod HTTP_HEAD'"
- Ошибка компиляции библиотеки
- Библиотека не найдена при использовании команды arduino-cli (хотя работает с Arduino IDE)
- Добавить библиотеку в проект CLion
- Столкновение двух библиотек. Неоднозначные функции/переменные?
- Создание массива с длиной, полученной из библиотеки
Какое это имеет отношение к Ардуино? Я думаю, что это общий вопрос C/C++. Вы написали этот вопрос и ответили на него непосредственно для документирования этого?, @chrisl
Вероятно, этот вопрос применим и в более широком смысле, как и многие другие вопросы на этом сайте. Да, я написал и ответил на этот вопрос для документации., @LukasFun
ваша Lib.h неверна. это сломало автоматическую генерацию форвардных объявлений, @Juraj
он компилируется в Arduino IDE 1.8.10 с пустым Lib.h, @Juraj
теперь я вижу свою ошибку. Я думал у тебя функции в .ino, а ты пишешь, что это .cpp. поэтому в c/c++ вы не можете использовать функции, определенные позже в коде, поэтому вы должны использовать предварительные объявления/прототипы функций, но так было 50 лет назад, так что на самом деле это не проблема Arduino., @Juraj