0

pragmaなど、構造体/クラスのレイアウトを制御するためのさまざまな がありますpragma pack。しかし、私の知る限り、pragma「レイアウトは気にしない。内部的なもので、コードはそれに依存していない。最適なパフォーマンス/サイズになるように並べ替えてください」と言うわけにはいきません。私の知る限り、それは典型的なケースであり、多くの場合、パフォーマンス/サイズを改善できます。また、プログラマーがパフォーマンスやサイズのために並べ替えるのに十分注意していたとしても、ターゲット アーキテクチャが異なれば最適なレイアウトも異なる可能性があります。

編集:明確にするために、私はメンバーの順序について話しています。パディングはすでに制御可能です。

また、PVS-Studio には関連するメッセージがあります。それが私が話していることです-なぜこれをコンパイラーで行うことができないのpragmaですか?

4

2 に答える 2

1

このようなプラグマは言語標準で許可されていますが、そのようなものを実装するコンパイラは知りません。

C では、 の動作は標準#pragmaのセクション 6.10.6 で指定されています(リンクは最新のドラフトへのリンクです)。


# pragma pp-tokens opt new-line形式の前処理ディレクティブで
、前処理トークンSTDCがディレクティブの直後pragma(マクロ置換の前) に続くと、実装は実装定義の方法で動作します。この動作により、変換が失敗したり、トランスレータまたは結果のプログラムが準拠していない方法で動作したりする可能性があります。実装によって認識されないプラグマは無視されます。

したがって、事実上、言語の規則に違反する#pragma 可能性があります。

この場合に関連するルールは、構造体メンバーが宣言された順序で配置されることです。6.7.2.1 パラグラフ 15:

構造体オブジェクト内で、非ビット フィールド メンバーとビット フィールドが存在するユニットには、宣言された順序で増加するアドレスがあります。適切に変換された構造体オブジェクトへのポインターは、その最初のメンバー (または、そのメンバーがビットフィールドの場合は、それが存在するユニット) を指し、その逆も同様です。構造体オブジェクト内に名前のないパディングがある場合がありますが、先頭にはありません。

悪いニュース: C 標準では、宣言された順序で構造体メンバーを配置する必要があります。最初のメンバーはオフセット 0 にある必要があります。メンバー間または最後のメンバーの後に任意のパディングがあってもかまいませんが、順序を変更することはできません。

朗報: この言語#pragmaでは、上記の規則に違反するレイアウトを指定する を定義する実装が許可されています。

悪いニュース: 私の知る限り、実際にそうする実装はありません。ある場合でも、そうでない他の実装があるため、そのような を使用するコードは#pragma移植性がありません。(ただし、少なくとも の名前#pragmaが一意である場合、それを認識しないコンパイラはそれを無視する必要があるため、コードは引き続きコンパイルされます。)

これは C の場合です。C++ の規則#pragmaは C の規則と非常によく似ています。構造体のレイアウトに関する C++ の規則も C の規則に似ていると確信しています。継承は物事をもう少し複雑にします。

于 2014-10-16T18:04:53.953 に答える