缩小初始化列表时,g ++ 4.9和g ++ 5的行为不同 [英] g++4.9 and g++5 different behaviour when narrowing in initializing list

查看:121
本文介绍了缩小初始化列表时,g ++ 4.9和g ++ 5的行为不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

#include <iostream>

int main()
{
    int i{10.1}; // narrowing, should not compile
    std::cout << i << std::endl;
}

根据C ++ 11标准,它不应编译(禁止拉大括号初始化)

According to the C++11 standard, it should not compile (narrowing in brace initialization is forbidden.)

现在,使用g++4.9.2 -std=c++11编译只会发出警告

Now, compiling with g++4.9.2 -std=c++11 only emits a warning

warning: narrowing conversion of '1.01e+1' from 'double' to 'int' inside { } [-Wnarrowing]

删除-std=c++11标志会导致有关括号初始化的警告,但不会缩小:

Removing the -std=c++11 flag results in a warning regarding the brace init, but not any narrowing:

warning: extended initializer lists only available with -std=c++11 or -std=gnu++11

另一方面,如果您使用g++5 -std=c++11进行编译,则g ++ 5 不会对其进行编译.但是,如果省略了-std=c++11,那么即使g++5也会很高兴地对其进行编译,仅给出与括号初始化有关的警告,而不是与变窄有关的警告:

On the other hand, g++5 doesn't compile it, provided you compile with g++5 -std=c++11. However, if -std=c++11 is omitted, then even g++5 happily compiles it, giving just a warning related to the brace init, not to the narrowing:

warning: extended initializer lists only available with -std=c++11 or -std=gnu++11

上述行为似乎有问题,g++4.9不应该编译代码,并且如果忘记指定-std=c++11g++5对其进行编译就很奇怪了.这是一个已知问题吗?

The above behaviour seems buggy, g++4.9 should not compile the code, and it is more than weird that g++5 compiles it if you forget to specify -std=c++11. Is this a known problem?

推荐答案

标准从不说任何不应该编译"的内容. (#error除外).某些格式错误的程序必须发出诊断信息,并发出警告才能满足要求.

The standard never says anything "should not compile" (except for #error). Certain ill-formed programs must emit a diagnostic and issuing a warning satisfies that.

您可以使用开关-Werror使gcc在所有诊断程序上停止编译.可以将其缩小为特定的警告,例如-Werror=narrowing.

You can cause gcc to stop compilation on all diagnostics by using the switch -Werror. It can be narrowed to specific warnings, e.g. -Werror=narrowing.

如果您使用GNU ++或默认模式而不是C ++ 11进行编译,则编译器可以执行其喜欢的任何事情,包括接受缩小的转换而不会产生投诉.

If you are compiling in GNU++ or whatever the default mode is instead of C++11 then the compiler can do whatever it likes, including accepting narrowing conversions without complaint.

参考:N3936 [intro.compliance]/2

Reference: N3936 [intro.compliance]/2

  • 如果程序包含任何可诊断规则的违反,则合格的实施应至少发布一条诊断消息.

  • If a program contains a violation of any diagnosable rule [...], a conforming implementation shall issue at least one diagnostic message.

如果程序违反了不需要诊断的规则,则本国际标准对与该程序有关的实现不作任何规定.

If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program.

[defns.diagnostic]

[defns.diagnostic]

诊断消息

属于实施的输出消息中由实施定义的子集的消息

message belonging to an implementation-defined subset of the implementation’s output messages

从第一个项目要点还请注意,不需要消息的数量或内容与违规的数量或内容相对应.

Note also from the first bullet point that it is not required that the number or content of messages corresponds to the number or content of the violations.

该标准完全由编译器决定如何组织其错误和/或警告,附带条件是对于某些违规行为,它不能默默地忽略它.

The standard leaves it completely up to the compiler to decide how to organize its errors and/or warnings, with the proviso that for certain violations it can't silently ignore it.

这篇关于缩小初始化列表时,g ++ 4.9和g ++ 5的行为不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆