473,320 Members | 2,104 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Undefined behaviour

Hi,

i heard a lot about "undefined behaviour" in this and other newsgroups
dealing with c/c++.

Is there a list where all cases with undefined behaviour in C++ are listed?

regards marbac
Jul 22 '05 #1
48 3018

"marbac" <ma****@chello.at> wrote in message
news:qh******************@news.chello.at...
Hi,

i heard a lot about "undefined behaviour" in this and other newsgroups
dealing with c/c++.

Is there a list where all cases with undefined behaviour in C++ are

listed?

I don't know of any compiled as a list.
But read the Holy Standard, it speaks a lot about undefined behaviors.

-Sharad
Jul 22 '05 #2

"marbac" <ma****@chello.at> wrote in message
news:qh******************@news.chello.at...
Hi,

i heard a lot about "undefined behaviour" in this and other newsgroups
dealing with c/c++.

Is there a list where all cases with undefined behaviour in C++ are listed?
regards marbac


It's called the C++ standard, and its several hundred pages long.

Off the top of my head here are a few common causes of undefined behaviour

1) dereferencing a null pointer
2) accessing outside the bounds of an array
3) deleting the same memory twice
4) dereferencing a pointer after it has been deleted
5) dereferencing a pointer which points to a destroyed object
6) accessing an uninitialised variable
7) signed integer overflow
8) modifying a const object

No doubt I've missed many others

As you can see several of the common causes of undefined behaviour involve
pointers. So the moral is don't use pointers, prefer STL classes instead,
they are somewhat safer.

john
Jul 22 '05 #3

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2l************@uni-berlin.de...

"marbac" <ma****@chello.at> wrote in message
news:qh******************@news.chello.at...
Hi,

i heard a lot about "undefined behaviour" in this and other newsgroups
dealing with c/c++.

Is there a list where all cases with undefined behaviour in C++ are

listed?

regards marbac


It's called the C++ standard, and its several hundred pages long.

Off the top of my head here are a few common causes of undefined behaviour

1) dereferencing a null pointer
2) accessing outside the bounds of an array
3) deleting the same memory twice
4) dereferencing a pointer after it has been deleted
5) dereferencing a pointer which points to a destroyed object
6) accessing an uninitialised variable
7) signed integer overflow
8) modifying a const object


Some more strike me -
1) main returning void
2) Copying a pointer after it has been deleted
3) Using mismatched forms of new/delete for arrays
4) Modifying a string literal
5) Changing a variable twice without a sequence point
6) Instantiating an STL container with auto_ptr
7) Adding declarations/definitions to std namespace
8) Playing around with reinterpret_cast

many more...

-Sharad

Jul 22 '05 #4
"John Harrison" <jo*************@hotmail.com> wrote in message
news:2l************@uni-berlin.de...
"marbac" <ma****@chello.at> wrote in message
news:qh******************@news.chello.at...
Is there a list where all cases with undefined behaviour in C++ are
listed?
.... Off the top of my head here are a few common causes of undefined behaviour .... 1) dereferencing a null pointer or any pointer to an address that has not been properly obtained ( i.e.
*(int*)454 = 0; ) 2) accessing outside the bounds of an array
3) deleting the same memory twice or calling delete on an object addresss that was not allocated with
new.
3b) Using delete[] to release memory allocated with new,
or delete on the address returned by new[]. 4) dereferencing a pointer after it has been deleted
5) dereferencing a pointer which points to a destroyed object
6) accessing an uninitialised variable or a variable that has been destroyed.
(NB: this also applies to global variables). 7) signed integer overflow
8) modifying a const object Two important additions I can think of:
9) modifying a variable twice between sequence points (or accessing the
value being modified).
e.g. a = ++i + ++i; or a = i + ++i;
10) deleting a derived class through a pointer to a base class whose
destructor is not virtual.

Off the top of my head too, I think that these would be the most common
causes, but I'm sure the list can be extended.

Furthermore, UB may be triggered by causing library functions
to perform one of the above actions, for example by passing an
insufficiently large or invalid output buffer to functions such as sprintf
or strcpy.
Some standard library functions have explicit restrictions on the parameters
they
can receive (e.g. calling memcpy with overlapping memory ranges).
So it is important, for writing correct code, to understand the behavior
and restrictions of the functions you are calling. And it's not an obvious
thing.
No doubt I've missed many others So do I...
The each of the C and C++ standards use the term "Undefined behavior"
close to 200 times, and an exaustive list is impossible to provide.
As you can see several of the common causes of undefined behaviour involve
pointers. So the moral is don't use pointers, prefer STL classes instead,
they are somewhat safer.

Overall, the C++ standard library does a better job than C's at trying to
prevent UB. What helps even more is if you are using an STL implementation
that
supports a 'debug' mode where all container iterators are checked at
runtime.
Some caveats I can think of include:
- initializing an std::string will a NULL char pointer.
- using [..] on standard containers (i.e. vector) does not verify range.
( vector::at() may be used instead, and will throw an exception ).
That's just adding my two cents, obviously my list is also partial and
incomplete...
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- e-mail contact form
Jul 22 '05 #5

"Ivan Vecerina" <NO**********************************@vecerina.com > skrev i
en meddelelse news:cd**********@newshispeed.ch...

[snip]
Some caveats I can think of include:
- initializing an std::string will a NULL char pointer.
- using [..] on standard containers (i.e. vector) does not verify range.
( vector::at() may be used instead, and will throw an exception ).
To be pedantic, nothing prevents vector::operator[] to be implemented as
vector::at. At least this is how I read the standard.
No doubt most libraries will not do so for performance reasons, of course.

/Peter

That's just adding my two cents, obviously my list is also partial and
incomplete...
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- e-mail contact form

Jul 22 '05 #6
Sharad Kala wrote:

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2l************@uni-berlin.de...

"marbac" <ma****@chello.at> wrote in message
news:qh******************@news.chello.at...
> Hi,
>
> i heard a lot about "undefined behaviour" in this and other
> newsgroups dealing with c/c++.
>
> Is there a list where all cases with undefined behaviour in C++ are listed?
>
> regards marbac


It's called the C++ standard, and its several hundred pages long.

Off the top of my head here are a few common causes of undefined
behaviour

1) dereferencing a null pointer
2) accessing outside the bounds of an array
3) deleting the same memory twice
4) dereferencing a pointer after it has been deleted
5) dereferencing a pointer which points to a destroyed object
6) accessing an uninitialised variable
7) signed integer overflow
8) modifying a const object


Some more strike me -
1) main returning void
2) Copying a pointer after it has been deleted


You could just combine a lot of the pointer stuff to:

Using the value of a pointer that doesn't point to a valid object.
3) Using mismatched forms of new/delete for arrays
4) Modifying a string literal
5) Changing a variable twice without a sequence point
Or changing and reading it
6) Instantiating an STL container with auto_ptr
7) Adding declarations/definitions to std namespace
8) Playing around with reinterpret_cast

many more...


1) Dividing by zero
2) Pointer arithmetic that crosses array bounds
3) Returning a reference or pointer to a local variable
4) Writing to a member of a union and then reading another one
5) Deleting a derived class object though a pointer to a base class that
has no virtual destructor
7) Using offsetof on a non-POD class/struct
8) Using a map/set with a comparison function with no strict/weak
ordering for the key type
9) Accessing vector members that don't exist
10)Using a container iterator after it has become invalid
Jul 22 '05 #7
On Tue, 13 Jul 2004 14:11:18 +0200, "Peter Koch Larsen"
<pk*****@mailme.dk> wrote:

"Ivan Vecerina" <NO**********************************@vecerina.com > skrev i
en meddelelse news:cd**********@newshispeed.ch...

[snip]
Some caveats I can think of include:
- initializing an std::string will a NULL char pointer.
- using [..] on standard containers (i.e. vector) does not verify range.
( vector::at() may be used instead, and will throw an exception ).


To be pedantic, nothing prevents vector::operator[] to be implemented as
vector::at. At least this is how I read the standard.
No doubt most libraries will not do so for performance reasons, of course.


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.

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

Tom
Jul 22 '05 #8
"marbac" <ma****@chello.at> wrote in message
news:qh******************@news.chello.at...
Hi,

i heard a lot about "undefined behaviour" in this and other newsgroups
dealing with c/c++.

Is there a list where all cases with undefined behaviour in C++ are listed?
regards marbac


I don't think it's really possible to compile a list. Think about it this
way: everything you could possibly do wrong that your compiler won't catch
is undefined behavior. Hence, what you're asking for is really a
compilation of all errors which could possibly be made in writing code,
which, unfortunately, is unlikely to exist anywhere, and would probably be
useless to you even if it did.
Jul 22 '05 #9
>Writing to a member of a union and then reading another one

Are you sure?

Certainly it seems as though it is a logic error which could possibly result in
undefined behavior, but is it guaranteed undefined behavior?

<CODE>

union FooBar
{
int Foo;
char Bar;
};

int main()
{

FooBar fooBar;

fooBar.Foo = 32; //Write FooBar::Foo

char bar = fooBar.Bar; //Oops! Read FooBar::Bar

return 0;
}

</CODE>

This code could results in the "rewrite your harddrive and sleep with your
girlfriend" kind of undefined behavior?

For that to happen wouldn't the compiler have to keep track of the last member
written to for each instance of a union so that it would be able to recognize
mismatched reads?

Just curious.
Jul 22 '05 #10
DaKoadMunky posted:
Writing to a member of a union and then reading another
one
Are you sure?

Certainly it seems as though it is a logic error which could possibly result in undefined behavior, but is it guaranteed undefined behavior?
<CODE>

union FooBar
{
int Foo;
char Bar;
};

int main()
{

FooBar fooBar;

fooBar.Foo = 32; //Write FooBar::Foo

char bar = fooBar.Bar; //Oops! Read FooBar::Bar

return 0;
}

</CODE>

This code could results in the "rewrite your harddrive and sleep with your girlfriend" kind of undefined behavior?

For that to happen wouldn't the compiler have to keep track of the last member written to for each instance of a union so that it would be able to recognize mismatched reads?

Just curious.


Well the only thing *I* can think of that could make that
do anything weird is if by editing that particular byte of
the int, that the value you're left with is invalid; but
then can you even have an invalid bit pattern for an int?
Common sense says no, but maybe the almighty Standard
doesn't give any guarantees that there isn't.

-JKop
Jul 22 '05 #11

"JKop" <NU**@NULL.NULL> wrote in message news:nA*****************@news.indigo.ie...
DaKoadMunky posted:
Writing to a member of a union and then reading another

one

Are you sure?

Certainly it seems as though it is a logic error which

could possibly
result in undefined behavior, but is it guaranteed

undefined behavior?


Conversion by union can be a disaster. Been there, done that. The BSD kernel used
to have a union that essentially looked like this:

union u {
char* c;
short* s;
int* i;
long* l;
};

and used to be loosy goosy vax and store into one field and read back from another.

This was fine until we were porting to a machine that encodes the operand size in
the low order bits of the pointer. That led to some fun hunting.
Jul 22 '05 #12
marbac wrote:
Hi,

i heard a lot about "undefined behaviour" in this and other newsgroups
dealing with c/c++.

Is there a list where all cases with undefined behaviour in C++ are listed?



"1.3.12 undefined behavior

behavior, such as might arise upon use of an erroneous program construct
or erroneous data, for which this International Standard imposes no
requirements. Undefined behavior may also be expected when this
International Standard omits the description of any explicit definition
of behavior. [Note: permissible undefined behavior ranges from ignoring
the situation completely with unpredictable results, to behaving during
translation or program execution in a documented manner characteristic
of the environment (with or without the issuance of a diagnostic
message), to terminating a translation or execution (with the issuance
of a diagnostic message). Many erroneous program constructs do not
engender undefined behavior; they are required to be diagnosed. ]"


Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #13
Rolf Magnus wrote:
4) Writing to a member of a union and then reading another one

This is implementation-defined in C. I'd be surprised if it was
different in C++.


Brian Rodenborn
Jul 22 '05 #14

"Default User" <fi********@boeing.com.invalid> wrote in message news:40**************@boeing.com.invalid...
Rolf Magnus wrote:
4) Writing to a member of a union and then reading another one

This is implementation-defined in C. I'd be surprised if it was
different in C++.

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

Jul 22 '05 #15
"Sharad Kala" <no******************@yahoo.com> wrote:
"John Harrison" <jo*************@hotmail.com> wrote:
"marbac" <ma****@chello.at> wrote:
Is there a list where all cases with undefined behaviour in C++ are
listed?
1) dereferencing a null pointer
2) accessing outside the bounds of an array
3) deleting the same memory twice
4) dereferencing a pointer after it has been deleted
5) dereferencing a pointer which points to a destroyed object
6) accessing an uninitialised variable
7) signed integer overflow
8) modifying a const object


Some more strike me -
2) Copying a pointer after it has been deleted


Exactly the same as John's #6 (the standard-ese term is "indeterminate")
4) Modifying a string literal


Same as John's #8 (string literals have type "char const []")
Jul 22 '05 #16
Ron Natalie wrote:

"Default User" <fi********@boeing.com.invalid> wrote in message news:40**************@boeing.com.invalid...
Rolf Magnus wrote:
4) Writing to a member of a union and then reading another one

This is implementation-defined in C. I'd be surprised if it was
different in C++.

C says it's unspecified, there is no need for the implementation to have a specific
behavior.


Ah, no. From the 89 standard:

With one exception, if a member of a union object is accessed after
a value has been stored in a different member of the object, the
behavior is implementation-defined./33/ 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, and if the union
object currently contains one of these structures, it is permitted to
inspect the common initial part of any of them. Two structures share
a common initial sequence if corresponding members have compatible
types for a sequence of one or more initial members.

33. The ``byte orders'' for scalar types are invisible to isolated
programs that do not indulge in type punning (for example, by
assigning to one member of a union and inspecting the storage by
accessing another member that is an appropriately sized array of
character type), but must be accounted for when conforming to
externally-imposed storage layouts.
The C99 standard says virtually the same thing.

In the general case, it's undefined behavior for C++ (there are some
specific outs).

Could you quote the standard on that?

Brian Rodenborn
Jul 22 '05 #17

"tom_usenet" <to********@hotmail.com> skrev i en meddelelse
news:a7********************************@4ax.com...
On Tue, 13 Jul 2004 14:11:18 +0200, "Peter Koch Larsen"
<pk*****@mailme.dk> wrote:

"Ivan Vecerina" <NO**********************************@vecerina.com > skrev ien meddelelse news:cd**********@newshispeed.ch...

[snip]
Some caveats I can think of include:
- initializing an std::string will a NULL char pointer.
- using [..] on standard containers (i.e. vector) does not verify range. ( vector::at() may be used instead, and will throw an exception ).
To be pedantic, nothing prevents vector::operator[] to be implemented as
vector::at. At least this is how I read the standard.
No doubt most libraries will not do so for performance reasons, of

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

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

Tom


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

/Peter
Jul 22 '05 #18
Peter Koch Larsen wrote:
You're right of course. My point was that vector::operator[] 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.

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
Jul 22 '05 #19
Ioannis Vranos wrote:
Peter Koch Larsen wrote:
You're right of course. My point was that vector::operator[] 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,


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".
and code assuming that this operator is index-checked, cannot be
considered portable.
That's of course true, and this is exactly the reason why there is at().
Furthermore, since at() is provided for this, operator[] is reasonable
to be defined having an efficient access to the data.


Yes.

Jul 22 '05 #20
Rolf Magnus wrote:
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
Jul 22 '05 #21

"Ron Natalie" <ro*@sensor.com> wrote in message news:40***********************@news.newshosting.co m...

"Default User" <fi********@boeing.com.invalid> wrote in message news:40**************@boeing.com.invalid...
Rolf Magnus wrote:
4) Writing to a member of a union and then reading another one

This is implementation-defined in C. I'd be surprised if it was
different in C++.

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?
Jul 22 '05 #22
Duane Hebert wrote:
"Ron Natalie" <ro*@sensor.com> wrote in message news:40***********************@news.newshosting.co m...
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
Jul 22 '05 #23

"Ioannis Vranos" <iv*@guesswh.at.grad.com> wrote in message news:cd***********@ulysses.noc.ntua.gr...
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 ...
Jul 22 '05 #24
Duane Hebert wrote:
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.

Jul 22 '05 #25

"Ioannis Vranos" <iv*@guesswh.at.grad.com> skrev i en meddelelse
news:cd***********@ulysses.noc.ntua.gr...
Peter Koch Larsen wrote:
You're right of course. My point was that vector::operator[] 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

Jul 22 '05 #26
Peter Koch Larsen wrote:

"Ioannis Vranos" <iv*@guesswh.at.grad.com> skrev i en meddelelse
news:cd***********@ulysses.noc.ntua.gr...
Peter Koch Larsen wrote:
> You're right of course. My point was that vector::operator[] 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.

Jul 22 '05 #27

"Rolf Magnus" <ra******@t-online.de> skrev i en meddelelse
news:cd*************@news.t-online.com...
Peter Koch Larsen wrote:

"Ioannis Vranos" <iv*@guesswh.at.grad.com> skrev i en meddelelse
news:cd***********@ulysses.noc.ntua.gr...
Peter Koch Larsen wrote:

> You're right of course. My point was that vector::operator[] 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
Jul 22 '05 #28
Duane Hebert wrote:

"Ron Natalie" <ro*@sensor.com> wrote in message news:40***********************@news.newshosting.co m...

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:


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
Jul 22 '05 #29
Duane Hebert wrote:

"Ron Natalie" <ro*@sensor.com> wrote in message news:40***********************@news.newshosting.co m...
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:

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
Jul 22 '05 #30
Duane Hebert wrote:
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
Jul 22 '05 #31
Default User wrote:
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
Jul 22 '05 #32
Peter Koch Larsen wrote:
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
Jul 22 '05 #33
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
Jul 22 '05 #34
Ioannis Vranos wrote:
Peter Koch Larsen wrote:
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?

Jul 22 '05 #35
Rolf Magnus wrote:
Ioannis Vranos wrote:
Peter Koch Larsen wrote:
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
Jul 22 '05 #36
Ioannis Vranos wrote:
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
Jul 22 '05 #37
Rolf Magnus wrote:
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
Jul 22 '05 #38

"Default User" <fi********@boeing.com.invalid> wrote in message news:40***************@boeing.com.invalid...

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.
In the general case, it's undefined behavior for C++ (there are some
specific outs).


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

Jul 22 '05 #39

"Default User" <fi********@boeing.com.invalid> wrote in message news:40***************@boeing.com.invalid...
Duane Hebert wrote:

"Ron Natalie" <ro*@sensor.com> wrote in message news:40***********************@news.newshosting.co m...

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:


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.

Jul 22 '05 #40

"Duane Hebert" <sp**@flarn2.com> wrote in message news:70**********************@weber.videotron.net. ..

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.

Jul 22 '05 #41

"tom_usenet" <to********@hotmail.com> wrote in message news:a7********************************@4ax.com...
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::out_of_range).

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


And this is an improvement over throwing how?
Jul 22 '05 #42
Ron Natalie wrote:

"Default User" <fi********@boeing.com.invalid> wrote in message news:40***************@boeing.com.invalid...

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.


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
Jul 22 '05 #43
Ron Natalie wrote:

"Default User" <fi********@boeing.com.invalid> wrote in message news:40***************@boeing.com.invalid...
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 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
Jul 22 '05 #44
Ron Natalie wrote:

"tom_usenet" <to********@hotmail.com> wrote in message
news:a7********************************@4ax.com...
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::out_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[].

Jul 22 '05 #45

"Rolf Magnus" <ra******@t-online.de> wrote in message news:cd*************@news.t-online.com...
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.
Jul 22 '05 #46
On Fri, 16 Jul 2004 14:25:38 -0400, "Ron Natalie" <ro*@sensor.com>
wrote:

"tom_usenet" <to********@hotmail.com> wrote in message news:a7********************************@4ax.com...
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::out_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
Jul 22 '05 #47

"Default User" <fi********@boeing.com.invalid> wrote in message news:40***************@boeing.com.invalid...
Ron Natalie wrote:

"Default User" <fi********@boeing.com.invalid> wrote in message news:40***************@boeing.com.invalid...

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.


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.

Jul 22 '05 #48
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
Jul 22 '05 #49

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Simon Bailey | last post by:
In the following code at the end of the program z = 20 & y = 99. void doit(const int* x) { int* nonconst; nonconst = const_cast<int*>(x); *nonconst = 99; } int main(int argc, char* argv)
8
by: Scott J. McCaughrin | last post by:
The following program compiles fine but elicits this message from the linker: "undefined reference to VarArray::funct" and thus fails. It seems to behave as if the static data-member:...
8
by: Joona I Palaste | last post by:
We all know that this: void *p; if (p=malloc(1)) { free(p); p; } causes undefined behaviour if malloc() succeeds. But what about this?
25
by: Nitin Bhardwaj | last post by:
Well, i'm a relatively new into C( strictly speaking : well i'm a student and have been doing & studying C programming for the last 4 years).....and also a regular reader of "comp.lang.c" I...
23
by: Ken Turkowski | last post by:
The construct (void*)(((long)ptr + 3) & ~3) worked well until now to enforce alignment of the pointer to long boundaries. However, now VC++ warns about it, undoubtedly to help things work on 64...
12
by: RoSsIaCrIiLoIA | last post by:
On Mon, 07 Feb 2005 21:28:30 GMT, Keith Thompson <kst-u@mib.org> wrote: >"Romeo Colacitti" <wwromeo@gmail.com> writes: >> Chris Torek wrote: >>> In article <4205BD5C.6DC8@mindspring.com> >>>...
26
by: Frederick Gotham | last post by:
I have a general idea of the different kinds of behaviour described by the C Standard, such as: (1) Well-defined behaviour: int a = 2, b = 3; int c = a + b; (Jist: The code will work...
12
by: Franz Hose | last post by:
the following program, when compiled with gcc and '-std=c99', gcc says test.c:6: error: jump into scope of identifier with variably modified type that is, it does not even compile. ...
10
by: subramanian100in | last post by:
Consider the following code: #include <iostream> #include <cstdlib> using namespace std; int main() { const double& ref = 100;
33
by: coolguyaroundyou | last post by:
Will the following statement invoke undefined behavior : a^=b,b^=a,a^=b ; given that a and b are of int-type ?? Be cautious, I have not written a^=b^=a^=b ; which, of course, is undefined....
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.