C ++ включают охрану, кажется, не работает - PullRequest
3 голосов
/ 13 ноября 2011

Я получаю сообщения об ошибках от компилятора mbed C ++, которые, по-видимому, свидетельствуют о неисправности включенных защитных устройств.

В main.cpp я включаю свой заголовочный файл следующим образом:

#include "mbed.h"
#include "sample.h"

Это мой sample.h:

#include "mbed.h"

#ifndef STUFF_H
#define STUFF_H

/* LEDs */
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

/* Subroutines */
void sweepLEDs();
void pulseLEDs(int numPulses);
void clearLEDs();

#endif

В sample.cpp я включаю sample.h следующим образом:

#include "sample.h"

В файлах main.cpp и sample.cpp,Я имею в виду переменные led1, led2, led3, led4 без объявления их.Однако компилятор выводит эти жалобы:

"Символ led1 многократно определен (для sample.cpp.cpp.LPC1768.o и main.cpp.cpp.LPC1768.o)."... "Символ led4 определен многократно (для sample.cpp.cpp.LPC1768.o и main.cpp.cpp.LPC1768.o)."

Неправильно ли написаны мои защитные щитки?Или есть какая-то другая проблема?

(Для справки, вот ссылка на источник mbed.h )

Ответы [ 2 ]

12 голосов
/ 13 ноября 2011

Проблема заключается в неправильном понимании того, что делают охранники.Включающие охранники не позволяют компилятору снова видеть тот же контент в том же модуле перевода (для того же файла .cpp).Они не не позволяют отдельным блокам перевода видеть один и тот же код.

В вашем заголовочном файле вы определяете (не просто объявляете) переменные.Поэтому каждая единица перевода, которая включает в себя заголовок, создает свою собственную копию этих переменных.

Правильный способ сделать это - определить переменные в файле .cpp и объявить их только в заголовке (защитники включения должныв любом случае, чтобы предотвратить многократное включение в одну и ту же единицу перевода).

То есть в вашем файле sample.h добавьте к переменным префикс extern и удалите инициализатор (поэтому они только объявлены,определены), и определите их в соответствующем файле .cpp (в котором также определены функции), поместив туда точные определения из вашего заголовка.

В несвязанной заметке вы должны поместить #include "mbed.h" в sample.h внутри включаемых защит, потому что некоторые компиляторы оптимизируют скорость компиляции для таких защит, и эта оптимизация не работает, если есть материал вне защитных включений.Обратите внимание, что это на самом деле не проблема правильности (при условии, что mbed.h также должным образом защищен включаемыми защитниками), а проблема производительности компиляции.

4 голосов
/ 13 ноября 2011

Вы должны пометить объявления как " extern ", например:

extern DigitalOut led1;

Затем определите их (т.е. выделите для них хранилище) в sample.cpp, используя выражение, которое вы использовали в заголовке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...