* Floare Augustin Theodor:
In “C The Complete Reference”, Herbert Schildt says: “Don't forget, a
const variable can be modified by something that is outside the
program. For example, a hardware device can set its own
value” (translated from the Romanian version)
I guess you're attempting some trolling-light by quoting Herbert Schildt, but as
it happens in this instance he's right, although only by virtue of making so
vague a statement that it's practically meaningless.
An originally const object can't have its value changed in a correct program.
If its value is changed then you have UB, which means all bets are off: one
reference to it may produce the original value, another the changed value.
So, it means that “const” counts only for the compiler, to check the
code for inconsistencies. But for the object code, the “const”
property is not present in any way, is it?
Constness can be present in the machine code in a number of ways.
First, the compiler may completely or partially optimize away an originally
const variable, as you discovered.
Second, the compiler may elect to place an originally const variable in read
only memory, so that write accesses are detected.
Third, although only of academic interest, a compiler may implement "fat
pointers" that keep information about whatever they refer to. Even in the
acedademic's wildest dreams this is usually limited to array bounds. But it
could in principle also include original constness of the referent.
“Undefined behavior” is a theory behind C++.
I'm sorry, no, it isn't.
It is a term defined by the C++ standard.
There are some other similar terms, like "unspecified behavior", and the
differences have to do with whether diagnostics are required, and whether the
behavior for any particular compiler needs to be documented.
The real implementation
can run in “undefined behavior” only if something wrong happened at
runtime.
Sorry, that's not the case.
For example, the second case of Undefined Behavior mentioned in the standard is
in §2.1/2, which notes that you have UB if a line continuation produces a
"universal-character-name" (like \u1234).
The UB says by definition that the standard then imposes no requirements on the
program results, or even on whether the compiler does produce an executable.
In short, from the formal point of view anything or nothing may happen.
In practice, with many cases of UB we still do have some expectations about
possible, practically reasonable behaviors. The stories about hate mails being
sent to presidents of superpowers, and nasal demons starting to fly out your
nose, not to mention the erasure of all Swedish pop music from Norwegian radio
stations (which might not be as catastrophic as it might sound (oops, I think
perhaps that was ambiguous)), are simply exaggerations. But even when you get
some reasonable result with some compiler, you can't count on it with other
compilers.
In this case, the program finishes its task, by printing the values
(the same result is for g++/Linux and Visual C++ 2008 Express Edition/
Windows). So, because the “undefined behavior” is the same on the two
compilers, it means that they implement the “undefined behavior” in
the same manner,
Sorry, no, it doesn't mean that.
It means they've produced programs that yield the same external effect.
The same external effect can be brought about in a zillion different ways.
by having a memory location with two different
values.
Sorry, no, and that's stupid.
A given memory location has only one value at a given time.
What happened in your case (I think it was your case, but I'm not going to check
back up the thread) was that you lied to the compiler, so the compiler optimized
away the actual use of a memory location: it used the value directly in the
machine code.
And because it is the same, it makes me say that the
implementors of compilers chose a “defined behavior” for an “undefined
behavior” case of the C++ theory.
Sorry, no, that conclusion does not follow.
They're allowed to defined the behavior in a case of formal UB, and one may rely
on such documented behavior in practice.
But the behavior is only defined if it's defined: by happenchance getting the
same external effect with two compilers does not make the behavior defined.
I hope that someone could come with an explanation for this result,
because I am not content with the “undefined behavior” solution.
Assuming by "solution" you mean "explanation": you should be content with that
, see above.
For otherwise you'll have to figure out where the behavior is documented, and
restrict yourself to use of that compiler, or those compilers.
Which is just a lot of work for no gain whatsoever.
Cheers & hth.,
- Alf