Undefined behaviour

R

Ron Natalie

Default User said:
Well, Ron said that but he was incorrect. I already quoted the C
standard on the issue. It's implementation-defined, not unspecified.
That means that an implementation has to select a behavior and document

I was only incorrect in saying that C said the behavior was unspecified. I have
since found that C99 has the same text that C++ does. The following text (this is from
C99, but it's essentially the same in C++):

An object shall have its stored value accessed only by an lvalue expression that has one of

the following types:73)

- a type compatible with the effective type of the object,

- a qualified version of a type compatible with the effective type of the object,

- a type that is the signed or unsigned type corresponding to the effective type of the

object,

- a type that is the signed or unsigned type corresponding to a qualified version of the

effective type of the object,

- an aggregate or union type that includes one of the aforementioned types among its

members (including, recursively, a member of a subaggregate or contained union), or

- a character type.
 
R

Ron Natalie

tom_usenet said:
I wouldn't like a library that implemented operator[] as at. I don't
want exceptions from undefined behaviour, since the throwing context
is lost.

What makes you think you won't get an exception anyhow. I can tell you
that on one very popular implementation, your undefined behavior will still
likely get mapped into an exception (it's just that it won't be std::eek:ut_of_range).

IMHO, any decent operator[] should at the very least have an assert in
it.

And this is an improvement over throwing how?
 
D

Default User

Ron said:
No, it does not. As a matter of fact, the passage you are quoting doesn't even exist
in C99.

Unless it was removed after the last draft was released, then yes it
does.

[#5] With one exception, if the value of a member of a union
object is used when the most recent store to the object was
to a different member, the behavior is
implementation-defined.70) One special guarantee is made in
order to simplify the use of unions: If a union contains
several structures that share a common initial sequence (see
below), and if the union object currently contains one of
these structures, it is permitted to inspect the common
initial part of any of them anywhere that a declaration of
the completed type of the union is visible. Two structures
share a common initial sequence if corresponding members
have compatible types (and, for bit-fields, the same widths)
for a sequence of one or more initial members.

6.2.6.1 / 7 specifically says it's unspecified what happens to bytes of other union members
not stored to. Other than that, the standard is mute (which makes it UNDEFINED behavior).

Please quote the actual text.
Further, 6.5 / 7 clearly makes it undefined behavior in C.

Again, please quote.

I'm not seeing what you are seeing.



Brian Rodenborn
 
D

Default User

I actually canceled this post and replaced it with another that didn't
say you were incorrect. Apparently it made it to your server anyway.
I was only incorrect in saying that C said the behavior was unspecified. I have
since found that C99 has the same text that C++ does. The following text (this is from
C99, but it's essentially the same in C++):

This has me curious now. I am going to stop discussing it here and bring
it up on comp.lang.c. I don't have an actual copy of the C99 standard,
as I don't work in it at this time, so my reading is from the final
committee draft.

Thanks for the input.



Brian Rodenborn
 
R

Rolf Magnus

Ron said:
tom_usenet said:
I wouldn't like a library that implemented operator[] as at. I don't
want exceptions from undefined behaviour, since the throwing context
is lost.

What makes you think you won't get an exception anyhow. I can tell
you that on one very popular implementation, your undefined behavior
will still likely get mapped into an exception (it's just that it
won't be std::eek:ut_of_range).

IMHO, any decent operator[] should at the very least have an assert
in it.

And this is an improvement over throwing how?

When debugging is switched off, no code is generated for the assert, so
it's faster. If you want an exception on buffer overflow, just use at()
instaead of operator[].
 
D

Duane Hebert

Rolf Magnus said:
It might be common, but it is abuse of unions. They were never meant for
such a thing, even if it works on many platforms. The way to do this is
reniterpret_cast.

I know that reinterpret_cast will work. Atcually in my case the
unsigned chars come from a volatile unsigned char[] so I have
to deal with that as well.

I just don't see how the union trick could not work on any platform
that I use. I was looking for an explanation as to why this would
be undefined. I could understand if it was implementation defined
or unspecified.

Thanks.
 
T

tom_usenet

tom_usenet said:
I wouldn't like a library that implemented operator[] as at. I don't
want exceptions from undefined behaviour, since the throwing context
is lost.

What makes you think you won't get an exception anyhow. I can tell you
that on one very popular implementation, your undefined behavior will still
likely get mapped into an exception (it's just that it won't be std::eek:ut_of_range).

You mean SEH type exceptions? In any case, they will only be thrown if
you access the memory incorrectly - if you access elements within the
capacity() of the vector, I imagine nothing is thrown.
IMHO, any decent operator[] should at the very least have an assert in
it.

And this is an improvement over throwing how?

The program stops immediately at the line in question in a debugger
(or provides a stack dump) even if you are "only" accessing
v[v.size()], yet there is no performance penalty in the release build.

Tom
 
R

Ron Natalie

Default User said:
Unless it was removed after the last draft was released, then yes it
does.
The stuff you are quoting does NOT appear in the C99 standard. It looks like this:

One special guarantee is made in order to simplify the use of unions: if a union contains
several structures that share a common initial sequence (see below), and if the union
object currently contains one of these structures, it is permitted to inspect the common
initial part of any of them anywhere that a declaration of the complete type of the union is
visible. Two structures share a common initial sequence if corresponding members have
compatible types (and, for bit-fields, the same widths) for a sequence of one or more
initial members.

Please stop telling me I'm wrong unless you are willing to bother to actually READ the
standard.
 
D

Default User

Ron Natalie wrote:

Please stop telling me I'm wrong unless you are willing to bother to actually READ the
standard.

Ron, I understand that and I canceled this message, replacing it with
another one where I said I'd take it up on CLC. I posted to CLC AND got
this answer already last week. Now, I understand there's no reason why
you have to read the group everyday, but if you aren't then it might be
good to read all messages before firing off replies.

You are right and I was wrong, done in by using the draft standard
rather than the real one.



Brian Rodenborn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,477
Latest member
ColumbusMa

Latest Threads

Top