5

下記のようなタイムエラーチェックをコンパイルしたいです。しかし、内部で使用する方法を見つけることができませんmain()か?

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
int main(){
BUILD_BUG_ON_NULL(12);
}

以下は言及されたエラーです

1--error C2332: 'struct' : missing tag name
2--error C2143: syntax error : missing ')' before '{'
3--error C2027: use of undefined type 'main::<unnamed-tag>'
4--error C2143: syntax error : missing ';' before '{'
5--error C2059: syntax error : ')'

誰かが私が間違っていることを教えてもらえますか?

4

3 に答える 3

5

最初にマクロを実行し、引数が。と異なる場合はコンパイルエラーをトリガーしBUILD_BUG_ON_ZEROます。BUILD_BUG_ON_NULL 0

マクロ引数がの場合、0コンパイルエラーはトリガーされませんが、0forBUILD_BUG_ON_ZERO(void *) 0forが生成されます。BUILD_BUG_ON_NULL

これらのマクロは、Cで記述されたLinuxカーネルに由来し、Cプログラムでのみ機能します。

C ++では、これらのマクロは機能しません。その理由は、C ++では、式で構造体を宣言できないためですsizeof

プログラムをCでコンパイルするのかC++でコンパイルするのかについては質問に記載されていませんが、C++でコンパイルしているのではないかと強く思います。したがって、これらのマクロをC++で使用しないでください。

于 2012-12-30T03:39:59.017 に答える
5

編集: 質問はもともと C++ としてタグ付けされていましたが、現在は C としてタグ付けされています。

質問のこれ以上の根本的な変更を追跡するつもりはありません。

C++ のタグ付けされた質問に対する元の回答:


このソースコード:

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
int main(){
BUILD_BUG_ON_NULL(0);
}

g++ 4.7.1 でコンパイル、生成

foo.cpp: 関数 'int main()' 内:
foo.cpp:4:1: エラー: 型は 'sizeof' 式で定義されていない可能性があります
foo.cpp:4:21: 警告: ステートメントは効果がありません [-Wunused-value]

これは何が悪いのかを直接言います。

したがって、異なるコンパイラでコンパイルすることをお勧めします。


コンパイル時のアサーションを探している可能性があります。

static_assertC++11 では、たとえば次のようなマクロを介してを使用できます。

#define STATIC_ASSERT( e ) static_assert( e, #e )

C++03 では、同じ翻訳単位で a を繰り返すことができ、クラス定義で使用できるtypedefため、有効/無効として実装できます。typedef

#define STATIC_ASSERT( e ) typedef char staticAssert_shouldBeTrue[e? 1 : -1]

これに伴う 1 つの問題は、g++ にコンパイラのバグがあった/あることでした。繰り返しtypedefが常に受け入れられるとは限らず、ローカルで一意の名前をそれぞれに生成する必要がありました__LINE__

ただし、Boost ライブラリの定義をそのまま使用することもできます。Boost は、必要に応じてそれぞれの特殊なケースを使用して現存するほとんどのコンパイラをサポートしているためです。

于 2012-12-30T03:11:48.710 に答える
2

でコンパイルするとgcc -std=c99 -pedantic-errors

screwed.c: In function ‘main’:
screwed.c:5:1: error: negative width in bit-field ‘&lt;anonymous>’
screwed.c:5:1: error: struct has no named members [-pedantic]

これらは、コードが C としてコンパイルされたときにコンパイルで発生するエラーです。ビットフィールドの幅は非負 (名前がある場合は正) であるstruct必要があり、少なくとも 1 つの名前付きメンバー (2 つ、2 つ、最後のものが柔軟な配列メンバーの場合)。structタグなしの s は許可されます。

コードを C 以外でコンパイルしたか、コンパイラが準拠していません。

C++ としてコンパイルすると、追加のエラー

error: types may not be defined in ‘sizeof’ expressions

が生成されます (ただし、struct名前のないメンバーに関するものは消えます)。

C++ では、式で型を定義することはできずsizeof、コンパイラはあまり明確ではない方法を選択しました。

于 2012-12-30T03:15:19.563 に答える