忽略 C++0x 中的缩小转换会产生什么后果

发布于 2024-12-22 09:56:08 字数 292 浏览 2 评论 0原文

自从在 g++ 中切换 C++0x 标准以来,我开始看到“缩小转换”错误,特别是在从“int”转换为“short”时,尽管我知道该错误涵盖了更广泛的 转化

任何人都可以阐明引入这种额外安全级别的理由吗?禁用此错误可能会产生什么后果? (除了潜在的精度损失)。

谢谢。

Since switching on the C++0x standard in g++, I've started seeing 'narrowing conversion' errors, particularly when converting from an 'int' to a 'short' although I understand the error covers a much broader swath of conversions.

Can anyone shed some light on the rational for introducing this extra level of safety?, What are the possible consequences of disabling this error? (apart from the potential loss of precision).

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自演自醉 2024-12-29 09:56:08

来自赋值和复合赋值运算符[expr.ass]


x={v} 的含义(其中 T 是表达式 x 的标量类型)是 x=T(v) 的含义,除了没有
允许缩小转换(8.5.4)。

以及来自列表初始化[dcl.ini.list]

如果需要缩小转换(见下文)来转换任何参数,则程序格式错误。

所以基本上你不能忽略它,你的程序在存在缩小转换的情况下格式不正确。

来自实施合规性

需要实施来诊断以下程序
使用根据本国际标准格式不正确的扩展。然而,这样做之后,他们就可以编译并执行此类程序。

Bjarne Stroustroup 说这个

防止缩小

问题:C 和 C++ 隐式截断:

   int x = 7.3;        // Ouch!
    void f(int);
    f(7.3);         // Ouch!

但是,在 C++0x 中,{} 初始化不会缩小:

int x0 {7.3};   // error: narrowing
int x1 = {7.3}; // error: narrowing
double d = 7;
int x2{d};      // error: narrowing (double to int)
char x3{7};     // ok: even though 7 is an int, this is not narrowing
vector<int> vi = { 1, 2.3, 4, 5.6 };    // error: double to int narrowing

C++0x 避免大量不兼容性的方法是,在决定什么是收缩转换时,可以(而不仅仅是类型)依赖初始值设定项的实际值(例如上例中的 7)。如果一个值可以精确地表示为目标类型,则转换不会缩小。

char c1{7};      // OK: 7 is an int, but it fits in a char
char c2{77777};  // error: narrowing 

请注意,浮点到整数的转换始终被视为缩小范围 - 甚至 7.0 到 7。

因此在某种程度上,缩小也提高了类型安全性。

From Assignment and compound assignment operators [expr.ass]

The
meaning of x={v}, where T is the scalar type of the expression x, is that of x=T(v) except that no
narrowing conversion (8.5.4) is allowed.

and from List-initialization [dcl.ini.list]

If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.

So basically you can't ignore it, your program is ill-formed in presence of narrowing conversions.

From Implementation compliance:

Implementations are required to diagnose programs that
use such extensions that are ill-formed according to this International Standard. Having done so, however, they can compile and execute such programs.

Bjarne Stroustroup say this:

Preventing narrowing

The problem: C and C++ implicitly truncates:

   int x = 7.3;        // Ouch!
    void f(int);
    f(7.3);         // Ouch!

However, in C++0x, {} initialization doesn't narrow:

int x0 {7.3};   // error: narrowing
int x1 = {7.3}; // error: narrowing
double d = 7;
int x2{d};      // error: narrowing (double to int)
char x3{7};     // ok: even though 7 is an int, this is not narrowing
vector<int> vi = { 1, 2.3, 4, 5.6 };    // error: double to int narrowing

The way C++0x avoids a lot of incompatibilities is by relying on the actual values of initializers (such as 7 in the example above) when it can (and not just type) when deciding what is a narrowing conversion. If a value can be represented exactly as the target type, the conversion is not narrowing.

char c1{7};      // OK: 7 is an int, but it fits in a char
char c2{77777};  // error: narrowing 

Note that floating-point to integer conversions are always considered narrowing -- even 7.0 to 7.

So in a way, narrowing also increases type safety.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文