要約すると、根本的な問題は、armcc
未定義のプリプロセッサ マクロがプリプロセッサ ディレクティブで使用されている場合に警告するオプションが C プリプロセッサ/コンパイラになく#if
、下流の開発者がコードを正しく動作させるためのヒントを必要としているという事実にあるようです。
コメントで述べたように、私の最初の本能は、プリプロセッサ マクロを使用して、どの色が選択されているかではなく、色が選択されているかどうかを示すことです。この場合、コード ブロックは次のようになります。
#if defined(CONFIG_COLOR_IS_RED)
/* Red case */
#elif defined(CONFIG_COLOR_IS_GREEN)
/* Green case */
#elif defined(CONFIG_COLOR_IS_BLUE)
/* Blue case */
#else
#error config.h is not included!
#endif
もちろん、下流の開発者はブロック全体を含める必要があります。(これは OP の問題のようです。ダウンストリーム担当者は、ブロックを忘れたり、編集を誤ったりする可能性があります。)
もう 1 つのオプションは、(ブロック レベルではなく) 式レベルで選択を行うことです。つまり、マクロを使用する
CONFIG_COLOR(red-expression, green-expression, blue-expression)
config.h
たとえば、次のように定義されています。
#if defined(CONFIG_COLOR_IS_RED)
#define CONFIG_COLOR(red, green, blue) (red)
#elif defined(CONFIG_COLOR_IS_GREEN)
#define CONFIG_COLOR(red, green, blue) (green)
#elif defined(CONFIG_COLOR_IS_BLUE)
#define CONFIG_COLOR(red, green, blue) (blue)
#else
#error Color not configured!
#endif
この場合、ヘッダー ファイルが含まれていない場合、コンパイラは、宣言されていない symbol についてコンパイル時に警告し、シンボルが定義されていないCONFIG_COLOR
ため、リンク時にリンクを拒否する必要があります。CONFIG_COLOR
この場合、ユーザーコードは非常に単純です。たとえば、
my_color_attribute = CONFIG_COLOR( my_red, my_green, my_blue );
my_red
、my_green
、およびの代わりに定数または式を使用しmy_blue
ます。ご覧のとおり、マクロは、選択された「色」に応じて、3 つの値から 1 つの値を選択します。
ブロックレベルのコードが必要な場合は、マクロを使用することをお勧めします
IF_RED
/* Red case */
ENDIF
IF_GREEN
/* Green case */
ENDIF
IF_BLUE
/* Blue case */
ENDIF
マクロは次のように定義されていconfig.h
ます
#if defined(COLOR_IS_RED)
#define IF_RED if (1) {
#define IF_GREEN if (0) {
#define IF_BLUE if (0) {
#elif defined(COLOR_IS_GREEN)
#define IF_RED if (0) {
#define IF_GREEN if (1) {
#define IF_BLUE if (0) {
#elif defined(COLOR_IS_BLUE)
#define IF_RED if (0) {
#define IF_GREEN if (0) {
#define IF_BLUE if (1) {
#else
#error Color not selected!
#endif
#define END_IF }
選択されていないコードケースの無効コード (到達することのないコード) を生成します。に必要なオプションがあるかどうかはわかりませんが、コンパイラはブランチを最適化できるはずarmcc
です。
ヘッダー ファイルが含まれていない場合config.h
、コンパイラはIF_RED
etc. シンボルを未定義としてチョークします。