#D0003. 环境测试 3:窄化转换

环境测试 3:窄化转换

题目描述

下面这段代码是一些爆 00 惨剧的最小实现。

这个代码可以在 DevC++ 中成功运行(伴随着一些警告),但是会在正式比赛中直接得到编译错误。这是因为大括号初始化不允许窄化转换,绝大多数版本的编译器下都会得到编译错误,而在某些编译器版本下(比如 DevC++ 的 4.9.2 版本)中只会警告。

如果提交这段代码得到了 AC 的结果,则说明当前 OJ 环境与比赛评测环境不一致。

#include<bits/stdc++.h>
using namespace std;

int main(){
	int a{1e18};
	cout<<"Hello World";
	return 0;
}

当年比赛时很多同学是使用了类似于下面的这段代码爆 00.

#include<bits/stdc++.h>
using namespace std;
struct Num{
	int x;
}; 
Num a;
int main(){
	a = {1e18};
	cout<<"Hello World";
	return 0;
}

(显然你可以通过提交正常的 Hello World 正确地程序拿到这题满分。

输入格式

无输入

输出格式

输出 Hello World

Hello World

背景

窄化转换

在C++中,窄化转换(narrowing conversion)是一种潜在的不安全的数值转换,其中目标类型可能无法保存源类型的所有值。

以下转换被定义为窄化转换:

  • 从浮点类型到整型。
  • 从浮点类型到级别较窄或较低的浮点类型,除非要转换的值是constexpr并且在目标类型的范围内(即使目标类型的精度不足以存储数字的所有有效数字)。
  • 从整数类型转换为浮点类型,除非要转换的值是constexpr,并且其值可以精确存储在目标类型中。
  • 从整型转换为不能表示原始类型的所有值的另一整型,除非要转换的值是constexpr,并且其值可以精确存储在目标类型中。这包括从宽到窄的整数转换,以及整数符号转换(有符号到无符号,反之亦然)。
  • 在大多数情况下,隐式窄化转换将导致编译器警告,但有符号/无符号转换除外(根据编译器的配置方式,这可能会产生警告,也可能不会产生警告)。

应尽可能避免窄化转换,因为它们可能不安全,是潜在错误的来源。

大括号初始化不允许窄化转换,除少数几个版本的编译器外,都会得到编译错误。