web-dev-qa-db-ja.com

マクロがまだ定義されていない場合にのみマクロを定義するのはなぜですか?

Cコードベース全体で、すべてのマクロが次のように定義されていることがわかります。

#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS                   0.2f
#endif

#ifndef BEEPTRIM_ROLL_RATE_DEGPS
#define BEEPTRIM_ROLL_RATE_DEGPS                    0.2f
#endif

#ifndef FORCETRIMRELEASE_HOLD_TIME_MS
#define FORCETRIMRELEASE_HOLD_TIME_MS               1000.0f
#endif

#ifndef TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS       50.0f
#endif

マクロを定義するだけでなく、これらの定義チェックを行う理由は何ですか?

#define BEEPTRIM_PITCH_RATE_DEGPS                   0.2f
#define BEEPTRIM_ROLL_RATE_DEGPS                    0.2f
#define FORCETRIMRELEASE_HOLD_TIME_MS               1000.0f
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS       50.0f

このプラクティスがウェブ上のどこにも説明されているのを見つけることができません。

92
Trevor Hickey

これにより、コンパイル時にマクロをオーバーライドできます。

gcc -DMACRONAME=value

ヘッダーファイルの定義はデフォルトとして使用されます。

138
Barmar

コメントで述べたように、この状況を想像してください。

foo.h

#define FOO  4

defs.h

#ifndef FOO
#define FOO 6
#endif

#ifndef BAR
#define BAR 4
#endif

bar.c

#include "foo.h"
#include "defs.h"

#include <stdio.h>

int main(void)
{
    printf("%d%d", FOO, BAR);
    return 0;
}

44

ただし、条件付きifndefがない場合、結果はMACRO再定義のコンパイル警告であり、64

$ gcc -o bar bar.c
In file included from bar.c:2:0:
defs.h:1:0: warning: "FOO" redefined [enabled by default]
 #define FOO 6
 ^
In file included from bar.c:1:0:
foo.h:1:0: note: this is the location of the previous definition
 #define FOO 4
 ^
51
Enzo Ferber

コンテキストはわかりませんが、これを使用して、これらのマクロ定義で設定された値をオーバーライドする可用性をユーザーに提供できます。ユーザーがこれらのマクロのいずれかに異なる値を明示的に定義する場合、ここで使用される値の代わりにそれが使用されます。

たとえば、g ++では、コンパイル時に-Dフラグを使用して値をマクロに渡すことができます。

17

これは、ヘッダーファイルのユーザーが自分のコードまたはコンパイラの-Dフラグからの定義をオーバーライドできるようにするためです。

14
Arkadiy

Cプロジェクトは複数のソースファイルに存在します。単一のソースファイルで作業する場合、チェックは(実際には)意味がないように見えますが、大規模なCプロジェクトで作業する場合は、定数を定義する前に既存の定義をチェックすることをお勧めします。アイデアは簡単です。特定のソースファイルに定数が必要ですが、別のソースファイルで既に定義されている可能性があります。

7
George

ユーザーがコンパイルして作業できるデフォルトのプリセットをユーザーに提供するフレームワーク/ライブラリについて考えることができます。これらの定義はさまざまなファイルに分散されており、最終的なユーザーはその値を構成できるconfig.hファイルを含めることをお勧めします。ユーザーが何らかの定義を忘れた場合、システムはプリセットのために動作を継続できます。

2
LPs