简体   繁体   中英

Type of ternary operator integer expression when used in aggregate struct initialisation

I've run into an interesting warning (with GCC and clang -Wnarrowing at least, haven't tested other compilers), when aggregate initialising a struct using a ternary operator expression (see below code). I don't understand why the type of the expression is apparently considered int in the aggregate initialisation case, but is silently coerced to be a size_t in the others. If C++23 size_t literals were a thing this would not be a problem obviously, as you'd just use the correct literal type. I'm just curious what's actually going on here, if anyone knows?

#include <cstddef>

int main()
{
    struct S { size_t m; };

    S s1 = {0}; // No warning

    bool b = true;
    S s2 = {b ? 1 : 0}; // warning: narrowing conversion of '(b ? 1 : 0)' from 'int' to 'size_t'
    //S s2 = {b ? 1u : 0u}; // No warning

    size_t s3 = b ? 1 : 0; // No warning

    return s1.m || s2.m || s3;
}

The type of b? 1: 0 b? 1: 0 is certainly int .

Brace-initialization (including aggregate initialization) is not allowed to perform narrowing conversions , such as a conversion from a signed type to an unsigned type. This is a narrowing conversion because some values in the source type ( ie , negative numbers) cannot be represented in the destination type. When a narrowing conversion occurs in a non-brace context, it is allowed.

GCC treats the disallowed narrowing conversions as a warning instead of an error, but technically, your code is ill-formed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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