C + +の警備員が動作していないように見える

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ソースへのリンク

3

2 答え

問題は、警備員を含むものの誤解です。インクルードガードは、コンパイラが同じコンテンツを同じ翻訳ユニット(同じ.cppファイル用)でもう一度見ることを防ぎます。彼らは 別々の翻訳単位が同じコードを見るのを妨げません。

ヘッダーファイルでは、変数を宣言するだけでなく定義します。したがって、ヘッダーを含むすべての翻訳単位は、それらの変数の独自のコピーを作成します。

これを行う正しい方法は、.cppファイル内の変数を定義し、ヘッダーにのみ宣言することです(インクルードガードは、同じ翻訳単位での複数のインクルードを防ぐために必要です)。

つまり、ファイルsample.hに、変数に extern を接頭辞として付け、初期化子を削除して(定義されていない、定義されていないように)、対応する.cppファイルで定義します関数も定義されています)、ヘッダーの正確な定義をそこに置きます。

関連のないノートでは、インクルードガードの中に #include "mbed.h" を入れる必要があります。これは、あるコンパイラがそのようなガードのコンパイル速度を最適化し、インクルードガードの外側には材料があります。これは本当に正しさの問題ではないことに注意してください(mbed.hはインクルードガードによっても適切に保護されていると仮定します)。しかしコンパイル時の問題です。

12
追加された

宣言は、次のように「 extern 」としてマークする必要があります。

extern DigitalOut led1;

次に、ヘッダにある式を使用して、sample.cppでそれらを定義します(つまり、そのためのストレージを割り当てます)。

4
追加された