Is implementation-defined behavior required to be consistent between runs in C++?

懵懂的女人 提交于 2020-01-03 08:42:13

问题


Is a standard-conforming C++ implementation allowed to implement some behavior that is said to be implementation-defined in the standard in such way that it is different between different runs of the same compiled once program with the same input data?

For example, is an implementation allowed to say "the behavior is this on weekends and that otherwise" and implement behavior according to such statement?


回答1:


Of course, if the implementation documents when exactly the behavior changes with different runs, that's fine. Notice that the implementation-defined behavior is part of the parameters of the abstract machine:

The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine.

Certain aspects and operations of the abstract machine are described in this International Standard as implementation-defined (for example, sizeof(int)). These constitute the parameters of the abstract machine. Each implementation shall include documentation describing its characteristics and behavior in these respects. Such documentation shall define the instance of the abstract machine that corresponds to that implementation (referred to as the ‘‘corresponding instance’’ below).

This does not allow changing the behavior in a single run of the compiler. But between different runs of the compiler, the compiler may use a different corresponding abstract machine which differs by different implementation defined values, according to what the implementation defined. Command line parameters like -Wall (which changes the implementation-defined set of diagnostic messages) are the most common example of this. This is a difference to unspecified behavior in addition to the documentation requirements. Unspecified behavior is much less restrictive:

Certain other aspects and operations of the abstract machine are described in this International Standard as unspecified (for example, order of evaluation of arguments to a function). Where possible, this International Standard defines a set of allowable behaviors. These define the nondeterministic aspects of the abstract machine. An instance of the abstract machine can thus have more than one possible execution sequence for a given program and a given input.




回答2:


One example I can think of is if the program uses big or little endian representation for numbers. I believe that this would certainly count as implementation defined behaviour.

On some chips, for example certain ARM chips it's possible to switch modes at run time so you might want a compiler which could produce a program that would run in either mode meaning that you have implementation defined behaviour which could potentially be different on each run depending on external settings.

Similarly I guess you could write a compiler which produced both 32 ad 64 bit compiled of the same program - and the mode it executed could be determined at run time. Again, the documentation would have to say that ints were 32 bit or 64 bit depending on how you ran it.

To be honest I can't see anyone doing either of these things, but they both sound vaguely plausible examples of what you were asking for and I can't see why they wouldn't be legal under the standard as long as the documentation properly documented the nature of the system dependent behaviour.




回答3:


Implementation defined behavior means

Unspecified Behavior where each implementation documents how the choice is made

It is mandatory for the compiler writers to document the behaviour of a particular programming construct for a particular implementation.

.....in such way that it is different between different runs of the same compiled once program with the same input data?

Nopes!

For example, is an implementation allowed to say "the behavior is this on weekends and that otherwise" and implement behavior according to such statement?

I am not sure but I think the answer is no.




回答4:


IIRC, system() is required to exist, but given implementation defined behavior. Something like system("ls | grep foo") will naturally have different effects based on whether or not your system can execute something called ls, which might vary between runs. And, even on a fairly normal UNIX machine where ls and grep do what you would expect and aren't taken out, the result will still depend on the existence of a file with foo in the name, which will certainly be allowed to vary over time, and from where the program is executed, etc. It just depends on where you draw the line of "the same input data." If the machine is in a perfectly identical state then you can expect identical behavior, but no two runs will involve a machine truly in a pedantically identical state. (Even the temperature of the CPU in otherwise perfectly identical machines could result in some throttling behavior, which alters the winner of some race condition, which visibly results in different behavior of your program.)




回答5:


The guarantees are what the compiler has documented. Different compiler flags or different state of the computer at compile time might affect how the compiler/optimizer processes your program and that can have an effect on the result. With compiler flags having the greatest impact (the same compiler can be used to generate 32 and 64bit programs in a 64bit environment, in the two runs alignment requirements can differ).

You can expect that in most cases the implementor will provide some basic guarantees about the behavior of the implementation and the program it generates for a given set of compiler/linker parameters. Even if the load of the system can affect how much the optimizer can work on your program --some optimizers will be allocated some limited time-- that should not change the expected behavior.

Note that while there is no guarantee, it would be hard to market a compiler that produces code with different behaviors depending on unrelated parameters as the position of the moon relative to the stars.




回答6:


rand(3) in <stdlib.h> can be called from within C++, not sure how much of the C library is included in "standard C++", but surely there's some standards-conforming mechanism to generating random numbers.

time(3) in <time.h> returns the current time; same story with C++ and calling into the C library.



来源:https://stackoverflow.com/questions/3296523/is-implementation-defined-behavior-required-to-be-consistent-between-runs-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!