50

システムでは、特定のプリミティブをメモリ内の特定のポイントに揃えることが要求されます (int から 4 の倍数のバイト、short から 2 の倍数のバイトなど)。もちろん、これらを最適化して、パディングで無駄なスペースを最小限に抑えることができます。

私の質問は、GCC がこれを自動的に行わないのはなぜですか? より明白なヒューリスティック (最大サイズ要件から最小サイズへの順序変数) が何らかの形で欠けていますか? 一部のコードは、その構造体の物理的な順序に依存していますか (それは良い考えですか)?

GCCは多くの点で非常に最適化されていますが、これはそうではありません.

4

7 に答える 7

79

C 標準に違反するため、gcc は構造体の要素を並べ替えません。C99 標準のセクション 6.7.2.1 には、次のように記載されています。

構造体オブジェクト内では、ビットフィールド以外のメンバーとビットフィールドが存在するユニットのアドレスは、宣言された順序で増加します。

于 2008-09-22T23:13:43.637 に答える
28

構造体は、バイナリ ファイル形式とネットワーク プロトコルのパッキング順序の表現としてよく使用されます。それが行われた場合、これは壊れます。さらに、コンパイラが異なれば最適化も異なるため、両方のコードをリンクすることは不可能です。これは単に実現不可能です。

于 2008-09-22T22:48:40.950 に答える
11

GCC は、ソース コードからマシン コードを生成する点で、私たちのほとんどよりも賢いです。ただし、ファイルに書き込むことができるデータであるため、構造体を再配置するのが私たちよりも賢明だったとしたら、私は震えます。4 文字で始まり、4 バイトの整数を持つ構造体は、GCC が構造体メンバーを再配置する必要があると判断した別のシステムで読み取った場合、役に立たなくなります。

于 2008-09-22T22:56:53.990 に答える
7

gcc SVN には構造再編成の最適化 (-fipa-struct-reorg) がありますが、プログラム全体の分析が必要であり、現時点ではあまり強力ではありません。

于 2008-10-31T19:11:25.470 に答える
2

あなたが言及したようなアラインメントの問題のため、Cコンパイラは構造体を正確に自動的にパックしません。ワード境界 (ほとんどの CPU では 32 ビット) にないアクセスは、x86 では大きなペナルティをもたらし、RISC アーキテクチャでは致命的なトラップを引き起こします。

于 2008-09-22T22:50:58.543 に答える
2

それが良い考えだとは言いませんが、構造体のメンバーの順序に依存するコードを書くことは確かにできます。たとえば、ハックとして、アクセスしたい内部の特定のフィールドの型としてポインターを構造体にキャストし、ポインター演算を使用してそこに到達することがよくあります。私にとってこれは非常に危険な考えですが、特に C++ で、プライベートとして宣言された変数が、サードパーティのライブラリのクラスにあり、パブリックにカプセル化されていない場合に、パブリックにアクセスできるようにするために使用されているのを見てきました。メンバーを並べ替えると、それが完全に壊れます。

于 2009-02-18T19:18:47.507 に答える
1

最新の gcc トランク、または活発に開発中の struct-reorg-branch を試してみてください。

https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=view&target=Olga+Golovanevsky_+Memory+Layout+Optimizations+of+Structures+and+Objects.pdf

于 2015-09-12T04:25:10.627 に答える