2009-09-04 14 views
7

コンパイル時に構造体のメンバのオフセットを見つける方法はありますか?構造体メンバのオフセットを含む定数を作成します。次のコードではoffsetof()マクロは最初のprintfステートメントで機能します。しかし、を宣言するためのライン10での使用には、エラーが発生します。コンパイル時のオフセット

"Cannot resolve '->' operator as a constant expression".

はそれを行うための他の方法はありますか?

struct MyStruct 
{ 
    unsigned long lw; 
    unsigned char c[5]; 
    int i; 
    int j; 
    unsigned long last; 
}; 

const int ofs = offsetof(struct MyStruct, i); // This line in error 

int main(void) 
{ 
    printf("Offset of c = %d.\n", offsetof(struct MyStruct, c)); 
    printf("Offset of i = %d.\n", ofs); 
    return 0; 
} 

答えて

4

正しい#includesを追加した後、g ++ 4で警告なしでコンパイルされます。

stddef.hを#includeしていますか? offsetof()はマクロであり、Cのビルトインキーワードではありません。

これで問題が解決しない場合は、定数を静的にしてモジュールに限定してみてください。それはコンパイラを幸せにするかもしれません。

9

offsetof()マクロは、コンパイル時にはです。それを定義する標準に準拠した方法はありませんが、すべてのコンパイラには何らかの方法が必要です。

一つの例は次のようになります。

#define offsetof(type, member) ((size_t) &(((type *) 0)->member)) 

技術的にを構築し、すべてのコンパイラは、少なくとも1つの、このような表現を持っている必要があります(ユーザー「litb」でコメントを参照)、コンパイル時ではないがコンパイル時に解決することができます。これは、正確にはoffsetof()が<stddef.h>に定義されています。

あなたのコードにおそらく他のエラーがあります - <stddef.h>などのインクルードがないか、またはあなたのコンパイラを苛立たせることがあります。

+0

もちろん、「コンパイル時」という意味ではありません。ライブラリ関数を使用しないコンストラクトを表示しますが、コンパイル時の値に評価されるわけではありません。実際にコードが発行されるかどうかは、もちろん無関係です.Cドラフトは、 "算術定数式は算術型でなければならず、整数定数、浮動定数、列挙定数、文字定数、および式のsizeというオペランドしか持たないものとします。ミックスにはポインタは使用できません。 –

+0

'offsetof'はコンパイル時の構造体であり、整数の定数式に評価されますが、実装例ではそうではありません。 –

+0

offsetof()を整数定数式と評価するものとして定義するには、言語に* NO *ウェイがあります。ポインタを使わずに定義する* NO *方法があります。あなたが何をしているにしても、あなたは常に組み込みのコンパイラや式を適切に最適化するコンパイラの能力に頼るでしょう。 offsetofのWikipedia、またはオープンソースのCライブラリをチェックしてください。だから、あなたは整数定数式の定義について技術的に正しいのですが(そして私の言い回しにも適応します)、私の実装例で指し示すのは間違っています。 – DevSolar

3

あなたは#include <stddef.h>を持っている場合、私は(あなたがなしで引用するエラーメッセージは意味がない)と仮定して、それはあなたのコンパイラのバグです。 offsetof resultは、C99とC90の整数定数式です。

関連する問題