質問

Cは、少なくとも3つのレベルの「一定の表現」を定義します。

  • 定数式(修飾なし)
  • 算術定数式
  • 整数定数式

    6.6段落3の読み取り:

    定数式には、代入、インクリメント、デクリメント、関数呼び出し、 またはコンマ演算子(ただし、そうでない部分式に含まれている場合を除く) 評価済み。

    つまり、1,2は一定の表現ではないということですか?

    段落8の内容:

    算術定数式は算術型を持ち、 整数定数、浮動定数、列挙定数、文字であるオペランド 定数、および式のsizeof。算術定数式のキャスト演算子 のオペランドの一部を除いて、算術型を算術型に変換するだけです。 結果が整数定数であるsizeof演算子。

    (union { uint32_t i; float f; }){ 1 }.fのオペランドは何ですか? 1がオペランドの場合、これはおそらく算術定数式ですが、{ 1 }がオペランドの場合、明らかにそうではありません。

    編集:別の興味深い所見:7.17段落3では、offsetofの結果がsize_t型の整数定数式である必要がありますが、私が知る限り、offsetofの標準実装はそうではありません。標準では整数定数式である必要があります。もちろん、これは、実装が(6.6段落10の下で)他の形式の定数式を受け入れること、またはポインター減算ではなく、offsetofマクロを__builtin_offsetofとして実装することが許可されているため問題ありません。ただし、この観察の本質は、整数定数式が必要なコンテキストでoffsetofを使用する場合は、実装によって提供されるマクロを使用する必要があり、独自のマクロをロールする必要がないということです。

役に立ちましたか?

解決

あなたの読書に基づくと、1,2は一定の表現ではありません。なぜそうではないのかわかりませんが、そうではないことに同意します(おそらくそうあるべきであるという事実にもかかわらず)。

6.5.2は、複合リテラルを接尾辞演算子として指定します。だから ジェネラコディセタグプレ

オペランドは、(union { uint32_t i; float f; }){ 1 }演算子に対するfおよび.です。最初の引数はunion型であるため、算術定数式ではありませんが、定数式です。

更新:これは標準の別の解釈に基づいていました。

私の以前の推論は、(union { uint32_t i; float f; }){ 1 }.fが一定の式の基準を満たしているため、一定の式であるというものでした。それでも定数式の基準(6.6段落3)を満たしていると思いますが、標準タイプの定数式(整数、算術、またはアドレス)のいずれでもないため、6.6段落までの定数式の対象となるだけです。 10、これにより実装定義の定数式が可能になります。

私もあなたの編集に取り掛かるつもりでした。 offsetofの「ハック」実装は定数式であると主張するつもりでしたが、上記と同じだと思います。定数式(および場合によってはアドレス定数)の基準を満たしていますが、整数定数式ではありません。したがって、6.6段落10以外では無効です。

他のヒント

1,2が定数式の場合、次のようなコードをコンパイルできます。 ジェネラコディセタグプレ

それが本当の理由かどうかはわかりませんが、1,2を定数式に変換するよりも、この(一般的な?)間違いに対してエラーを出すことが重要であると考えられていたと思います。

更新:R。がコメントで指摘しているように、VLAの導入以降、コードについてのコードはコンパイラエラーではなくなりました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top