ページ 11

ラベルの置き場所によってエラーが出る

Posted: 2018年5月14日(月) 23:55
by h1j1k1

gotoのラベルの置く場所によってエラーが出るか出ないかが変わります。
なぜでしょうか?
OS:win7, compiler:mingw-w64

コード抜粋

コード:

goto lbl;
switch(s){
	case 1:{
	lbl:
	printf(label);
	break;
}
	
error: a label can only be part of a statement and a declaration is not a statement

コード:

goto lbl;
switch(s){
	case 1:{
	printf("label");
	lbl:
	printf("label");
	break;
}

コンパイル成功

Re: ラベルの置き場所によってエラーが出る

Posted: 2018年5月15日(火) 21:59
by みけCAT
そのままでは明らかにコンパイルできないので適当にコードを補ったところ、
どちらのコードもWandbox (C / gcc 8.1.0) でコンパイルが通りました。
そのままコンパイラに入力して問題が再現できるコードを提示していただけますか?

コード:

#include <stdio.h>

int main(void) {
	const char* label = "";
	int s = 0;

	goto lbl;
	switch(s){
		case 1:{
		lbl:
		printf(label);
		break;
	}

	}
	return 0;
}

コード:

#include <stdio.h>

int main(void) {
	int s = 0;

	goto lbl;
	switch(s){
		case 1:{
		printf("label");
		lbl:
		printf("label");
		break;
	}

	}
	return 0;
}

Re: ラベルの置き場所によってエラーが出る

Posted: 2018年5月15日(火) 22:34
by h1j1k1

抜粋するところを間違えていました。
すいません。
コート全体を送らせていただきます。

エラーコード

コード:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define GetRand (((unsigned int)((float)rand() / 32768.0)) * 10)

int main(void) {
	const char* label = "print\n";
	srand((unsigned int)time(NULL));
	int s = GetRand;
	if(s == 3) goto lbl;
	while(0){
		switch(s){
			case 1:{
				lbl:
				int ed = s * GetRand;
				printf("end(%d, %d)", s, ed);
				goto end;
				break;
			}
			case 0:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:{
				printf(label);
				printf(" = %d\n", label);
			}
			default:{
				printf("error");
				exit(1);
				break;
			}
		}
		s = GetRand;
	}
	end:
	return 0;
}



エラー無しコード

コード:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define GetRand (((unsigned int)((float)rand() / 32768.0)) * 10)

int main(void) {
	const char* label = "print\n";
	srand((unsigned int)time(NULL));
	int s = GetRand;
	if(s == 3) goto lbl;
	while(0){
		switch(s){
			case 1:{
				lbl:
				printf(""); // これ追記しただけです
				int ed = s * GetRand;
				printf("end(%d, %d)", s, ed);
				goto end;
				break;
			}
			case 0:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:{
				printf(label);
				printf(" = %d\n", label);
			}
			default:{
				printf("error");
				exit(1);
				break;
			}
		}
		s = GetRand;
	}
	end:
	return 0;
}


暇つぶしに書いたものなので、コードの意味や効率は突っ込まないで頂けるとありがたいです。

Re: ラベルの置き場所によってエラーが出る

Posted: 2018年5月15日(火) 23:16
by みけCAT
エラーメッセージの通り、ラベルの対象が宣言か普通の文かの違いでしょう。

コード:

			case 1:{
				int ed;
				lbl:
				ed = s * GetRand;
				printf("end(%d, %d)", s, ed);
				goto end;
				break;
			}
とするとエラーが出なくなると思います。

Re: ラベルの置き場所によってエラーが出る

Posted: 2018年5月17日(木) 21:13
by あたっしゅ
「構造化プログラミング」の立場から言えば、(C++ の規格に反しなくても)外から switch 文の中に goto 文で突っ込んでいくのがおかしい。
ん、case n: 節から case m: 節に飛ぶのは、ありか ?
goto で return まで飛ぶぐらいなら、その場で、return すりゃ、いいんじゃないの ?
goto 文で美しいと思ったのは、ステイトマシンの記述。

Re: ラベルの置き場所によってエラーが出る

Posted: 2018年5月19日(土) 22:10
by h1j1k1
gotoでswitch文で入るのはやめた方がいいんですね。勉強になりました
case n節からm節に飛ぶのはアウトなんですか?私は普通に使ってました
gotoでreturnに特に意味はないですね。そのままreturnするようにします