Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++20 Designated Initializers char[]

C++20 introduces designated initialisers. I'm trying to initalise a character array inside a struct with the new syntax.

Pretty simple problem, I think code may explain it best:

struct Test
{
    unsigned v;
    char b[12];
};

int main()
{
    char str[12] = "hello"; // Works.
    char strb[12]{"hello"}; // Works.
    //
    Test testa
    {
        .v = 100u,
        .b = "hello" //Doesn't work...
    };
    Test testb
    {
        .v = 100u,
        .b = { "hello" } //Doesn't work...
    };
    Test testc
    {
        .v{ 100u },
        .b{ "hello" } //Doesn't work...
    };
    Test testd
    {
        .v{ 100u },
        .b{ "hello" } //Doesn't work...
    };
    Test teste
    {
        .v = 100u,
        .b = {} //This works.
    };
    Test testf
    {
        .v = 100u,
        .b = {'h', 'e', 'l', 'l', 'o', '\0'} //This works.
    };
    return 0;
}

I find this behaviour bazzar, the char str[12] = "hello"; line works just fine. But the same initaliation form doesn't work in designated initialiser lists.

Question : Why can't I initialize the char array with a string literal?

Edit

I was previously using GCC. This works with clang. Is there a workaround for GCC and, is clang or GCC correct?

like image 827
David Ledger Avatar asked Oct 18 '25 12:10

David Ledger


1 Answers

Designated initializers are a minor variation of aggregate initialization. The only use of the designator names are to decide which aggregate member to initialize from the given brace-or-equal initializer. The use of designated initialization changes nothing about the specific form of initialization and therefore, whether or not it is valid.

Given your Test object, Test{100u, "hello"} and Test{.v = 100u, .b = "hello"} are either both valid or both invalid. In both cases, Test::b is initialized in accord with [dcl.init.aggr]4.2:

Otherwise, the element is copy-initialized from the corresponding initializer-clause or is initialized with the brace-or-equal-initializer of the corresponding designated-initializer-clause.

Copy-initialization is the exact same process it would be if you simply initialized an array variable. Which is perfectly valid.

So your could should work. This is a compiler bug.

The GCC "workaround" is to wait for the bug to be fixed. Or go back to standard aggregate initialization until their compiler is fixed.

like image 113
Nicol Bolas Avatar answered Oct 20 '25 01:10

Nicol Bolas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!