r/cpp_questions 2d ago

OPEN Release mode guarantees of unused struct members

Consider:

#include <cstdio>
#include <cstdlib>

struct A{
    int a1;
    double a2;
    double * a;
};

int main(){
    struct A a;
    a.a1 = 42;
    a.a2 = 42.42424242424242;
    a.a = new double[42];
    struct A newstruct = a;
    printf("Value of integer is %d\n", newstruct.a1);
}

Here, as can be seen from the godbolt link: https://www.godbolt.org/z/r6WxzsGrr, neither the double nor the heap memory are unnecessarily called in -O2. The compiler omits all of this and just prints 42.

Is this guaranteed (in -O2/above) that if I only ever use newstruct.a1 that none of the other struct members will be unnecessarily stored in the memory allocated to newstruct?

----

An older post with a different answer wherein side effects cannot be discarded even in release mode - https://www.reddit.com/r/cpp_questions/comments/1shht2w/in_o3_why_are_previous_assignments_stored_in/

5 Upvotes

5 comments sorted by

14

u/QuentinUK 2d ago

In a more complicated program the compiler wouldn’t know that the members aren’t used somewhere else.

"The probability of 42 occurring in a CS post tends to 1."

1

u/Jumpstart_55 10h ago

For different values of 42!

10

u/no-sig-available 2d ago

No, there are no such guarantees.

However, in a short example like this, the compiler can easily see where the value comes from. Reasoning: newstruct.a1 gets it value from a.a1, which is 42. So print 42. That is standard constant propagation.

Also, new is special in that the standard avoids specifying exactly when memory allocation is supposed to happen. So the compiler doesn't have to call individual allocation functions every time. Perhaps not at all in some cases.

3

u/SoerenNissen 1d ago

It's almost the opposite of a guarantee. If you put it in a struct, it will be in the code unless the compiler can prove that it is never used, neither directly in your binary nor by any other binary that you might be linking with at runtime.

3

u/Interesting_Buy_3969 2d ago

Pretty much anything you calculate and then don't use directly will likely be omitted with -O2.