none
C99の質問で恐縮ですが RRS feed

  • 質問

  • 構造体には、パディングが発生することがあると、昔から思っていたのですが、最近の規格では、

    charに関しては、例外的にパディングなしになったと聞きました。本当でしょうか?

    C#固有の話でなくて申し訳ないのですが、よろしくご教授ください。

    また、C#の場合にはどのようになっているのでしょうか?

    2011年3月5日 20:38

回答

  • C#のパディングは標準で8バイトですが、
    StructLayoutAttribute拡張属性で変更できます。
    メンバーのデータサイズがパディングサイズに満たない場合は、
    データサイズ長のn倍境界に配置されます。
    つまり1バイトのbyte型の場合は常につめて配置されます。
    2バイトのchar型の場合はパディングが2以上ならワード境界に、
    パディングが1ならばつめて配置されます。
    C99は分かりませんが、VC++はC#と同じルールに従っていると思われます。
    そのおかげでP/Invokeで構造体が扱えます。
    • 回答としてマーク Tolbie 2011年3月6日 12:04
    2011年3月6日 0:43
  • C99は分かりませんが、VC++はC#と同じルールに従っていると思われます。

    C# は構造体の属性だけ見ていれば何とかなる面がありますが、Visual C++ はそうもいきません。
    コンパイル時のオプション(/Zp)で指定できるし、#pragma pack ディレクティブでどこででも変えられますので、「同じルール」と言ってしまうのには違和感がありました。

    http://msdn.microsoft.com/ja-jp/library/xh3e3fd0.aspx
    http://msdn.microsoft.com/ja-jp/library/2e70t5y1.aspx

    なお、C99 で特別なルールがあるかどうかは、私は存じません。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク Tolbie 2011年3月6日 12:04
    2011年3月6日 5:41
    モデレータ

すべての返信

  • C#のパディングは標準で8バイトですが、
    StructLayoutAttribute拡張属性で変更できます。
    メンバーのデータサイズがパディングサイズに満たない場合は、
    データサイズ長のn倍境界に配置されます。
    つまり1バイトのbyte型の場合は常につめて配置されます。
    2バイトのchar型の場合はパディングが2以上ならワード境界に、
    パディングが1ならばつめて配置されます。
    C99は分かりませんが、VC++はC#と同じルールに従っていると思われます。
    そのおかげでP/Invokeで構造体が扱えます。
    • 回答としてマーク Tolbie 2011年3月6日 12:04
    2011年3月6日 0:43
  • C99は分かりませんが、VC++はC#と同じルールに従っていると思われます。

    C# は構造体の属性だけ見ていれば何とかなる面がありますが、Visual C++ はそうもいきません。
    コンパイル時のオプション(/Zp)で指定できるし、#pragma pack ディレクティブでどこででも変えられますので、「同じルール」と言ってしまうのには違和感がありました。

    http://msdn.microsoft.com/ja-jp/library/xh3e3fd0.aspx
    http://msdn.microsoft.com/ja-jp/library/2e70t5y1.aspx

    なお、C99 で特別なルールがあるかどうかは、私は存じません。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク Tolbie 2011年3月6日 12:04
    2011年3月6日 5:41
    モデレータ
  • ありがとうございます。

    C#の場合は、拡張属性なのですね。前に質問したときに覚えた、C#の構造体の特殊な制約のせいで、私自身は、あまり構造体を使うことは無いのですが、ちょっと気になったものですから。

    でも実際には、C99完全準拠の処理系はまだ、殆どないそうなので、あまり気にすることはないのかも知れませんね。

    2011年3月6日 12:01
  • 回答ありがとうございます。

    C++でもやはり、オプションで変更することができるのですね。

    実際、規格としてはどうなのか?というのが質問のキモでしたが、前の人の返信に書いたとおり、C99処理系がまだ殆ど無いらしいので、とりあえず気にしないことにします。

     

    2011年3月6日 12:04