web-dev-qa-db-ja.com

sizeof(int)が正しいのに、sizeof intが間違っているのはなぜですか?

sizeofは、任意のデータ型と式のサイズを計算するために使用される演算子であり、オペランドが式の場合、括弧は省略できます。

int main()
{
        int a;

        sizeof int;
        sizeof( int );
        sizeof a;
        sizeof( a );

        return 0;
}

sizeofの最初の使用法は間違っていますが、他の使用法は正しいです。

Gccを使用してコンパイルすると、次のエラーメッセージが表示されます。

main.c:5:9: error: expected expression before ‘int’

私の質問は、C標準がこの種の操作を許可しない理由です。ウィルsizeof intあいまいさを引き起こしますか?

96
Yishu Fang

以下はあいまいになる可能性があります。

_sizeof int * + 1
_

それは_(sizeof (int*)) + 1_または_(sizeof(int)) * (+1)_ですか?

明らかに、C言語はあいまいさを解決するためのルールを導入できたかもしれませんが、なぜそれが気にならなかったのか想像できます。現状の言語では、型指定子が式で「裸」に表示されることはないため、その2番目の_*_が型または算術演算子の一部であるかどうかを解決するための規則は必要ありません。

既存の文法は、sizeof (int *) + 1の潜在的なあいまいさをすでに解決しています。 _(sizeof(int*))+1_、notsizeof((int*)(+1))です。

C++には、関数スタイルのキャスト構文で解決するためのやや類似した問題があります。 int(0)typedef int *intptr; intptr(0);は記述できますが、int*(0)は記述できません。その場合の解決策は、「ネイキッド」タイプは単純なタイプ名でなければならないということです。スペースが含まれている可能性のある古いタイプIDや末尾の句読点であってはなりません。たぶんsizeofも同じ制限付きで定義できたかもしれませんが、私にはわかりません。

101
Steve Jessop

から C99標準

6.5.3.4.2
sizeof演算子は、そのオペランドのサイズ(バイト単位)を生成します。これは、式または括弧で囲まれた型の名前の場合があります。

あなたの場合、intは式でも括弧で囲まれた名前でもありません。

32
Jainendra

Cでsizeof演算子を使用するには2つの方法があります。構文は次のとおりです。

C11 6.5.3 Unary operators
...
sizeof unary-expression
sizeof ( type-name )

オペランドとして型を使用する場合は常に、言語の構文定義により、括弧が必要です。式でsizeofを使用する場合、括弧は必要ありません。

C標準は、式でそれを使用する場合の例を示しています。

sizeof array / sizeof array[0]

ただし、一貫性を保つため、および演算子の優先順位に関連するバグを回避するために、状況に関係なく常に()を使用するよう個人的にアドバイスします。

6
Lundin