简体   繁体   English

GCC、clang 不同意 MSVC 对缩小转换的看法

[英]GCC, clang disagree with MSVC on narrowing conversion

Consider the following program:考虑以下程序:

struct uint1 {
    unsigned x;
    uint1(unsigned x_) : x(x_) { }
};

struct foo { uint1 a; };

foo f(int v) { 
    return {v}; 
}

struct bar { unsigned a; };

bar g(int v) {
    return {v};
}

Now, where do we have narrowing conversions here?现在,我们在哪里缩小转换?

Compiler编译器 version版本 narrowing conversion in f() ?缩小f()中的转换? narrowing conversion in g() ?缩小g()中的转换?
GCC GCC 11.2 11.2 No Yes是的
clang clang 13.0 13.0 No Yes是的
MSVC MSVC 19.4 19.4 Yes是的 Yes是的

Which is right?哪个是对的? Naively, it seems to me there's a narrowing conversion in both functions.天真地,在我看来,这两个功能的转换都在缩小。

See it all on GodBolt .GodBolt上查看所有内容。

Note: C++17 in case it matters.注意:C++17 以防万一。

It seems that GCC and Clang are right in not classing this as a narrowing conversion.似乎 GCC 和 Clang 没有将其归类为缩小转换是正确的。

The initialisation in question is that of a foo object.有问题的初始化是foo object 的初始化。 Its constructor argument is enclosed in {} .它的构造函数参数包含在{}中。 There cannot be a narrowing conversion in this initialisation, because the argument of the constructor is not of a numeric type.在这个初始化中不能有缩小转换,因为构造函数的参数不是数字类型。 It is struct uint1 .它是struct uint1

So where does struct uint1 cone from?那么struct uint1 cone 是从哪里来的呢? It is converted from v , but not by means of braced initialisation.它是从v转换而来的,但不是通过大括号初始化。 The pair of braces around v is already occupied by the constructor of uint1 . v周围的一对花括号已经被uint1的构造函数占用。

So this is equivalent to foo{uint1(v)} .所以这相当于foo{uint1(v)}

MSVC on the other hand seems to interpret this as foo(uint1{v}) , and I don't think this interpretation is justified.另一方面,MSVC 似乎将此解释为foo(uint1{v}) ,我认为这种解释是不合理的。

Neither compiler complains about an explicit foo{uint1(v)} , as is required by the standard, because there is no narrowing at the top level.两个编译器都没有抱怨标准要求的显式foo{uint1(v)} ,因为在顶层没有缩小范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM