最近在换了工作后,在新公司上班刚一个多星期就接到一个任务:修改某个模块的.c为.cpp文件,解决编译问题。这不中遇到最多的就是修改goto问题,可能是项目的需要吧,几乎每个c文件里都有好几个goto。
C语言中goto随意用,但C++中却是不行的,修改为cpp后最常见的编译错误如下图:
C++中不允许跳过变量初始化,即goto语句后不能有变量的定义。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int test = 0;
goto error_label;
int a = test;
error_label:
return -1;
}
这样编译错误:
但如果改成:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int test = 0;
goto error_label;
int a;
error_label:
return -1;
}
是否有编译错误?答案是:编译正常。
stackoverflow 上也有相关的解释:
g++ - Statement goto can not cross variable definition? - Stack Overflow
这似乎是涉及到资源释放问题,正如上面所说的,goto后不能有变量的定义,而不是声明,那声明和定义最大的区别是什么呢?我一直记得在学校时老师说的:定义才分配内存,而声明是没有分配内存的。
#include <stdio.h>
#include <stdlib.h>
int value;
int main()
{
int test = 0;
char *p = nullptr;
// goto error_label;
int a;
int b = 10;
error_label:
return -1;
}
gdb跟踪:
从打印中似乎可以看出,a并未分配内存地址,b分配了内存地址,全局变量value也有内存地址,从地址上显明可以看出value和b肯定不在同一个区块,因为:
全局变量value既是声明也是定义了,因为它会存在bss段中。
但c++并没有真正解决这个资源释放问题啊,因为可以在goto前声明一个变量(指针变量),在goto后给这个指针申请内存,这样goto跳转后,也会造成内存泄漏。那到底c++是为何禁止goto后有变量初始化呢?有大神知道的话指点一下。