0

データ構造のアライメント用のマクロを作成するために、 を#pragma pack介してディレクティブを実装しようとしています。これはすべて、本「C:一言で言えば」_Pragma оperatorの本に記載されています

#define  STR(s)  #s
#define  ALIGNMENT(n) _Pragma( STR (pack(n)) )
#define  ALIGNLEVEL(l) ALIGNMENT(l)
int  main()
{
   ....
    if(1)
    {
        ALIGNLEVEL(1)
        printf("%s\n", STR(Byte-aligned: no padding));>
    }
    else
    {
        ALIGNLEVEL(4)
        printf("%s\n", STR(four-byte: boundaries));

    }
    typedef struct s
    {
        size_t l_num;
        short  h_num;
        char ch;
    } s;

私が期待する結果は、構造体のサイズが7 バイト(バイト整列) またはx64 ビット プラットフォームで11 バイトになることです。上記のコードはオプション付きのGCC 4.7.xでコンパイルされ、戻り値は8 バイト(32 ビット OS) です。-Werror

このマクロの何が問題になる可能性がありますか?
なぜこうなった?

4

1 に答える 1

2

プログラムは、ifステートメントのテストの評価結果によってプラグマが影響を受けるという前提で作成されています。これは当てはまりません: 2 番目のプラグマは最初のプラグマをオーバーライドするだけで、構造体のパッキング アラインメントは無条件に 4 に設定されますALIGNLEVEL。 -64)。

if本質的にコンパイル時のプラグマを見るときなど、コンパイラが実行時の構造を無視することは理にかなっています。定数テストがあってもif、非定数に簡単に変更でき、コンパイラは一貫した結果を提供できません。異なる状況で異なる配置が必要な場合は、プリプロセッサを使用する必要があります。

#if SOME_CONDITION
    ALIGNLEVEL(1)
    printf("%s\n", STR(Byte-alligned: no padding));>
#else
    ALIGNLEVEL(4)
    printf("%s\n", STR(four-byte: boundaries));
#endif

ランタイム条件に基づいて異なるアライメントを使用する必要がある場合は、両方の構造を定義し、適切に選択された抽象化に基づいて、どちらかを使用するコードを切り替える必要があります。

于 2013-07-12T18:31:04.030 に答える