语句goto不能跨越变量定义? [英] Statement goto can not cross variable definition?

查看:1060
本文介绍了语句goto不能跨越变量定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设这些代码编译在 g ++ 中:

  #include< ;文件stdlib.h> 

int main(){
int a = 0;

转到;

int * b = NULL;

exit:
return 0;
}

g ++ 会抛出错误:
$ b

  goto_test.c:10:1:错误:跳转到标签'exit'[-fpermissive] 
goto_test.c:6:10:错误:从这里[-fpermissive]
goto_test.c:8:10:错误:交叉初始化'int * b'

好像 goto 不能交叉指针定义,但是 gcc 将它们编译好,没有任何抱怨。

修正错误后,我们必须在任何 goto 语句之前声明所有指针,也就是说你必须声明这些指针,即使你现在不需要它们(并且违反了一些原则)。



g ++ 禁止使用 tail-goto 语句?




更新:



goto 可以交叉变量(任何类型的变量,不限于指针)声明,但除了那些获得初始化值的声明。如果我们删除上面的 NULL 赋值,现在 g ++ 保持静默。所以如果你想声明 goto -cross-area之间的变量,不要对它们进行初始化(并且仍然违反一些原则)。 >

解决方案

跳转后不能跳过变量的定义,因为跳转后这些变量不会存在变量的生命周期始于定义点。该规范似乎没有明确提到goto不能这样做,但它隐含在关于变量生命周期的内容中。



由于错误提及 [--fpermissive] ,您可以通过指定编译器标志将其变为警告。这表明两件事。它曾经被允许(变量会存在,但在跳转后未被初始化),并且gcc开发人员认为规范措辞意味着这是被禁止的(或者意味着它是未定义的行为,因为它们可以选择禁止它们)。



编译器只检查变量是否正式存在,而不检查它是否被使用,否则结果会不一致。但如果你不再需要变量,你可以自己结束它的一生,使尾随可行:

  int main(){
int a = 0;
转到退出;
{
int * b = NULL;
}
exit:
return 0;
}

完全有效。

在附注中,您正在使用 g ++ 进行编译,但只要文件的扩展名为 .c ,它被认为是C而不是C ++。 gcc g ++ 在一些默认标志中有所不同,主要针对链接器阶段,但它们都编译任何已安装的语言(C, C ++,ObjC,ObjC ++)。


Suppose these code compiled in g++:

#include <stdlib.h>

int main() {
    int a =0;

    goto exit;

    int *b = NULL;

exit:
    return 0;
}

g++ will throw errors:

goto_test.c:10:1: error: jump to label ‘exit’ [-fpermissive]
goto_test.c:6:10: error:   from here [-fpermissive]
goto_test.c:8:10: error:   crosses initialization of ‘int* b’

It seems like that the goto can not cross pointer definition, but gcc compiles them ok, nothing complained.

After fixed the error, we must declare all the pointers before any of the goto statement, that is to say you must declare these pointers even though you do not need them at the present (and violation with some principles).

What the origin design consideration that g++ forbidden the useful tail-goto statement?


Update:

goto can cross variable (any type of variable, not limited to pointer) declaration, but except those that got a initialize value. If we remove the NULL assignment above, g++ keep silent now. So if you want to declare variables that between goto-cross-area, do not initialize them (and still violate some principles).

解决方案

Goto can't skip over definitions of variables, because those variables would not exist after the jump, since lifetime of variable starts at the point of definition. The specification does not seem to explicitly mention goto must not do that, but it is implied in what is said about variable lifetime.

Since the error mentions [-fpermissive], you can turn it to warning by specifying that compiler flag. This indicates two things. That it used to be allowed (the variable would exist, but be uninitialized after the jump) and that gcc developers believe the specification wording implies this is forbidden (or implies it's undefined behaviour which they chose to forbid because they can).

The compiler only checks whether the variable formally exists, not whether it's used, otherwise the results would be rather inconsistent. But if you don't need the variable anymore, you can end it's lifetime yourself, making the "tail-goto" viable:

int main() {
    int a =0;
    goto exit;
    {
        int *b = NULL;
    }
exit:
    return 0;
}

is perfectly valid.

On a side-note you are compiling with g++, but as long as the file has extension .c, it's considered C and not C++. gcc and g++ differ in some default flags, mainly for linker phase, but they both compile any installed language (C, C++, ObjC, ObjC++) as determined by the extension.

这篇关于语句goto不能跨越变量定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆