Is undefined behavior defined for consistency between compilers of the same program with the same compiler in the same environment?

Suppose my program contains a specific construct, which is the standard C ++ state for undefined behavior. This basically means that the implementation should do something reasonable, but it’s allowed not to document it. But is an implementation needed to create the same behavior every time it compiles a particular construct with undefined behavior or is it allowed to create different behaviors in different compilers?

What about undefined behavior? Let it pretend that my program contains a UB construct in accordance with the standard. Implementation allows you to display any behavior. But can this behavior differ between compilers of the same program in the same compiler with the same settings in the same environment? In other words, if I dereferenced the null pointer in line 78 in the X.cpp file and the implementation formats, then in this case, the disk will mean that it will do the same after recompiling the program?

Question ... I am compiling the same program with the same compiler in the same environment with the same compiler settings. Will the construction be indicated by undefined behavior, and undefined behavior spawns every identical behavior for each compiler, or are they allowed to distinguish between compilations?

0
c ++ compiler-construction
Jun 17 '10 at 8:10
source share
9 answers

Undefined behavior can vary between runs of the same program and even between execution of the same code in the same program run. For example, the value of an uninitialized (automatic) variable is undefined, and then its actual value is any value that appears in this place in memory. Obviously, this may change.

EDIT:

This also applies to unspecified behavior. For example, the order in which function arguments are evaluated is not specified, so if they have side effects, these side effects can occur in any order. It might print "Hello! Ho!" or "Ho! Hello!":

f( printf("Hi!"), printf("Ho!") ); 

This may vary by design. As the standard says: "Thus, an abstract machine instance can have more than one possible execution sequence for a given program and a given input." The difference is that with undefined behavior, anything can happen: the computer can explode, reformat the disk, or whatever. If unspecified, the computer cannot explode.

There is also implementation-defined behavior, such as the sizeof(int) value. It should be the same at all times for the same compiler.

+3
Jun 17 '10 at 8:17
source share
β€” -

If this behavior is undefined, then by the very nature of what will happen is undefined, you cannot rely on it to be the same under any circumstances.

On the other hand, nonspecific behavior is what remains for individual developers to decide how to implement if there is ambiguity in the language specification, for example. This will be consistent between compilers and starts, but not necessarily between different providers. So, for example, relying on unspecified behavior when you only create using Visual Studio, everything is fine, but if you try to port the code to gcc, it may lead to an error or lead to a different behavior than you expect.

+5
Jun 17 '10 at 8:16
source share

Unspecified behavior and undefined are not guaranteed by consistency between the individual runs of an already compiled program. This in itself makes the concept of consistency between individual compilers completely pointless.

In addition, it may be worth adding that undefined behavior can occur at the compilation stage, preventing the program from compiling at all.

+3
Jun 17 '10 at 8:21
source share

But can this behavior be different compiling the same program on the same compiler with the same settings in the same environment?

Yes.

In other words, if I play the null pointer on line 78 in the X.cpp file and the disk implementation formats in this case, does this mean that it will do the same after the program is recompiled?

The results of undefined behavior are almost always caused by code emitted by the compiler interacting with the operating system and / or hardware in ways not specified by the language developer. Therefore, if you cast a NULL pointer, what happens really has nothing to do with the compiler, but will depend on how the underlying operating system / hardware deals with invalid memory access. If the OS / hardware always deals with this sequentially (e.g. via a trap), you can expect UB to be consistent, but this has nothing to do with the language or the compiler.

+2
Jun 17 '10 at 8:27
source share

I do not know about unspecified behavior (but judging by the name, maybe he does the same bad / evil in everything that just no one knows what exactly he does). But for undefined behavior, I think it could behave VERY differently between platforms or compilers. I have seen some really weird coredumps on Solaris that haven't been seen on Ubuntu, etc.

+1
Jun 17 '10 at 8:13
source share

To specify it as undefined ... this means that it will not be told what will happen, either on another or on the same platform (with repeated tests).

+1
Jun 17 '10 at 8:16
source share

It is worth noting that the implementation of the specified behavior of C ++ Standard is not 100% identical among compilers, even today. Given this, it is not reasonable to expect that the behavior of undefined or undefined is an agnostic compiler. You have a better chance of writing portable code if you just stick to the standard.

+1
Jun 17 '10 at 8:16
source share

No, partly the reason for undefined / behavior-defined implementation exists in the standard. Undefined behavior cannot be the same between several compilers of the same source code on the same computer (say, with different optimization flags).

The committee clearly prefers well-defined behavior. The behavior defined by the implementation exists when the committee believes that there are several implementations for a concept, and there is no reason to prefer one after the other in all cases. Undefined behavior exists when a committee considers it too difficult to maintain promises in reasonable implementations.

In many cases, Undefined behavior is implemented as something without validation. The behavior then depends on the operating system, if any, and if it notices something less than kosher.

As an example, dereferencing memory that you are not is undefined. In general, the OS will kill your program if you do. However, if the stars are aligned to the right, you will be able to dereference a memory that you do not own in accordance with C ++ rules (for example, you have not received it from new , or already delete d it), but the OS believes that you own it. Sometimes you will crash, and sometimes you will just corrupt memory somewhere else in your program, and sometimes you will avoid undetected ones (if, for example, the memory has not been returned).

Race conditions are considered undefined, and they are known to be different during different program runs. You will probably have different settings each time you break the stack if your operating system has not noticed.

Double delete is undefined. They usually crash, but the fact that they are Undefined means that you cannot rely on what is happening.

+1
Jun 17 '10 at 8:21
source share

Many of these behaviors are implemented differently when compiled with different levels of optimization, with or without debug mode.

+1
Jun 17 '10 at 8:22
source share



All Articles