解决c++ error:crosses initialization of 问题

 更新时间:2023年03月21日 14:24:55   作者:会飞的晨蕊  
最近在写代码的时候,碰到了 crosses initialization of ... 的问题,只因我在 switch 的某个 case 分支下定义了一个变量,于是乎便将这个问题整理一下,需要的朋友可以参考下

最近在写代码的时候,碰到了 crosses initialization of ... 的问题,只因我在 switch 的某个 case 分支下定义了一个变量,于是乎便将这个问题整理一下。

情形1 在 switch case 的某个分支定义了变量

1.1 问题代码示例

#include <iostream>

void switchTest(int code);

int main() {
    switchTest(1);
}

void switchTest(int code) {
	switch (code) {
	case 1:
		int myNum = 0;
		break;
	case 2:
		break;
	default:
		break;
	}
}

上述代码,我在第一个 case 分支下定义了 myNum 变量,尝试编译,出现如下错误。主要看 C2360 这一行,myNum 的初始化操作由 case标签跳过,也就是说当 code !=1 的时候,不会进行 myNum 的初始化。第一反应是“我这个 myNum 只在 case 1 下用啊,不初始化就不初始化嘛,反正其他地方又不用”。

在这里插入图片描述

呃,这就牵扯到变量的作用范围了。myNum 这个局部变量的作用范围是从定义处开始直到 switch 语句结束。通俗说,就算我们跳过了 case 1 处的初始化,myNum 在后面的分支中,也是可以被访问到的,被访问到就有可能被使用(虽然我们自己没打算在后面使用,但编译器认为这是有风险的),但是我们又没有对其进行初始化,那这就会出问题。那这个问题怎么处理呢?

1.2 问题的解决

1.2.1 限定 myNum 的作用域

void switchTest(int code) {
	switch (code)
	{
	case 1:
	{
		int myNum = 0;
		break;
	}
	case 2:
		break;
	default:
		break;
	}
}

我们给 case 1 加上大括号,明确告诉编译器,我们在后面不使用这个 myNum 了,它只在 case 1 里有效,这种方式应该是最符合我们本意的。

1.2.2 确保 myNun 被初始化

void switchTest(int code) {
	int myNum = 0;
	switch (code)
	{
	case 1:
		break;
	case 2:
		break;
	default:
		break;
	}
}

既然 myNum 不被初始化的原因的是 case 分支,那么我们将 myNum 的初始化提到 switch 外面吧,这样一来,在它的作用域内,myNum 就肯定会被初始化了。

1.2.3 不算方案的方案

void switchTest(int code) {
	switch (code)
	{
	case 2:
		break;
	case 1:
		int myNum = 0;
		break;
	}
}

上面这种写法是能编译过的,而且满足我的意图。我把 case 1 放到了最后一个分支,这样一来,myNum 的作用域就只是在最后一个分支了,在 myNum 的作用域内,它都是被初始化了的,因此是不会出问题的。当然,这样写只是为了说明,出现这个错误的根因是:变量在其作用范围内,可能不会被初始化。(项目中请勿这样弄哦)

情形2 goto 跳过了变量的初始化

2.1 goto 中的错误示例

#include <iostream>

void gotoTest();

int main()
{
	gotoTest();
}

void gotoTest() {
	goto label;
	int myNum = 1;
	label: std::cout << "goto the label" << std::endl;
}

上面的代码里,我们使用 goto 跳过了 myNum 的初始化,不出意外的出了意外,编译时出现如下错误,原因和我们上面 switch 的例子是一样的,那解决方法自热也是类似的

在这里插入图片描述

2.2 问题的解决

2.2.1 限定 myNum 的作用域

void gotoTest() {
	goto label;
	{
		int myNum = 1;
	}
	label: std::cout << "goto the label" << std::endl;
}

限制 myNum 的作用域,告诉编译器我们在后面不使用了。

2.2.2 确保 myNun 被初始化

void gotoTest() {
	int myNum = 1;
	goto label;
	label: std::cout << "goto the label" << std::endl;
}

将 myNum 的初始化提前,确保不会因为 goto 导致跳过了初始化。

结论

crosses initialization of 翻译过来就是 跳过了初始化,根本原因是变量在其作用范围内,存在不被初始化的风险,解决思路有两个:一是明确限定变量的作用域;而是将初始化提前,避免不被初始化的发生。

到此这篇关于解决c++ error:crosses initialization of 问题的文章就介绍到这了,更多相关c++ crosses initialization of内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于C++制作一个简单的跑酷游戏

    基于C++制作一个简单的跑酷游戏

    这篇文章主要为大家详细介绍了如何利用C++制作一个简单的跑酷小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2023-06-06
  • 你真的知道C++对象大小吗?

    你真的知道C++对象大小吗?

    这篇文章主要给大家介绍了关于C++对象大小的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • C++容器vector实现通讯录功能

    C++容器vector实现通讯录功能

    这篇文章主要为大家详细介绍了C++容器vector实现通讯录功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • C语言进阶输入输出重定向与fopen函数使用示例详解

    C语言进阶输入输出重定向与fopen函数使用示例详解

    这篇文章主要为大家介绍了C语言进阶输入输出重定向与fopen函数的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • C语言实现简易扫雷程序

    C语言实现简易扫雷程序

    这篇文章主要为大家详细介绍了C语言实现简易扫雷程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C语言交换奇偶位与offsetof宏的实现方法

    C语言交换奇偶位与offsetof宏的实现方法

    offsetof()是C自带的一个宏,它的作用就是计算结构体成员相对于首地址处的偏移量,下面这篇文章主要给大家介绍了关于C语言交换奇偶位与offsetof宏的实现方法,需要的朋友可以参考下
    2023-02-02
  • C++编程中的数据类型和常量学习教程

    C++编程中的数据类型和常量学习教程

    这篇文章主要介绍了C++编程中的数据类型和常量学习教程,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • 详解C语言-二级指针三种内存模型

    详解C语言-二级指针三种内存模型

    这篇文章主要介绍了详解C语言-二级指针三种内存模型的相关知识,文中代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下
    2020-06-06
  • C++通过boost.date_time进行时间运算

    C++通过boost.date_time进行时间运算

    这篇文章介绍了C++通过boost.date_time进行时间运算的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C++函数的默认参数详情

    C++函数的默认参数详情

    这篇文章主要介绍了C++函数的默认参数得相关资料,C++中的默认参数的用法和Python基本一致。使用默认参数的方法非常简单,也就是我们在函数声明的时候,就为某些参数指定好默认值,当我们调用函数的时候,如果没有传入对应的参数,那么则使用默认值,下面来看文章具体内容吧
    2021-11-11

最新评论