C言語関係掲示板

過去ログ

No.1034 a = b-+-+-+-+-c;の解釈

[戻る] [ホームページ]
No.13246

単項演算子について
投稿者---こう(2004/03/19 21:51:38)


#include <stdio.h>

main()
{
int a=1,b=1,c=1;

printf("%d\n",a);
a = b-+-+-+-+-c;
printf("%d\n",a);

}


上記の様な式は、gccで問題なくコンパイルされ、結果も出力されます。

結果
1
0

ほかにも、a=b+-+c,a=b++-+cなども動くようです。

しかし、どのように理解していいのかわかりません。
どなたかご教授お願いいたします。

No.13247

Re:単項演算子について
投稿者---nop(2004/03/19 23:27:41)


>a = b-+-+-+-+-c;

おそらく
 a = b-(+(-(+(-(+(-(+(-c))))))));

ではないかと。


# >a=b+-+c;
# → a = b + (-(+c));
# >a=b++-+c;
# → a = (b++)-(+c);
#
# おそらくこんなもんでしょ

No.13248

Re:単項演算子について
投稿者---こう(2004/03/20 00:36:32)


確かにそう解釈すればすべてうまくいきます。
実際にその考えを頭に入れてやってみましたところ、

1) a=b+-+-+-+-++c;  これは3        
a=b+(-(+(-(+(-(+(-(++c))))))));

2) a=b+-+-++-+-+c;  これも3 (?)
a=b+(-(+(-(++(-(+(-(+c))))))));

3) a=b+-+-++-+-+-+c; これはコンパイルエラー
a=b+(-(+(-(++(-(+(-(+(-(+c))))))))));

4) a=b+-+-++-+-+-+-++-+-+-+-c; コンパイルエラー 

になりました。
どうやら中間に含まれるインクリメントは、2つ以上はいるとエラーになるようです。インクリメント直前のオブジェクトは、全体としてプラスになってないと、これまたエラーになるようです。デクリメントの場合は、上記の条件を満たしていてもエラーになってしまいました。

こんな感じにまとめてしまいましたが、妥当でしょうかね?


No.13249

Re:単項演算子について
投稿者---YuO(2004/03/20 04:20:51)


>2) a=b+-+-++-+-+c;  これも3 (?)
>a=b+(-(+(-(++(-(+(-(+c))))))));

これはコンパイルエラーになる必要があります。

++演算子はスカラ型の変更可能な左辺値をオペランドとして要求しますが,
+や-といった演算子は左辺値を生成しません。
そのため,++演算子の対象となるオペランドがその制約に違反してしまうのです。
#この制約は前置・後置に関わらず,また--演算子にも言えます。


>こんな感じにまとめてしまいましたが、妥当でしょうかね?

妥当ではないです。


++演算子及び--演算子のオペランドになりうるのは,
  • (const修飾されていない)スカラ型の識別子からなる一次式
  • 結果の型が(const修飾されていない)スカラ型になる,単項*演算子を適用した式
  • 結果の型が(const修飾されていない)スカラ型になる,[]演算子を適用した式
  • ここに列挙した式を括弧で囲った式
になります。


スカラ型(scalar types)というのは,
  • 算術型(arithmetic types)
    • 整数型(integer types) [C90/95では汎整数型(integral types)]
      • char型
      • 符号付き整数型(signed integer types)
      • 符号無し整数型(unsigned integer types)
      • 列挙型(enumerated types)
    • 浮動小数点型(floating types)
      • 実数浮動小数点型(real floating types)
      • 複素数型(complex types) [C90/C95では存在しない]
      • 虚数型(imaginary types) [C90/C95では存在しない/C99ではOptional]
  • ポインタ型(pointer types)
の総称です。
ちなみに,ISO/IEC 9899:1999の定義を元にJIS X 3010-1993の訳を当てはめています。
また,JIS X 3010:2003を持っていないので,規格中での訳語は異なっている可能性があります。
#real floating typesに関して特に自信がない……。

左辺値・変更可能な左辺値は過去ログ882@No.11424を参照してください。


No.13250

Re:単項演算子について
投稿者---こう(2004/03/20 09:37:29)


>>2) a=b+-+-++-+-+c;  これも3 (?)
>>a=b+(-(+(-(++(-(+(-(+c))))))));
>
>これはコンパイルエラーになる必要があります。
>

実際、エラーにはならなかったのですが、どういう理由が考えられるでしょうか。それとも環境の違いでしょうか。

No.13251

Re:単項演算子について
投稿者---RAPT(2004/03/20 10:29:04)


>>>2) a=b+-+-++-+-+c;  これも3 (?)
>>>a=b+(-(+(-(++(-(+(-(+c))))))));
>>
>>これはコンパイルエラーになる必要があります。
>>
>
>実際、エラーにはならなかったのですが、どういう理由が考えられるでしょうか。それとも環境の違いでしょうか。

一言で言うと、あならのせいではありません。
コンパイラの仕様が悪いっていうことになると思います。

No.13252

Re:単項演算子について
投稿者---iijima(2004/03/20 10:53:52)


> a=b+-+-++-+-+c;

BCC5.5.1はコンパイルエラーを報告しました.

> どういう理由が考えられるでしょうか。それとも環境の違いでしょうか。

RAPTさんがおっしゃるように,コンパイラの問題と思われます.

No.13257

Re:単項演算子について
投稿者---こう(2004/03/20 17:30:48)


なるほど、納得いたしました。皆さんありがとうございました。
またよろしくお願いいたします。