Hatena Blog Tags

コンマ演算子

(コンピュータ)
こんまえんざんし

プログラム言語Cにおける,(コンマ演算子,comma operator)

意味規則 コンマ演算子は,左オペランドをボイド式として評価する。その評価の直後を副作用完了点とする。次に右オペランドを評価する。コンマ演算子の結果は,右オペランドの型及び値を持つ*1。コンマ演算子の結果を変更するか,または次の副作用完了点の後でそれにアクセスしようとした場合,その動作は未定義とする。

代入式を並べることで,コンマ演算子を用いたときとほぼ同じ動作を実現できるので,コンマ演算子はあまり使われない。

サンプルコード

#include <stdio.h>
int main(void){
	int a = 0;
	a = 10; a = 20; printf("%d\n", a);  // 3つの代入式の並び
	a = 10, a = 20, printf("%d\n", a);  // コンマ演算子の使用で1つの式
}

サンプル出力

20
20

しかし,代入式を並べることが出来ない箇所ではコンマ演算子が活躍する。代入式を並べることが出来ない代表的な箇所は,繰り返し文の制御式と,for文の節1,式3である。

サンプルコード

#include <stdio.h>
int main(void){
	int i, j;
	for (/*節1*/i = 0, j = 9; i < j; /*式3*/++i, --j){
		printf("%d %d\n", i, j);
	}
	while (/*条件式*/printf("%d ", i), i){
		--i;
	}
}

サンプル出力

0 9
1 8
2 7
3 6
4 5
5 4 3 2 1 0

また,コンマ演算子とコンマ区切り子は文法上別のものとして扱われる。初期化子並びや実引数式並びに現れるコンマは区切り子である。それらの文脈でコンマ演算子を用いるには括弧を使う。

サンプルコード

#include <stdio.h>
int main(void){
	printf("%d\n", (0, 1, 2));
}

サンプル出力

2

本来であればコンマ演算子の結果は左辺値ではなく評価した値を返すが,左辺値を返す実装も存在する*2。しかし,その結果(左辺値)を変更すること,またそれにアクセスすることは結局のところ未定義動作となる。

サンプルコード

#include <stdio.h>
int main(void){
    int a = 3, b = 5;
    (a, b) = 7;            // コンマ演算子の結果を変更しようとしている
    printf("b = %d\n", b); // コンマ演算子の結果にアクセスしている
}

gccやdmcでは上記コードでコンパイルが通るが,プログラム言語Cにおいて全く移植性のないコードなので普通用いるべきではない。(gccでは警告を出す。)未定義動作のコードなのでサンプル出力も挙げない。

*1:コンマ演算子は,左辺値を返さない。

*2:C++に合わせていると思われる。

このタグの解説についてこの解説文は、すでに終了したサービス「はてなキーワード」内で有志のユーザーが作成・編集した内容に基づいています。その正確性や網羅性をはてなが保証するものではありません。問題のある記述を発見した場合には、お問い合わせフォームよりご連絡ください。

関連ブログ