Объявление глобальных переменных в отдельном файле: конфликт компилятора
Итак, у меня есть:
1/ Мой файл myapp.ino
, который включает src.h
(реализован в src.cpp
). Скомпилировано для Arduino Uno.
2/ У меня также есть файл unit-tests.cpp
, предназначенный для тестирования функций в src.cpp
. Скомпилировано для настольных компьютеров/MacOS.
Я не понимаю, где объявлять глобальные переменные. Эти три файла должны иметь к ним доступ (я знаю, что это не на 100 % хорошая практика, но это простое приложение).
Упрощенный пример:
src.h
#ifndef CHAOS_SRC_H
#define CHAOS_SRC_H
extern float min_delta;
extern float max_delta;
extern float min_val;
extern float max_val;
extern float rescale_power;
#endif
src.cpp
#include "src.h"
//float min_delta;
//float max_delta;
//float min_val;
//float max_val;
float rescale_power;
myapp.ino
#include "src.h"
float presets[4][5] = {
// MIN_DELTA, MAX_DELTA, MIN_VAL, MAX_VAL
{0, 500, 0, 30, 1}, // Old tape
{200, 2000, 0, 255, 1}, // Broken tape
{0, 500, 90, 100, 3}, // New broken tape (delay time at ~ min)
{0, 100, 90, 140, 3}, //
};
float min_delta = presets[PRESET][0];
float max_delta = presets[PRESET][1];
float min_val = presets[PRESET][2];
float max_val = presets[PRESET][3];
float rescale_power = presets[PRESET][4];
unit-tests.cpp
#include "src.h"
int main()
{
}
Когда я компилирую myapp.ino
для Arduino, компилятор сообщает, что rescale_power
имеет несколько определений. Поэтому я удаляю его из src.cpp
, и он работает.
Но затем, когда я компилирую unit-tests.cpp
для настольных компьютеров, этот компилятор жалуется на Неопределенные символы для архитектуры x86_64: "_rescale_power"
.
Повторное добавление решает проблему.
И так далее.
Какой путь, пожалуйста? Есть какая-то логика?
@theredled, 👍-1
Обсуждение1 ответ
Если у вас есть пара файлов заголовок/реализация, общее правило таково:
что реализация определяет все, что объявляет заголовок.
Таким образом, вы сохраняете определение rescale_power
в src.cpp. Поскольку каждый
переменная должна быть определена только один раз, вам придется удалить определение
из myapp.ino.
Если по какой-то причине src.cpp не может узнать желаемое начальное значение
передать rescale_power
, затем использовать инициализацию по умолчанию и назначить
желаемое значение в myapp.ino:
void setup() {
rescale_power = presets[PRESET][4];
}
Изменить: В комментарии вы написали:
Я не понимаю, почему я не могу поместить
rescale_power = 4
вmyapp.ino
снаружи функция?
Потому что это задание. Присвоения — это утверждения: они выполняется во время выполнения и может быть записан только внутри функций. Для ссылка, вот синтаксис объявления, определения и задание:
// Объявление:
extern float rescale_power;
// Определения:
float rescale_power; // неявно инициализируется нулем
float rescale_power = 2; // с явной инициализацией
// Назначение:
rescale_power = 4;
Спасибо за Ваш ответ. Я удалил объявление везде, кроме src.php. Это работает для unit-tests.cpp
; но это не работает для myapp.ino
: ошибка:
rescale_power' не была объявлена в этой области`., @theredled
@theredled: Вы сохранили объявление rescale_power в src.h? Этот файл все еще включен в myapp.ino?, @Edgar Bonet
Нет, я удалил. Теперь у меня есть объявление в src.h
extern float rescale_power;
и определение в src.cpp
float rescale_power = 2;
.
Теперь это работает! Но я не понимаю, почему я не могу поместить rescale_power = 4 в myapp.ino вне функции?, @theredled
Отредактировано----------, @theredled
- Получена ошибка недопустимого преобразования из 'const char*' в 'const uint8_t*
- Как написать неблокирующий код, для опроса датчика на 100 Гц
- Область действия объекта RtcDateTime при объявлении вне функции
- попытка сделать модульный код wemos d1 вызывает collect2: ошибка: ld вернул 1 статус выхода статус выхода 1
- Как объявить массив переменного размера (глобально)
- устаревшее преобразование из строковой константы в 'char*'
- Как получить тип данных переменной?
- Как запрограммировать ардуино на чистом C/C++?
Почему минус, пожалуйста?, @theredled
Не уверен, но недавно [вопросы были отклонены, чем обычно.](https://arduino.meta.stackexchange.com/questions/2757/who-is-down-voting-all-and-every-question). Вопрос подлежит закрытию, вероятно, на том основании, что это скорее вопрос C++, чем вопрос Arduino. Я не могу сказать, что вас смущает. Ошибка укажет на каждое из нескольких определений. Вы использовали
extern
. Понимаете ли вы значение слова «extern» в том смысле, как вы его используете?, @timemageРазве это не единственный способ сделать переменную доступной извне?, @theredled
И компиляторы Arduino и g++ не реагируют одинаково, поэтому я предполагаю, что в Arduino должно быть что-то особенное., @theredled
Определение переменной несколько раз, как в показанном коде, приведет к поломке g++ (или любого другого компилятора C++), независимо от того, запускается ли он из процесса сборки или из более традиционной системы сборки, отличной от Arduino. Чтобы внести ясность, я только говорю вам, что это не то дерево, на которое стоит лаять. Проверьте ответ Эдгара Боне еще раз, понимая, что
extern
приведет к тому, что переменные будут *только* **объявлены**, а не *также* **определены**, как по умолчанию., @timemage