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;
}

Source: Windows Questions C++

LEAVE A COMMENT