2012-10-13 38 views
6

任何人都可以请我解释一下,为什么编译器允许初始化内置类型的变量,如果初始化器可能会导致信息丢失?为什么编译器允许缩小转换范围

例如C++ Primer,第5版说,编译器不会让我们列出初始化变量的内置类型,如果初始化器可能导致信息丢失。

但我的编译器GCC 4.7.1 v在成功地将下面的代码初始化的变量a

long double ld = 3.1415926536; 
int a{ld}; 

只是有警告:从“长双”到“廉政”内缩小“LD”的转换{ } [ - 差点]。

+2

我会说这本书是错误的。 C和C++与这种东西非常疏忽...... –

+0

@MatthieuM。 C++ 11不是。 – rubenvb

+0

** n3337 ** ** 4.9/1 [conv.fpint] ** *浮点类型的前值可以转换为整数类型的前值。转换截断;也就是说,小数部分被丢弃。如果在目标类型中不能表示被截断的值,那么行为是不确定的*因此,转换是可能的并且在标准中实际定义,不清楚的是它是否被允许*这里*,并且我还没有发现任何关于。 –

回答

10

之一初始化列表的特征在于,收缩转换是不允许的。但是,语言定义并不区分警告和错误;当代码格式不正确时,它需要“诊断”,它被定义为来自一组实现定义消息的任何消息。警告符合这个要求。这是非标准扩展的机制:发布了警告,编译器可以自由地做任何事情,包括根据特定于实现的规则编译内容。

2

您可以设置编译器标志将所有警告标记为错误。在这种情况下,只有它会阻止你这样做。否则它只会是一个警告。

0

这个问题最近出现了。用gcc-4.7一个命令行开关接通所需的行为:

g++ -Werror=narrowing ... 
+0

这不是C++ 11的变化吗?我认为在C++ 11之前允许缩小转换范围,但是根据C++ 11中的通用初始化语法禁止转换。 – rubenvb

+2

@rubenvb - 它不会改变任何东西从C + + 03;它引入了**新语法**用于初始化,具有不同的规则(不缩小转换);使用其他形式的初始化的代码不受限于缩小转换的限制。 –

+2

@Pete使用braced-init-list(C++ 03中可能使用不同的名称)初始化数组不允许缩小C++ 11中的转换次数,这是一个重大改变。 – rubenvb

相关问题