「教えて!ピックアップ」リリース!

 assert.h を見ると、次のように書かれています。

#define assert(x) ((void)0)

 文法的に (void)0 どのように解釈出来るのでしょう。

 次のプログラムで試すとエラーにもならず、コンパイラ結果を見ると何もしていないのが分かりました。

voidmain(void)
{
(void)0;
}

A 回答 (3件)

> 文法的に (void)0 どのように解釈出来るのでしょう。



文法的には,単純に,0をvoid型にキャストしているだけです。
cast-expression: (void)0 as '(' type-name ')' cast-expression
 type-name: void
 cast-expression: 0 as unary-expression
  unary-expression: 0 as postfix-expression
   postfix-expression: 0 as primary-expression
    primary-expression: 0 as constant

そして,void型への型変換は,規格 (ISO/IEC 9899:1999) の
6. Language - 6.3 Conversions - 6.3.2 Other operands - 6.3.2.2 void
に説明があり,
> If an expression of any other type is evaluated as a void expression, its value or designator is discarded.
と書かれています。
つまり,値0は単純に破棄されます。

ちなみに,全ての式文は,6.8.3 Expression and null statementの第2段落に
> The expression in an expression statement is evaluated as a void expression for its side effects.
とあるため,voidへのキャストがあるかのように扱われます。
    • good
    • 1
この回答へのお礼

 回答有り難う御座います。

 詳しいですね。規格を此処まで熟知している人は少ないと思います。
 頼りになります。
 英語の勉強にもなりました。

 また質問したときには、宜しくお願いします。

お礼日時:2009/12/22 13:00

C言語では、関数呼び出しも代入計算も、基本的に全ての文は「式」に「;」を付けたものになっています。



「func();」という文は、「func()」という式を文にしたものになります。
「b=a+1;」という文は、「b=a+1」という式を文にしたものになります。

同じように、「0;」という文は、「0」という式を文にしたものになります。
ただし、このままだと数式の値を何にも利用していませんから、
コンパイラはバグの可能性を考えて「式の結果を利用していない」という警告を出す場合があります。(例えば、「a+1;」も文としては正しいですが、何の意味もない式文ですので、記述者が間違えている可能性が高いと推測できます)

そこで、「0」という式をvoidにキャストする「(void)0」にすると、式の値を使っていないことを明示できるため、そういう警告を出さないようにできるのです。

では、非デバッグ時にassertの定義がなぜこのような形になっているかというと、
if (foo) assert(bar);
といった形でassertが使われた時に、assert の効果は無くしつつも、assertを式として成立させて、if文としての体裁は変わらないようにしているのです。
    • good
    • 1
この回答へのお礼

 早速の回答有り難う御座います。

 mtaka2さんの回答を見て下記のプログラムで試した所、コンパイラからは警告もエラーも有りませんでした。
 ルネサスのマイコン用コンパイラHEWを使っています。
 MISRA C と言うC言語のチェッカでは次の警告が有りました。

0; 何の副作用も無いという警告有り
1 == 1; 何の副作用も無いという警告有り
(void)0; 何の副作用も無いという警告有り
if (1)  ; {}を付けた方が良いと言う警告有り
if (1){} ; 警告無し
if (1){(void)0;}; 何の副作用も無いという警告有り

 (void)0 を使えば警告は出なくなる事を期待したのですが、出るようです。

お礼日時:2009/12/22 11:43

「void へのキャスト」は「評価した値を使わない」ことを明示することになります. 「関数呼び出しや副作用を一切持たない式文にたい

して警告を出す」処理系においては, 「void にキャストする」ことでそのような警告を抑制することができます.
    • good
    • 0
この回答へのお礼

 いつも回答有り難う御座います。

 void と同じように無い事を明確にする訳ですね。
 int から long にキャストする例は見かけますが、void にキャストしたらエラーかポインタような感じがしますよね。

お礼日時:2009/12/22 13:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


人気Q&Aランキング