20

非常に長いインクルード パスが必要であるにもかかわらず、コードが 1 行あたり 80 文字に準拠できるように、#include ディレクティブを 2 行に分割する方法があればいいのにと思います。

コンパイラの検索パスを拡張する以外に、どうすればこれを管理できますか? 非常に長いパス文字列を 2 行に分割する方法はありますか?

「#define」マクロの展開は明らかに #include 展開の後に行われるため、これらは機能しません。

#define BIGPATH "..."
#include BIGPATH ## "/foo.c"
#include "BIGPATH/foo.c"
#include BIGPATH"/foo.c"

私も試してみました

#include "foo" ##
         "bar"

#include "foo" \
         "bar"

無駄に。おそらく私が望んでいることは不可能ですか?助けて、スタックオーバーフロー・ケノービ、あなたが私の唯一の希望です。

回答:以下の提案された回答に基づいて構築すると、実際に私にとってうまくいったのは次のとおりです。

#define STRINGIFY(x) #x
#define PATH(path) STRINGIFY(/my/very/long/path)
#include PATH(foo.h)
#undef PATH
#undef STRINGIFY
4

5 に答える 5

12

私はこれの考えが好きではありません、私はこの可能性に言及したかっただけです。ダニエル・フィッシャーが述べたように行くのが最善です。このソリューションは少し風変わりで、すべての状況で機能するわけではありませんが、これはここにコンパイルされています:

#define PATH(FILE) </path/to/FILE>
#include PATH(file.h)

そして、明らかな制限のいくつかを挙げれば、次のようになります。

  • これらのインクルードの検索パスは「ローカル」ではありません
  • FILEには「、」を含めることはできません(かなり珍しい)
  • PATH定義は80文字を超えることができます

このリストに自由に追加してください。

編集
読みやすくするために、以下のJonathansコメントからの解決策を私の例のスタイルで投稿します。

#define STRINGIFY(x) #x 
#define PATH(FILE) STRINGIFY(/path/to/FILE) 
#include PATH(foo.h)

#include <>このバージョンは、次のようにマップされるため、バージョンの「ローカリティの問題」を軽減します。#include ""

于 2012-10-04T19:20:47.563 に答える
9

これは私のためにコンパイルされます(Boost.PPの動作を思い出す方法に基づいています):

#define a() <vec\
tor>

#include a()

int main() {
  std::vector<int> x;
}

完全なパスに変更<vector>するだけです-必要な方法で文字列を連結できないと思います#include.

于 2012-10-04T19:15:46.920 に答える
4

短い名前の別のヘッダー ファイルを使用して、長い名前のヘッダー ファイルを保存します。したがって、最小 80 文字を超えるすべてのヘッダーは、適切にフォーマットされたコードには含まれません。

//short_name.h
#include "really_really_long_include_name.h"

//code
#include "short_name.h"
于 2012-10-04T19:19:12.277 に答える
4

すべての前処理ディレクティブは、改行トークンで終了します。include ディレクティブは、次のいずれかの形式です。

# include < h-char-sequence> new-line
# include " q-char-sequence" new-line
# include pp-tokens new-line

#include "foo" "bar"エスケープされた改行の削除はディレクティブの実行前に発生しますが、文字列の連結はその後に発生するため、最後の例は実行されるのと同等になります。これは、include ディレクティブの最終的な有効な形式と一致します。

ただし、この形式では、後続のマクロ名includeがすべて置き換えられます。あなたのものにはマクロがありません。結果のディレクティブが通常の 2 つの形式のいずれとも一致しない場合、動作は未定義です。

すべての置換後のディレクティブが前の 2 つの形式のいずれとも一致しない場合、動作は未定義です。

標準には、複数の文字列リテラルがある場合についての特定の注意事項があります。

隣接する文字列リテラルは単一の文字列リテラルに連結されないことに注意してください (2.2 の翻訳フェーズを参照)。したがって、2 つの文字列リテラルになる展開は無効なディレクティブです。

そのため、その例は機能しません。ただし、有効なファイル名を生成するためにマクロ展開に依存できることを意味します。例えば:

#define LONG_PATH(file) <foo/bar/baz/file>
#include LONG_PATH(file.h)

または:

#define STRINGIZE(x) #x
#define LONG_PATH(file) STRINGIZE(foo/bar/baz/file)
#include LONG_PATH(file.h)
于 2012-10-04T19:31:56.037 に答える
3

いいえ、できません。プリプロセッサでは、インクルード ファイル名が単一の前処理トークンである必要があります。使用しているインクルード検索パスを修正するか、1 行あたり 80 文字という要件を緩和する必要があります。

于 2012-10-04T19:11:53.617 に答える