Undefined behaviour

I

Ioannis Vranos

Rolf said:
If an implementation of vector's operator[]() threw an out_of_range
exception or anything else, it would be a system-specific extension,


It would be an instance of undefined behaviour, just like a crash would
be. Still you would probably not call a crash a "system-specific
extension".


The system-specific extension I was talking about above, was the fact of
throwing an exception.






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
D

Duane Hebert

Ron Natalie said:
C says it's unspecified, there is no need for the implementation to have a specific
behavior. In the general case, it's undefined behavior for C++ (there are some
specific outs).

I've heard this before but you mean basically that:

union spoo {
unsigned char c[sizeof(short)];
short s;
};

spoo doh;
doh.c[0] = LOW_BYTE;
doh.c[1] = HIGH_BYTE;

cout << doh.s ;


is undefined?
This is a common method to interpret unsigned char
data from I/O devices. I know it can be done without
a union but not as cleanly. I don't see how this could
not work (as long as you are aware of the endianness
of the unsigned chars etc.)

Any thoughts? At any rate, what would be the purpose
of a union?
 
I

Ioannis Vranos

Duane said:
I've heard this before but you mean basically that:

union spoo {
unsigned char c[sizeof(short)];
short s;
};

spoo doh;
doh.c[0] = LOW_BYTE;
doh.c[1] = HIGH_BYTE;

cout << doh.s ;


is undefined?
This is a common method to interpret unsigned char
data from I/O devices. I know it can be done without
a union but not as cleanly. I don't see how this could
not work (as long as you are aware of the endianness
of the unsigned chars etc.)

Any thoughts? At any rate, what would be the purpose
of a union?


Strictly speaking reading doh.s which was not properly assigned a value
is undefined behaviour.


Well union comes from C, and systems in the past had very severe space
constraints, so for example you could use a union in half a program as
an integer and then as a float. :)






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
D

Duane Hebert

Ioannis Vranos said:
Strictly speaking reading doh.s which was not properly assigned a value
is undefined behaviour.

But the union shares the memory between the unsigned char[2] and the
short. The unsigned char was assigned a value, reading the short
after is just interpreting the same memory as a short no?
Well union comes from C, and systems in the past had very severe space
constraints, so for example you could use a union in half a program as
an integer and then as a float. :)

True. It's been a while though ...
 
R

Rolf Magnus

Duane said:
I've heard this before but you mean basically that:

union spoo {
unsigned char c[sizeof(short)];
short s;
};

spoo doh;
doh.c[0] = LOW_BYTE;
doh.c[1] = HIGH_BYTE;

cout << doh.s ;


is undefined?
This is a common method to interpret unsigned char
data from I/O devices.

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.
 
P

Peter Koch Larsen

Ioannis Vranos said:
Peter said:
You're right of course. My point was that vector::eek:perator[] is allowed to
verify the range. The assert is an excellent solution.



If an implementation of vector's operator[]() threw an out_of_range
exception or anything else, it would be a system-specific extension, and
code assuming that this operator is index-checked, cannot be considered
portable.

No it would not. Elsewhere in this thread you have quoted the standard on
undefined behaviour - read it and tell me if you find an assert or a throw
kochs_exception would violate the standard.

/Peter
Furthermore, since at() is provided for this, operator[] is reasonable
to be defined having an efficient access to the data.






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
R

Rolf Magnus

Peter said:
Ioannis Vranos said:
Peter said:
You're right of course. My point was that vector::eek:perator[] is
allowed to
verify the range. The assert is an excellent solution.



If an implementation of vector's operator[]() threw an out_of_range
exception or anything else, it would be a system-specific extension,
and code assuming that this operator is index-checked, cannot be
considered portable.

No it would not. Elsewhere in this thread you have quoted the standard
on undefined behaviour - read it and tell me if you find an assert or
a throw kochs_exception would violate the standard.

I agree that I wouldn't call it a system-specific extension. Throwing an
exception is just as much of a system specific extension as crashing
and output like "segmentation fault, core dumped" or just ignoring the
faulty access.
But he's right in that depending on an exception being thrown is
non-portable. Depending on any specific behaviour when doing something
that - according to the standard - invokes undefined behaviour is
non-portable.
 
P

Peter Koch Larsen

Rolf Magnus said:
Peter said:
Ioannis Vranos said:
Peter Koch Larsen wrote:

You're right of course. My point was that vector::eek:perator[] is
allowed to
verify the range. The assert is an excellent solution.



If an implementation of vector's operator[]() threw an out_of_range
exception or anything else, it would be a system-specific extension,
and code assuming that this operator is index-checked, cannot be
considered portable.

No it would not. Elsewhere in this thread you have quoted the standard
on undefined behaviour - read it and tell me if you find an assert or
a throw kochs_exception would violate the standard.

I agree that I wouldn't call it a system-specific extension. Throwing an
exception is just as much of a system specific extension as crashing
and output like "segmentation fault, core dumped" or just ignoring the
faulty access.
But he's right in that depending on an exception being thrown is
non-portable. Depending on any specific behaviour when doing something
that - according to the standard - invokes undefined behaviour is
non-portable.

I fully agree. This is not something you can rely on, but it can be handy
while developing your application. Debug it on a platform that checks for
invalid accesses and it helps you a little before deplying your platform on
your final target.

/Peter
 
D

Default User

Duane said:
I've heard this before but you mean basically that:

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
it.



Brian Rodenborn
 
D

Default User

Duane said:
I've heard this before but you mean basically that:


Well, I think what Ron said was somewhat confusing. I already quoted the
C standard on the issue. It's implementation-defined, that means that
the standard doesn't impose any behavior, but the implementation has to
select a behavior and document it. So the behavior for a user is not
unspecified, you can check your documentation.

There's also the bit about the union members being structs with common
initial sequences.


union spoo {
unsigned char c[sizeof(short)];
short s;
};

spoo doh;
doh.c[0] = LOW_BYTE;
doh.c[1] = HIGH_BYTE;

cout << doh.s ;

is undefined?

Not in C. Some have said that is so in C++, but I haven't seen a quote
from the standard. Usually these things are the same between the
languages, but sometimes not. Obviously, the fact that all data is POD
in C but not in C++ may well be a factor.
This is a common method to interpret unsigned char
data from I/O devices. I know it can be done without
a union but not as cleanly. I don't see how this could
not work (as long as you are aware of the endianness
of the unsigned chars etc.)

It likely would. That doesn't mean it's guaranteed. You can do the same
thing by casting a pointer to the object to a pointer to unsigned char,
then access the bytes that way. That is standard.
Any thoughts? At any rate, what would be the purpose
of a union?

These days, very little. I haven't used a union in anger since the DOS
days.



Brian Rodenborn




Brian Rodenborn
 
I

Ioannis Vranos

Duane said:
But the union shares the memory between the unsigned char[2] and the
short. The unsigned char was assigned a value, reading the short
after is just interpreting the same memory as a short no?


Yes but the standard says:

"In a union, at most one of the data members can be active at any time,
that is, the value of at most one of the data members can be stored in a
union at any time."



So an implementer may choose to do weird magic in the implementation of
a union. In other words, it is not a well-defined behaviour.






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
I

Ioannis Vranos

Default said:
Well, I think what Ron said was somewhat confusing. I already quoted the
C standard on the issue. It's implementation-defined, that means that
the standard doesn't impose any behavior, but the implementation has to
select a behavior and document it. So the behavior for a user is not
unspecified, you can check your documentation.

There's also the bit about the union members being structs with common
initial sequences.

Not in C. Some have said that is so in C++, but I haven't seen a quote
from the standard. Usually these things are the same between the
languages, but sometimes not. Obviously, the fact that all data is POD
in C but not in C++ may well be a factor.



You are making a mistake. Here we are talking about C++ and not C. :)






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
I

Ioannis Vranos

Peter said:
No it would not. Elsewhere in this thread you have quoted the standard on
undefined behaviour - read it and tell me if you find an assert or a throw
kochs_exception would violate the standard.


If a standard library implementation performs range checking in vector's
operator[]() and throws an exception in case of out of range, isn't this
a platform-specific extension?






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
I

Ioannis Vranos

Rolf Magnus wrote:

I agree that I wouldn't call it a system-specific extension. Throwing an
exception is just as much of a system specific extension as crashing
and output like "segmentation fault, core dumped" or just ignoring the
faulty access.


I was not talking about a system-specific *behaviour*, but a system
specific *extension*, like WinMain() for example.






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
D

Default User

Ioannis said:
You are making a mistake. Here we are talking about C++ and not C. :)


I am not making a mistake. I responded to the reply to Ron Natalie's
assertions about C. I specifically said that it may be different in C++.
Try to keep up.



Brian Rodenborn
 
R

Rolf Magnus

Ioannis said:
Peter said:
No it would not. Elsewhere in this thread you have quoted the
standard on undefined behaviour - read it and tell me if you find an
assert or a throw kochs_exception would violate the standard.


If a standard library implementation performs range checking in
vector's operator[]() and throws an exception in case of out of range,
isn't this a platform-specific extension?

No, it isn't. If the behaviour is undefined, anything can happen from
the standard point of view, and "anything" includes an exception being
thrown, the program crashing or the computer exploding. So the
implementation does just what the standard says it should do.
Which behaviour would not be an "extension" for you?
 
K

Kai-Uwe Bux

Rolf said:
Ioannis said:
Peter said:
No it would not. Elsewhere in this thread you have quoted the
standard on undefined behaviour - read it and tell me if you find an
assert or a throw kochs_exception would violate the standard.


If a standard library implementation performs range checking in
vector's operator[]() and throws an exception in case of out of range,
isn't this a platform-specific extension?

No, it isn't. If the behaviour is undefined, anything can happen from
the standard point of view, and "anything" includes an exception being
thrown, the program crashing or the computer exploding. So the
implementation does just what the standard says it should do.
Which behaviour would not be an "extension" for you?

Whether something is an extension is not answered by the standard but by
the vendor of my compiler/library. If the documentation of the vector class
in a particular library implementation advertises that an exception will be
thrown for out of range indices, then I would call it an extension.


Best

Kai-Uwe Bux
 
I

Ioannis Vranos

Rolf said:
No, it isn't. If the behaviour is undefined, anything can happen from
the standard point of view, and "anything" includes an exception being
thrown, the program crashing or the computer exploding. So the
implementation does just what the standard says it should do.
Which behaviour would not be an "extension" for you?



Yes, accessing a vector out of range causes undefined behaviour, which
includes a throwing of an exception, which would be a system-specific
extension provided it is documented in the implementer's documentation.






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
 
R

Ron Natalie

Default User said:
The C99 standard says virtually the same thing.

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

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).

Further, 6.5 / 7 clearly makes it undefined behavior in C.

6.5 / 7 of C99 appears almost word for word as 5 / 9 in the C++ standard.

I was wrong, it's undefined behavior in both languages (in most cases).
 
R

Ron Natalie

Duane Hebert said:
union spoo {
unsigned char c[sizeof(short)];
short s;
};

spoo doh;
doh.c[0] = LOW_BYTE;
doh.c[1] = HIGH_BYTE;

cout << doh.s ;


is undefined?

Yes, but the reverse is not. You're allowed to alias things to char (or unsigned char) arrays, but not
the other way around.
 

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
473,774
Messages
2,569,596
Members
45,144
Latest member
KetoBaseReviews
Top