#Why doesn't this generate a reorder warning?

24 messages · Page 1 of 1 (latest)

lone kiln
#
struct Foo {
    A a; // has innards that depend on b, taken in as a reference to b
    C c; // some other object that uses b
    B b;

    Foo()
        : a(b), c()
    {}
};

gcc 15.2.1
clangd 20.1.8

Just surprised I didn't get any warnings before it crashed trying to use a b that wasn't fully constructed. Thought this would be an easy one for the compiler?

sand zenithBOT
#

@lone kiln

It looks like you may have code formatting errors in your message

Note: Make sure to use back-ticks (`) and not quotes (')
Note: Make sure to specify a highlighting language, e.g. `cpp`, after the back-ticks

Markup

```cpp
int main() {}
```

Result
int main() {}
#

When your question is answered use !solved or the button below to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

lone kiln
#

A and B are both structs

torpid anvil
lone kiln
#

B has default constructor, A does not

torpid anvil
#

I assume the warning wouldn't care if A was just an aggregate with a reference to B for example

lone kiln
#

A wouldn't qualify because I gave it a constructor? altho it's simple, it just takes two references

torpid anvil
lone kiln
#

just saved as a ref in an initializer list

#

without rearranging the order, it crashes elsewhere while attempting to use B before it's constructed. Put A after B and that no longer happens.

sick zealot
#

Would be better to have a complete example we can compile ourselves

arctic trellis
#

The compilers have a warning about the order of initializers, but that isn't what is wrong here. You have only one initializer in the constructor.

#

What is potentially wrong is that you might have UB due to an out-of-lifetime access to b before it is initialized. GCC and Clang do warn about this if that is the case.

#

I didn't get MSVC to warn for this though.

lone kiln
#

I can try to come up with a concrete example tomorrow. It's getting late. I know that B wasn't initialized because the data structures in B was pointing to invalid memory (gdb)

#

whichw as just a vector

lone kiln
#

A doesn't use b directly either. It simply sets up a context for other objects. C does use it though. I had the order wrong, so I edited the initial post. B came last in the declaration list. Crash was happening in C when was trying to use B

all members automatic storage.

arctic trellis
#

The order of initializers is still correct though, but you might have simply hidden the actual out-of-lifetime access well enough now that the compiler can't see it any more or that it is out of scope of the analysis for the uninitialized access warning.

lone kiln
#

yeah. Actually C uses the context setup by A, which stores a ref to B

arctic trellis
#

storing the reference to b in a before b is initialized is completely valid, the compiler probably intentionally doesn't warn about this

#

just actual access is UB

lone kiln
#

Yeah, I'll have to try to produce a simple concrete example tomorrow, if I can.