スニペット:
((int8_t) + (78));
value を取り、unaryを適用し、それを型にキャストしてから捨てる式です。法的な表現とまったく違いはありません。78
+
int8_t
42;
a + 1;
また、式を評価して結果を破棄します (ただし、コンパイラが副作用がないと判断できる場合、これらは最適化されて存在しない可能性があります)。
これらの「裸の」式は C で完全に有効であり、一般に with などの副作用がある場合にのみ役立ちます。これは、値をインクリメントするという副作用i++
で計算して破棄します。i
そのマクロを使用する必要がある方法は、次の行に沿ったものです。
int8_t varname = INT8_C (somevalue);
一見冗長な単項演算子の理由は+
、標準で見つけることができます。C99 の引用6.5.3.3 Unary arithmetic operators /1
:
単項 + または - 演算子のオペランドは算術型でなければなりません。
そして、で6.2.5 Types, /18
:
整数型と浮動小数点型をまとめて算術型と呼びます。
つまり、単項+
は、ポインタ、複素数、または構造体など、マクロ内の他のすべてのデータ型を使用することを防ぎます。
そして最後に、あなたの理由:
signed char + 78;
スニペットが機能しないのは、同じではないためです。これは型の変数を宣言し始めていますが、それは正当な変数名ではないため、signed char
に到達するとチョークします。+
作業スニペットと同等にするには、次を使用します。
(signed char) + 78;
+78
type への値のキャストですsigned char
。
また、 C99 に従って7.8.14 Macros for integer constants /2
、これらのマクロで非定数を使用することにも注意する必要があります。それらは動作することが保証されていません。
これらのマクロのインスタンスの引数は、対応する型の制限を超えない値を持つ接尾辞なしの整数定数 (6.4.4.1 で定義) でなければなりません。
6.4.4.1
さまざまな整数形式 (10 進数/8 進数/16 進数) をさまざまな接尾辞 ( U
、UL
、ULL
、L
およびLL
型に応じて対応する小文字) と共に指定するだけです。肝心なのは、変数ではなく定数でなければならないということです。
たとえば、次のglibc
とおりです。
# define INT8_C(c) c
# define INT16_C(c) c
# define INT32_C(c) c
# if __WORDSIZE == 64
# define INT64_C(c) c ## L
# else
# define INT64_C(c) c ## LL
# endif
これにより、INT8_C
マクロは正常に機能しますが、テキストINT64_C(val)
は前処理されてvalL
またはvalLL
になり、どちらも必要ありません。