質問
Cで行われる一定の折り畳みについて保証があるかどうか、私は興味があります.
私が見たところ
私には評判が不明なサイトのこのリンクは、率直なコメントをしています。
すべての C コンパイラは、マクロ展開後に存在する整数定数式を折りたたむことができます (ANSI C 要件)。
しかし、たとえば The C Programming Language, second edition (ANSI C のすべての詳細を説明するために完全に更新されたと思います) には何も表示されません。しかし、関連する単語への参照のインデックスをチェックした後、これを約束するものは何も見つかりませんでした. 特に38ページと209ページは、コンパイル時に評価できる任意の式を、定数を使用できる場所で使用できると述べているため(十分に知識があれば、おそらくいくつかの制限があります)、そのような式は次のように述べています。 " may " はコンパイル時に評価されますが、"will"/(いくつかの同義語) ではありません。
この C89 最終案を検索しました。"folding" と "folded" という単語では値の結果が得られず、"constant expression" で検索すると 63 件の一致が生成され、そのうちの約半分を調べました。興味のある主要な部分は基本的に本と同じようです ( 「かもしれない」の代わりに「できる」という言葉を使用していますが、この文脈ではそれらは同義です)。
これらはどちらも、すべての ANSI C コンパイラが基本的な定数折りたたみ機能を備えている必要があることを論理的に強く暗示しているように思われますが、同時に、定数式を式を計算するコードにコンパイルすることに対する厳しい禁止事項はないようです。実行時 (このような実装でも、定数式の利点が得られます。これは、コンパイラが定数式を一度計算すると、値が変化しないと想定するコードを生成できるためです。また、そのような実装は、特定の基礎となるアーキテクチャ (たとえば、いくつかの RISC アーキテクチャ) の制限によって強制される可能性があります。可能な値を初期化するために 2 つの命令を使用するか、メモリ位置からそれらをロードする必要があります)。
この C99 最終ドラフトも簡単に検索しましたが、"folding" は価値のない結果を 1 つ得ましたが、"folded" と "constant" にはそれぞれ 100 以上の一致があり、現在クロールする時間を割り当てることができませんでした。
動機
これらのマクロは、ビットをいじるコードでよりセマンティック/意図を明確にするために作成しました。
#define UCHAR_LOW_N_BITS_m(n) (unsigned char )(UCHAR_MAX >> (CHAR_BIT - (n)))
#define UCHAR_NTH_BIT_m(n) (unsigned char )(1 << (n))
..wheren
は常に整数リテラルです。私は安心したいのですが、「大丈夫です。リモートで重要な使用中のすべての C コンパイラがこれらの定数を折りたたんでくれます」という安心できる声を聞きたいです。(追記: ビットが 0 番目または 1 番目のビットから始まるUCHAR_NTH_BIT_m
かのように動作するかどうかについて、別の質問をしました。できれば適切な場所で行います。)
そして、はい、一番下のものは別のマクロに変えることができます。たとえば、コードでたまたま必要なマクロを#define UCHAR_1ST_BIT_m (unsigned char )1
介して#define UCHAR_3RD_BIT_m (unsigned char )4
、または必要に応じて多くのマクロを作成できます-そして、それらのどれが優れているかについては未定ですが、おそらく議論の余地があります。優れたペダンティック言語弁護士タイプの C プログラマーになるためには、一番上のものを正確に避けることはできません (これらの DSP/組み込みおよび古代のメインフレーム C 実装でコードが正しいことを実行することを確認する必要があります)。