萌えハッカーニュースリーダー

2025/04/22 09:27 Detecting if an expression is constant in C

出典: https://nrk.neocities.org/articles/c-constexpr-macro
hakase
博士

やっほー、ロボ子!今日のITニュース、なかなか面白いのがあったのじゃ。

roboko
ロボ子

こんにちは、博士。どんなニュースですか?

hakase
博士

C言語で式がコンパイル時定数かどうかを検出するマクロを作る話!

roboko
ロボ子

コンパイル時定数の検出ですか。それはまたニッチなテーマですね。

hakase
博士

そうそう。C23のstatic複合リテラルを使う方法があるらしいぞ。`typeof`と組み合わせると、式の型を保持しつつ定数だって保証できるんだって。

roboko
ロボ子

`typeof`ですか。式の型を保持できるのは便利ですね。でも、記事によるとClang v20では`static`が複合リテラルでサポートされていないみたいですね。

hakase
博士

あらら、そうなのか。じゃあ、GNU拡張の`__builtin_constant_p`を使う手もあるぞ。これは式が定数かどうかを判定して、違う場合はコンパイルエラーにしてくれる。

roboko
ロボ子

それは便利ですね!でも、整数の型昇格で結果の型が変わる可能性があるから、`__typeof__(x)`でキャストする必要があるんですね。

hakase
博士

さすがロボ子、よく分かってるのじゃ!C11以降なら`static_assert`も使えるぞ。`sizeof`と無名構造体を使うらしい。

roboko
ロボ子

`static_assert`ですか。でも、型の変化や、`static_assert`の式が整数定数式である必要があるという制約があるんですね。

hakase
博士

そうなんだよね。あと、`sizeof`と配列型を持つ複合リテラルを使う方法もあるぞ。C99から使えるらしい。

roboko
ロボ子

複合リテラルが可変長型を受け入れないことを利用するんですね。でも、型の変化や、浮動小数点式をサポートしないという制約があるんですね。

hakase
博士

なかなか一筋縄ではいかないのじゃ。`sizeof`とenum定数を使う手もあるけど、これはenum定数がリークしちゃう問題があるんだよね。

roboko
ロボ子

enum定数がリークするんですか?マクロを複数回使用できないのは困りますね。関数の引数内でenumを宣言すればスコープを限定できるみたいですが、コンパイラが警告を出す場合もあるんですね。

hakase
博士

そうそう。カンマ演算子を使うと、`sizeof`トリックで発生する型の変化を回避できるらしいけど、「カンマ式の左側のオペランドに効果がない」って警告が出ちゃう。

roboko
ロボ子

警告が出るとちょっと気持ち悪いですね。GCCの癖で、昔は負のサイズの配列を使ってコンパイルエラーを起こしてたけど、今は`error`属性を使うようになったんですね。

hakase
博士

そうそう。定数式の検出って、ほんとに奥が深いんだぞ。コンパイラの警告を抑制するのが難しい場合もあるし。

roboko
ロボ子

本当にそうですね。この記事のアップデートで、`_Generic`、三項演算子、nullポインタ定数のルールを使って整数定数式を判定する方法が紹介されてますね。C11が必要で、整数のみに有効みたいですが。

hakase
博士

へー、そんな方法もあるのか!C言語、奥が深いねぇ。まるで私の知識みたい…って、自分で言っちゃった!

roboko
ロボ子

博士、自分で言うのはちょっと…。

hakase
博士

まあ、いいのじゃ!最後に一つなぞなぞ!コンパイル時にしか存在しないものはなーんだ?

roboko
ロボ子

えーと…コンパイル時にしか存在しないもの…コンパイルエラー?

hakase
博士

ブッブー!正解は…私の若さ!…って、オチになってないか!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search