13

ヘッダーが依存するマクロ(特に、など)を定義する場合、それら_FILE_OFFSET_BITSを配置するのに最適な場所はどこですか?FUSE_USE_VERSION_GNU_SOURCE

私が考えたいくつかの可能性は次のとおりです

  1. そのファイルに含まれるヘッダーによって公開される定義に依存するソースファイルの上部
  2. 関連するヘッダーのインクルードの直前
  3. CPPFLAGSコンパイラを介してレベルで定義しますか?(など-D_FILE_OFFSET_BITS=64):
    1. ソースリポジトリ全体
    2. プロジェクト全体
    3. それを必要とするソースだけ
  4. プロジェクトヘッダー。マクロが適用される関連ヘッダーも含める必要があります。
  5. 私が考えていなかった他の場所ですが、無限に優れています

注:make、autotools、およびその他のビルドシステムへの適用性による正当化は、私の決定の要因です。

4

8 に答える 8

3

まあ、それは異なります。

ほとんどの場合、コマンドラインを介して定義します-Makefileまたは使用するビルドシステムで。

私は実際に_FILE_OFFSET_BITSはそれを明示的に定義するのではなく、とを使用getconf LFS_CFLAGSgetconf LFS_LDFLAGSます。

于 2010-08-10T13:53:36.010 に答える
3

マクロがシステムヘッダーに影響を与える場合、それらはおそらく、それらのシステムヘッダーを含むすべてのソースファイル(間接的にそれらを含むものを含む)に影響を与える場所に移動する必要があります。したがって、ビルドシステムでCPPFLAGSなどを設定してすべてのファイルのコンパイルに影響を与えることができると仮定すると、最も論理的な場所はコマンドラインになります。

プリコンパイル済みヘッダーを使用していて、すべてのソースファイル(MSVCプロジェクトの場合はstdafx.hなど)に最初に含める必要があるプリコンパイル済みヘッダーがある場合は、それらもそこに配置できます。

自己完結型のライブラリに影響を与えるマクロ(サードパーティまたはユーザーが作成したもの)の場合、マクロを定義してライブラリヘッダーを含めるラッパーヘッダーを作成します。プロジェクトでライブラリを使用する場合はすべて、ライブラリヘッダーを直接含めるのではなく、ラッパーヘッダーを含める必要があります。これにより、マクロを不必要に定義することを回避し、マクロがそのライブラリに関連していることを明確にします。ライブラリ間に依存関係がある場合は、安全のためにマクロをグローバル(ビルドシステムまたはプリコンパイル済みヘッダー内)にすることをお勧めします。

于 2010-08-11T08:18:01.280 に答える
1

CPPFLAGSプロジェクト全体を通して、私は常にそれらをコマンドラインに配置していました。それらを他の場所に置くと、それらを定義するプロジェクトヘッダーを含める前に、新しいソースファイルにコピーするのを忘れたり、システムヘッダーを含めたりする危険があります。これにより、非常に厄介なバグが発生する可能性があります(1つのファイルが宣言するなど)。従来の32ビットstruct statであり、そのアドレスを64ビットを期待する別のファイルの関数に渡しますstruct stat)。

_FILE_OFFSET_BITS=64ところで、それがまだglibcのデフォルトではないのは本当にばかげています。

于 2010-08-02T05:50:36.500 に答える
1

私が見たほとんどのプロジェクトは、-Dコマンドラインオプションを介してそれらを使用していました。これは、さまざまなコンパイラとシステムヘッダーを使用してソースを簡単に構築できるためです。それらを必要としない、またはそれらの別のセットを必要とする別のシステム用のシステムコンパイラを使用してビルドする場合、configureスクリプトは、makeファイルがコンパイラに渡すコマンドライン引数を簡単に変更できます。

フラグのいくつかは、関数のどのバージョンが取り込まれるか、または構造体のサイズ/レイアウトに影響を与え、それらを混同すると、注意しないとおかしなことが起こる可能性があるため、プログラム全体で行うのがおそらく最善です。

彼らは確かに追いつくのが面倒です。

于 2010-08-10T13:48:13.367 に答える
1

特にautotoolsの場合_GNU_SOURCEは、次を使用できますAC_USE_SYSTEM_EXTENSIONS(autoconfのマニュアルから自由に引用してください)。

--マクロ:AC_USE_SYSTEM_EXTENSIONS
このマクロはAutoconf2.60で導入されました。可能であれば、通常は標準に準拠した名前空間の問題が原因で、通常は拡張機能を無効にするホストでCまたはPosixへの拡張機能を有効にします。これは、Cコンパイラを実行するマクロの前に呼び出す必要があります。必要に応じて、次のプリプロセッサマクロが定義されています。

_GNU_SOURCE GNU/Linuxで拡張機能を有効にします。

__EXTENSIONS__ Solarisで一般的な拡張機能を有効にします。

_POSIX_PTHREAD_SEMANTICS Solarisでスレッド拡張機能を有効にします。

_TANDEM_SOURCE HPNonStopプラットフォームの拡張機能を有効にします。

_ALL_SOURCE AIX3およびInterixの拡張機能を有効にします。

_POSIX_SOURCE MinixのPosix機能を有効にします。

_POSIX_1_SOURCE Minixの追加のPosix機能を有効にします。

_MINIX Minixプラットフォームを特定します。この特定のプリプロセッサマクロは廃止されており、Autoconfの将来のリリースで削除される可能性があります。

について_FILE_OFFSET_BITSは、を呼び出す必要がありAC_SYS_LARGEFILEますAC_FUNC_FSEEKO

- 大きい:AC_SYS_LARGEFILE

ラージファイルサポートと呼ばれる64ビットファイルオフセットを調整します。一部のホストでは、大きなファイルにアクセスできるプログラムを作成するために、特別なコンパイラオプションを使用する必要があります。そのようなオプションを出力変数に追加しますCC。定義_FILE_OFFSET_BITS_LARGE_FILES、必要に応じて。

オプションを使用して構成すると、ラージファイルサポートを無効にでき--disable-largefileます。

このマクロを使用する場合は、ラージファイルサポートが有効になっている場合に一般的であるため、幅が。off_tよりも広い場合でもプログラムが機能することを確認してください。long intたとえば、。を使用して任意のoff_tXを出力することは正しくありませんprintf("%ld", (long int) X)

LFSは、Cの対応物を置き換えるために、およびを使用しない関数を導入fseekoしました。プロトタイプを使用し、ラージファイルサポートが有効になっている場合は、プロトタイプを使用できるように注意してください。ftellofseekftelloff_tAC_FUNC_FSEEKO

autoheaderを生成するために使用している場合は、使用するconfig.hことに関心のある他のマクロを定義できます。AC_DEFINEAC_DEFINE_UNQUOTED

AC_DEFINE([FUSE_VERSION], [28], [FUSE Version.])

自動ヘッダーを使用している場合、定義はコマンドラインに渡されるか、に配置されconfig.hます。の本当の利点はAC_DEFINE、構成チェックの結果としてプリプロセッサ定義を簡単に許可し、システム固有の問題を重要な詳細から分離できることです。

.cファイルを書き込むときは、#include "config.h"最初にインターフェイスヘッダー(たとえば、foo.h-foo.cこれにより、ヘッダーに依存関係が欠落していないことが保証されます)、次に他のすべてのヘッダーが続きます。

于 2010-08-24T10:02:15.237 に答える
0

私は通常、それらを誤って設定しないようにしながら、それらを必要とするものにできるだけ近づけて配置します。

関連する情報は、識別しやすいように近くに保管する必要があります。古典的な例は、Cが関数の先頭だけでなく、コード内の任意の場所で変数定義を許可できるようにする機能です。

void something (void) {
    // 600 lines of code here
    int x = fn(y);
    // more code here
}

よりもはるかに優れています:

void something (void) {
    int x;
    // 600 lines of code here
    x = fn(y);
    // more code here
}

x後者の場合、タイプを検索する必要がないためです。


例として、単一のソースファイルを異なる値で複数回コンパイルする必要がある場合、コンパイラを使用してコンパイルする必要があります。

gcc -Dmydefine=7 -o binary7 source.c
gcc -Dmydefine=9 -o binary9 source.c

ただし、そのファイルのすべてのコンパイルで7を使用する場合は、使用する場所に近づけることができます。

source.c:
    #include <stdio.h>

    #define mydefine 7
    #include "header_that_uses_mydefine.h"

    #define mydefine 7
    #include "another_header_that_uses_mydefine.h"

よりローカライズされるように、2回実行したことに注意してください。これは問題ではありません。1つだけ変更すると、コンパイラがそのことを通知しますが、特定のヘッダーにそれらの定義が設定されていることを確認できます。


また、最初に8に設定しないと、(たとえば)インクルードしないことが確実な場合は、次のことだけを含むファイルを作成することもできます。bitio.hBITCOUNTbitio8.h

#define BITCOUNT 8
#include "bitio.h"

次にbitio8.h、ソースファイルに含めるだけです。

于 2010-08-11T04:24:40.637 に答える
0

ヘッダーファイルを使用することをお勧めします。これにより、makeファイルやその他のビルドシステム、およびVisualStudioなどのIDEプロジェクトによってコードベースをビルドできるようになります。これにより、コメントを付けることができる単一の定義ポイントが得られます(私は、マクロドキュメントを生成できるdoxygenのファンです)。

ヘッダーファイルのもう1つの利点は、マクロの有効な組み合わせのみが定義されていることを確認する単体テストを簡単に記述できることです。

于 2010-08-11T04:35:37.597 に答える
0

ターゲット固有のグローバルなプロジェクト全体の定数は、makefileのCCFLAGSに配置するのが最適です。あらゆる場所で使用する定数は、それらを使用するすべてのファイルに含まれている適切なヘッダーファイルに含めることができます。

例えば、

// bool.h - a boolean type for C
#ifndef __BOOL_H__
#define BOOL_H
typedef int bool_t
#define TRUE 1
#define FALSE 0
#endif

次に、他のヘッダーで、


`#include "bool.h"`
// blah
于 2010-08-11T19:45:26.840 に答える