Home > Enterprise >  Is it undefined behavior to access an array out of bounds if I know what data is at the accessed adr
Is it undefined behavior to access an array out of bounds if I know what data is at the accessed adr

Time:01-17

Imagine the following definition.

struct X {
    double a[8] {0.0};
    double b[8] {0.0};
}

int main() {
    X x;
    x.a[10] = 1.0;
}

Is the behavior of the program undefined when I access x.a[10]?

CodePudding user response:

Yes, it is undefined behavior, but not only because compiled may alter memory layout of X.

It is undefined behavior because the standard says so. As a result the compiler can do whatever with this code: the compiler can drop the assignment completely, can assign 1.0 to all the 16 elements, can crash the program, format your hard drive, etc.

CodePudding user response:

Yes. It's undefined behavior. Because the compiler could insert some padding between a and b. Il could also insert some padding after b. The only thing you can be sure of is that no padding will be put before a.

An interesting and very detailed description is provided in The Lost Art of Structure Packing.

CodePudding user response:

It is according to the "undefined behavior sanitizer" built into g /clang

runtime error: index 10 out of bounds for type 'double [8]'

i.e. the out of bounds access you're already worried about, is indeed UB. It's very very risky doing assumptions on memory layout and usually (even when you know what you're doing) the resulting code is not portable.

Demo

Notice in the demo, invocation of the checker happened with -fsanitize=undefined. We have great tools, let's use them.

Also notice that if you enable the memory checker, i.e. -fsanitize=address, no warning is emitted. That is to say, "just because it doesn't cause runtime memory problems it doesn't mean it's not UB".

CodePudding user response:

Your false premise is that out of bounds access would be defined, then of course it is ... not undefined. But it is not.

You assume that the two arrays are stored in adjacent memory directly next to each other and that pointer arithmetics works also beyond the bounds of an array. The first is not true in general and the second is false always.

Pointer arithmetics is only defined within the bounds of an array.

Your code has undefined behavior.


Note that your code is not instructions for your CPU. Your code is an abstract description of what the program should do. And x.a[10] simply has no meaning in the language. It is not defined. The compiler is not mandated to translate it to anything useful.

  • Related