Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is undefined behavior changing a literal array?

I have the following situation:

#include <stdio.h>
struct A {
    double* a;
};
struct A data = {
    (double[]) {1.1, 1.2, 1.3}
};
void f() {
    data.a[2] = 2.2;
    printf("%f\n", data.a[2]); // situation 1
}

int main() {
    f();
    printf("%f\n", data.a[2]); // situation 2
}

I'd like to know if the two labeled situations are undefined behaviors or not. I believe that situation 1 is not a undefined behavior (once I use data only inside f), but situation 2 actually is.

In the case of not being undefined behavior, if I change data.a[2] = 2.2; inside f to data.a = (double[]) {2.1, 2.2, 2.3};, I would get undefined behavior?

like image 428
João Paulo Avatar asked Feb 05 '26 15:02

João Paulo


1 Answers

I'd like to know if the two labeled situations are undefined behaviors or not. I believe that situation 1 is not a undefined behavior (once I use data only inside f),

C specifies the behavior of all the operators involved, and it has no restrictions on their use with the objects or sequence of events appearing in the example code. So the behavior is defined.

but situation 2 actually is.

C specifies the behavior of all the operators involved, and it has no restrictions on their use with the objects or sequence of events appearing in the example code. So the behavior is defined.

The object data is declared at file scope, so its lifetime spans the entire run of the program. Its one member is initialized with a pointer to the first element of an array expressed as a compound literal, and since that compound literal appears outside the body of any function, its lifetime, too, spans the entire run of the program. Furthermore, its type (in this case) is double[3], which is not const-qualified, so its elements may be assigned to.

In the case of not being undefined behavior, if I change data.a[2] = 2.2; inside f to data.a = (double[]) {2.1, 2.2, 2.3};, I would get undefined behavior?

Yes, in main(). A compound literal appearing inside a function body has automatic duration, so its lifetime ends no later than when the function returns. At that point, any pointers to or into it become indeterminate, and any attempt to dereference them (as main thereafter does) has undefined behavior.

like image 181
John Bollinger Avatar answered Feb 07 '26 07:02

John Bollinger