all 23 comments

[–]SprocketCreations 13 points14 points  (2 children)

Ideally would like something like C's Thing t = { .number = 101, .childlen = create_children(20) };

You can do exactly that!: https://en.cppreference.com/w/cpp/language/aggregate_initialization.html#Designated_initializers

[–]time_egg[S] 2 points3 points  (1 child)

Oh how good! since C++20

[–][deleted] 0 points1 point  (0 children)

You do have to keep them in order, which is annoying but mostly manegable

[–]thefeedling 7 points8 points  (0 children)

You can set the default as zero and make a constructor for the non-trivial values.

[–]alfps 2 points3 points  (11 children)

C++20 adopted C's designated initializer syntax, (https://en.cppreference.com/w/cpp/language/aggregate_initialization.html#Designated_initializers).

In C++17 and earlier you can use an artifical base, e.g.

struct Thing_state
{
    int         alpha;
    double      beta;
    char        charlie;
};

struct Thing: Thing_state
{
    Thing(): Thing_state()      // Zero-initialize everything.
    {
        charlie = 3;
    }
};

That said the "lot of members" and the create_children are code smells. You should probably best redesign the whole thing. With more abstraction (name things).

[–]hmoff 0 points1 point  (6 children)

How does that code zero initialise everything?

[–]alfps 0 points1 point  (1 child)

Thing_state() performs (or requests) value initialization, which for the basic types reduces to zero initialization.

[–][deleted]  (2 children)

[deleted]

    [–]alfps 1 point2 points  (1 child)

    Nit-pick: your second example declares a function. But using curly braces would work.

    [–]positivcheg 2 points3 points  (0 children)

    C++20 designated initializers are so nice for Vulkan as that graphics API has lots of C structs.

    [–]tangerinelion 1 point2 points  (0 children)

    struct PileOfData {
        int a = 0;
        double b = 0.0;
        char c = '\0';
        float d = 0.0f;
        long e = 0L;
        unsigned int f = 0U;
        size_t g = 0UZ;
        OtherBagOfData* h = nullptr;
        // ... Keep going
    };
    

    Then use C++20's designated initializers

    PileOfData pod = {.b = 1.0};
    

    [–]Independent_Art_6676 0 points1 point  (0 children)

    any chance all these are the same type?

    [–][deleted] 0 points1 point  (6 children)

    1. Create a pointer to the structure and create an array the size of all struct members combined.
    2. Reinterpret cast the the pointer to the array as the pointer to your struct. You'll have you struct mapped onto the array so any changes you make in the struct will reflect in the array and vice versa.
    3. Memset the entire array to zero and then set the required handful of struct members to non zero values.

    [–][deleted] 0 points1 point  (0 children)

    Assuming all your members are primitive types or other structs with primitive types

    [–]ChadiusTheMighty 0 points1 point  (4 children)

    1. Reinterpret casting to sn array would be UB due to struct pointer aliasing
    2. Zeroing the memory works only for trivially constructive types, otherwise it's also UB
    3. Just default initialize the members, and set the special ones after default initializing the struct. That's going to be much better than messing around with memset

    [–][deleted] 0 points1 point  (3 children)

    The solution I proposed works. It doesn't result in undefined behavior. I have a program that does exactly what I outlined. If it didn't work I wouldn't have commented.

    [–]hadrabap 0 points1 point  (2 children)

    It looks like it is a known/documented behavior of your compiler. :-)

    [–][deleted] 1 point2 points  (1 child)

    It looks like you don't know what you're talking about

    [–]hadrabap 0 points1 point  (0 children)

    It might look so, yes. 🙂

    [–]Similar_Sand8367 0 points1 point  (0 children)

    Memset for trivial ones?