Объявление глобальных переменных в отдельном файле: конфликт компилятора

c variables cpp

Итак, у меня есть:

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". Повторное добавление решает проблему. И так далее.

Какой путь, пожалуйста? Есть какая-то логика?

, 👍-1

Обсуждение

Почему минус, пожалуйста?, @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


1 ответ


3

Если у вас есть пара файлов заголовок/реализация, общее правило таково: что реализация определяет все, что объявляет заголовок. Таким образом, вы сохраняете определение 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