Connecting Tech Pros Worldwide Forums | Help | Site Map

Undefined behaviour

marbac
Guest
 
Posts: n/a
#1: Jul 22 '05
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



Sharad Kala
Guest
 
Posts: n/a
#2: Jul 22 '05

re: Undefined behaviour



"marbac" <marbac@chello.at> wrote in message
news:qhOIc.60916$Q74.3555@news.chello.at...[color=blue]
> 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[/color]
listed?

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

-Sharad


John Harrison
Guest
 
Posts: n/a
#3: Jul 22 '05

re: Undefined behaviour



"marbac" <marbac@chello.at> wrote in message
news:qhOIc.60916$Q74.3555@news.chello.at...[color=blue]
> 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[/color]
listed?[color=blue]
>
> regards marbac[/color]

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


Sharad Kala
Guest
 
Posts: n/a
#4: Jul 22 '05

re: Undefined behaviour



"John Harrison" <john_andronicus@hotmail.com> wrote in message
news:2lhr06Fck27jU1@uni-berlin.de...[color=blue]
>
> "marbac" <marbac@chello.at> wrote in message
> news:qhOIc.60916$Q74.3555@news.chello.at...[color=green]
> > 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[/color]
> listed?[color=green]
> >
> > regards marbac[/color]
>
> 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[/color]

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



Ivan Vecerina
Guest
 
Posts: n/a
#5: Jul 22 '05

re: Undefined behaviour


"John Harrison" <john_andronicus@hotmail.com> wrote in message
news:2lhr06Fck27jU1@uni-berlin.de...[color=blue]
> "marbac" <marbac@chello.at> wrote in message
> news:qhOIc.60916$Q74.3555@news.chello.at...[color=green]
> > Is there a list where all cases with undefined behaviour in C++ are
> > listed?[/color][/color]
....[color=blue]
> Off the top of my head here are a few common causes of undefined behaviour[/color]
....[color=blue]
> 1) dereferencing a null pointer[/color]
or any pointer to an address that has not been properly obtained ( i.e.
*(int*)454 = 0; )[color=blue]
> 2) accessing outside the bounds of an array
> 3) deleting the same memory twice[/color]
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[].[color=blue]
> 4) dereferencing a pointer after it has been deleted
> 5) dereferencing a pointer which points to a destroyed object
> 6) accessing an uninitialised variable[/color]
or a variable that has been destroyed.
(NB: this also applies to global variables).[color=blue]
> 7) signed integer overflow
> 8) modifying a const object[/color]
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.
[color=blue]
> No doubt I've missed many others[/color]
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.
[color=blue]
> 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.[/color]
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


Peter Koch Larsen
Guest
 
Posts: n/a
#6: Jul 22 '05

re: Undefined behaviour



"Ivan Vecerina" <NOT_VALID_please_use_contact_webform@vecerina.com > skrev i
en meddelelse news:cd0i4d$7v1$1@newshispeed.ch...

[snip]
[color=blue]
> 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 ).[/color]

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[color=blue]
>
>
> 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
>
>[/color]


Rolf Magnus
Guest
 
Posts: n/a
#7: Jul 22 '05

re: Undefined behaviour


Sharad Kala wrote:
[color=blue]
>
> "John Harrison" <john_andronicus@hotmail.com> wrote in message
> news:2lhr06Fck27jU1@uni-berlin.de...[color=green]
>>
>> "marbac" <marbac@chello.at> wrote in message
>> news:qhOIc.60916$Q74.3555@news.chello.at...[color=darkred]
>> > 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[/color]
>> listed?[color=darkred]
>> >
>> > regards marbac[/color]
>>
>> 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[/color]
>
> Some more strike me -
> 1) main returning void
> 2) Copying a pointer after it has been deleted[/color]

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.
[color=blue]
> 3) Using mismatched forms of new/delete for arrays
> 4) Modifying a string literal
> 5) Changing a variable twice without a sequence point[/color]

Or changing and reading it
[color=blue]
> 6) Instantiating an STL container with auto_ptr
> 7) Adding declarations/definitions to std namespace
> 8) Playing around with reinterpret_cast
>
> many more...[/color]

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


tom_usenet
Guest
 
Posts: n/a
#8: Jul 22 '05

re: Undefined behaviour


On Tue, 13 Jul 2004 14:11:18 +0200, "Peter Koch Larsen"
<pklspam@mailme.dk> wrote:
[color=blue]
>
>"Ivan Vecerina" <NOT_VALID_please_use_contact_webform@vecerina.com > skrev i
>en meddelelse news:cd0i4d$7v1$1@newshispeed.ch...
>
>[snip]
>[color=green]
>> 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 ).[/color]
>
>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.[/color]

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
Aguilar, James
Guest
 
Posts: n/a
#9: Jul 22 '05

re: Undefined behaviour


"marbac" <marbac@chello.at> wrote in message
news:qhOIc.60916$Q74.3555@news.chello.at...[color=blue]
> 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[/color]
listed?[color=blue]
>
> regards marbac[/color]

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.


DaKoadMunky
Guest
 
Posts: n/a
#10: Jul 22 '05

re: Undefined behaviour


>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.
JKop
Guest
 
Posts: n/a
#11: Jul 22 '05

re: Undefined behaviour


DaKoadMunky posted:
[color=blue][color=green]
>>Writing to a member of a union and then reading another[/color][/color]
one[color=blue]
>
> Are you sure?
>
> Certainly it seems as though it is a logic error which[/color]
could possibly[color=blue]
> result in undefined behavior, but is it guaranteed[/color]
undefined behavior?[color=blue]
>
><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[/color]
and sleep with[color=blue]
> your girlfriend" kind of undefined behavior?
>
> For that to happen wouldn't the compiler have to keep[/color]
track of the last[color=blue]
> member written to for each instance of a union so that it[/color]
would be able[color=blue]
> to recognize mismatched reads?
>
> Just curious.[/color]

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
Ron Natalie
Guest
 
Posts: n/a
#12: Jul 22 '05

re: Undefined behaviour



"JKop" <NULL@NULL.NULL> wrote in message news:nAXIc.4516$Z14.5338@news.indigo.ie...[color=blue]
> DaKoadMunky posted:
>[color=green][color=darkred]
> >>Writing to a member of a union and then reading another[/color][/color]
> one[color=green]
> >
> > Are you sure?
> >
> > Certainly it seems as though it is a logic error which[/color]
> could possibly[color=green]
> > result in undefined behavior, but is it guaranteed[/color]
> undefined behavior?[color=green]
> >[/color][/color]

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.


Ioannis Vranos
Guest
 
Posts: n/a
#13: Jul 22 '05

re: Undefined behaviour


marbac wrote:
[color=blue]
> 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?[/color]




"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
Default User
Guest
 
Posts: n/a
#14: Jul 22 '05

re: Undefined behaviour


Rolf Magnus wrote:
[color=blue]
> 4) Writing to a member of a union and then reading another one[/color]


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




Brian Rodenborn
Ron Natalie
Guest
 
Posts: n/a
#15: Jul 22 '05

re: Undefined behaviour



"Default User" <first.last@boeing.com.invalid> wrote in message news:40F4582A.75612BD@boeing.com.invalid...[color=blue]
> Rolf Magnus wrote:
>[color=green]
> > 4) Writing to a member of a union and then reading another one[/color]
>
>
> This is implementation-defined in C. I'd be surprised if it was
> different in C++.
>[/color]
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).

Old Wolf
Guest
 
Posts: n/a
#16: Jul 22 '05

re: Undefined behaviour


"Sharad Kala" <no__spam.sharadk_ind@yahoo.com> wrote:[color=blue]
> "John Harrison" <john_andronicus@hotmail.com> wrote:[color=green]
> > "marbac" <marbac@chello.at> wrote:[color=darkred]
> > > Is there a list where all cases with undefined behaviour in C++ are[/color][/color]
> listed?[color=green]
> > 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[/color]
>
> Some more strike me -
> 2) Copying a pointer after it has been deleted[/color]

Exactly the same as John's #6 (the standard-ese term is "indeterminate")
[color=blue]
> 4) Modifying a string literal[/color]

Same as John's #8 (string literals have type "char const []")
Default User
Guest
 
Posts: n/a
#17: Jul 22 '05

re: Undefined behaviour


Ron Natalie wrote:[color=blue]
>
> "Default User" <first.last@boeing.com.invalid> wrote in message news:40F4582A.75612BD@boeing.com.invalid...[color=green]
> > Rolf Magnus wrote:
> >[color=darkred]
> > > 4) Writing to a member of a union and then reading another one[/color]
> >
> >
> > This is implementation-defined in C. I'd be surprised if it was
> > different in C++.
> >[/color]
> C says it's unspecified, there is no need for the implementation to have a specific
> behavior.[/color]

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.

[color=blue]
> In the general case, it's undefined behavior for C++ (there are some
> specific outs).[/color]


Could you quote the standard on that?



Brian Rodenborn
Peter Koch Larsen
Guest
 
Posts: n/a
#18: Jul 22 '05

re: Undefined behaviour



"tom_usenet" <tom_usenet@hotmail.com> skrev i en meddelelse
news:a7v7f0datspj8rcivetq4d279ob2l77cig@4ax.com...[color=blue]
> On Tue, 13 Jul 2004 14:11:18 +0200, "Peter Koch Larsen"
> <pklspam@mailme.dk> wrote:
>[color=green]
> >
> >"Ivan Vecerina" <NOT_VALID_please_use_contact_webform@vecerina.com > skrev[/color][/color]
i[color=blue][color=green]
> >en meddelelse news:cd0i4d$7v1$1@newshispeed.ch...
> >
> >[snip]
> >[color=darkred]
> >> 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[/color][/color][/color]
range.[color=blue][color=green][color=darkred]
> >> ( vector::at() may be used instead, and will throw an exception ).[/color]
> >
> >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[/color][/color]
course.[color=blue]
>
> 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[/color]

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

/Peter


Ioannis Vranos
Guest
 
Posts: n/a
#19: Jul 22 '05

re: Undefined behaviour


Peter Koch Larsen wrote:
[color=blue]
> You're right of course. My point was that vector::operator[] is allowed to
> verify the range. The assert is an excellent solution.[/color]



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
Rolf Magnus
Guest
 
Posts: n/a
#20: Jul 22 '05

re: Undefined behaviour


Ioannis Vranos wrote:
[color=blue]
> Peter Koch Larsen wrote:
>[color=green]
>> You're right of course. My point was that vector::operator[] is
>> allowed to verify the range. The assert is an excellent solution.[/color]
>
>
>
> If an implementation of vector's operator[]() threw an out_of_range
> exception or anything else, it would be a system-specific extension,[/color]

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".
[color=blue]
> and code assuming that this operator is index-checked, cannot be
> considered portable.[/color]

That's of course true, and this is exactly the reason why there is at().
[color=blue]
> Furthermore, since at() is provided for this, operator[] is reasonable
> to be defined having an efficient access to the data.[/color]

Yes.

Ioannis Vranos
Guest
 
Posts: n/a
#21: Jul 22 '05

re: Undefined behaviour


Rolf Magnus wrote:
[color=blue][color=green]
>>If an implementation of vector's operator[]() threw an out_of_range
>>exception or anything else, it would be a system-specific extension,[/color]
>
>
> 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".[/color]


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






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
Duane Hebert
Guest
 
Posts: n/a
#22: Jul 22 '05

re: Undefined behaviour



"Ron Natalie" <ron@sensor.com> wrote in message news:40f45c55$0$28065$9a6e19ea@news.newshosting.co m...[color=blue]
>
> "Default User" <first.last@boeing.com.invalid> wrote in message news:40F4582A.75612BD@boeing.com.invalid...[color=green]
> > Rolf Magnus wrote:
> >[color=darkred]
> > > 4) Writing to a member of a union and then reading another one[/color]
> >
> >
> > This is implementation-defined in C. I'd be surprised if it was
> > different in C++.
> >[/color]
> 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).[/color]

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?


Ioannis Vranos
Guest
 
Posts: n/a
#23: Jul 22 '05

re: Undefined behaviour


Duane Hebert wrote:
[color=blue]
> "Ron Natalie" <ron@sensor.com> wrote in message news:40f45c55$0$28065$9a6e19ea@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?[/color]


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
Duane Hebert
Guest
 
Posts: n/a
#24: Jul 22 '05

re: Undefined behaviour



"Ioannis Vranos" <ivr@guesswh.at.grad.com> wrote in message news:cd4g0j$17hf$1@ulysses.noc.ntua.gr...
[color=blue]
> Strictly speaking reading doh.s which was not properly assigned a value
> is undefined behaviour.[/color]

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?
[color=blue]
>
> 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. :-)[/color]

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


Rolf Magnus
Guest
 
Posts: n/a
#25: Jul 22 '05

re: Undefined behaviour


Duane Hebert wrote:
[color=blue]
> 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.[/color]

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.

Peter Koch Larsen
Guest
 
Posts: n/a
#26: Jul 22 '05

re: Undefined behaviour



"Ioannis Vranos" <ivr@guesswh.at.grad.com> skrev i en meddelelse
news:cd3b7g$1hr2$1@ulysses.noc.ntua.gr...[color=blue]
> Peter Koch Larsen wrote:
>[color=green]
> > You're right of course. My point was that vector::operator[] is allowed[/color][/color]
to[color=blue][color=green]
> > verify the range. The assert is an excellent solution.[/color]
>
>
>
> 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.[/color]

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[color=blue]
>
> 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[/color]


Rolf Magnus
Guest
 
Posts: n/a
#27: Jul 22 '05

re: Undefined behaviour


Peter Koch Larsen wrote:
[color=blue]
>
> "Ioannis Vranos" <ivr@guesswh.at.grad.com> skrev i en meddelelse
> news:cd3b7g$1hr2$1@ulysses.noc.ntua.gr...[color=green]
>> Peter Koch Larsen wrote:
>>[color=darkred]
>> > You're right of course. My point was that vector::operator[] is
>> > allowed[/color][/color]
> to[color=green][color=darkred]
>> > verify the range. The assert is an excellent solution.[/color]
>>
>>
>>
>> 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.[/color]
>
> 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.[/color]

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.

Peter Koch Larsen
Guest
 
Posts: n/a
#28: Jul 22 '05

re: Undefined behaviour



"Rolf Magnus" <ramagnus@t-online.de> skrev i en meddelelse
news:cd69ul$rot$06$1@news.t-online.com...[color=blue]
> Peter Koch Larsen wrote:
>[color=green]
> >
> > "Ioannis Vranos" <ivr@guesswh.at.grad.com> skrev i en meddelelse
> > news:cd3b7g$1hr2$1@ulysses.noc.ntua.gr...[color=darkred]
> >> Peter Koch Larsen wrote:
> >>
> >> > You're right of course. My point was that vector::operator[] is
> >> > allowed[/color]
> > to[color=darkred]
> >> > 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.[/color]
> >
> > 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.[/color]
>
> 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.
>[/color]

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


Default User
Guest
 
Posts: n/a
#29: Jul 22 '05

re: Undefined behaviour


Duane Hebert wrote:[color=blue]
>
> "Ron Natalie" <ron@sensor.com> wrote in message news:40f45c55$0$28065$9a6e19ea@news.newshosting.co m...[/color]
[color=blue][color=green]
> > 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).[/color]
>
> I've heard this before but you mean basically that:[/color]

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
Default User
Guest
 
Posts: n/a
#30: Jul 22 '05

re: Undefined behaviour


Duane Hebert wrote:[color=blue]
>
> "Ron Natalie" <ron@sensor.com> wrote in message news:40f45c55$0$28065$9a6e19ea@news.newshosting.co m...[/color]
[color=blue][color=green]
> > 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).[/color]
>
> I've heard this before but you mean basically that:[/color]


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.


[color=blue]
>
> 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?[/color]

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.
[color=blue]
> 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.)[/color]

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.
[color=blue]
> Any thoughts? At any rate, what would be the purpose
> of a union?[/color]

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



Brian Rodenborn




Brian Rodenborn
Ioannis Vranos
Guest
 
Posts: n/a
#31: Jul 22 '05

re: Undefined behaviour


Duane Hebert wrote:
[color=blue]
> 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?[/color]


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
Ioannis Vranos
Guest
 
Posts: n/a
#32: Jul 22 '05

re: Undefined behaviour


Default User wrote:
[color=blue]
> 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.[/color]



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






Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
Ioannis Vranos
Guest
 
Posts: n/a
#33: Jul 22 '05

re: Undefined behaviour


Peter Koch Larsen wrote:
[color=blue]
> 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.[/color]


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
Ioannis Vranos
Guest
 
Posts: n/a
#34: Jul 22 '05

re: Undefined behaviour


Rolf Magnus wrote:

[color=blue]
> 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.[/color]


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
Rolf Magnus
Guest
 
Posts: n/a
#35: Jul 22 '05

re: Undefined behaviour


Ioannis Vranos wrote:
[color=blue]
> Peter Koch Larsen wrote:
>[color=green]
>> 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.[/color]
>
>
> 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?[/color]

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?

Kai-Uwe Bux
Guest
 
Posts: n/a
#36: Jul 22 '05

re: Undefined behaviour


Rolf Magnus wrote:
[color=blue]
> Ioannis Vranos wrote:
>[color=green]
>> Peter Koch Larsen wrote:
>>[color=darkred]
>>> 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.[/color]
>>
>>
>> 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?[/color]
>
> 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?[/color]

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
Default User
Guest
 
Posts: n/a
#37: Jul 22 '05

re: Undefined behaviour


Ioannis Vranos wrote:
[color=blue]
> You are making a mistake. Here we are talking about C++ and not C. :-)[/color]


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
Ioannis Vranos
Guest
 
Posts: n/a
#38: Jul 22 '05

re: Undefined behaviour


Rolf Magnus wrote:
[color=blue]
> 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?[/color]



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
Ron Natalie
Guest
 
Posts: n/a
#39: Jul 22 '05

re: Undefined behaviour



"Default User" <first.last@boeing.com.invalid> wrote in message news:40F46AFD.32652269@boeing.com.invalid...
[color=blue]
>
> The C99 standard says virtually the same thing.
>[/color]

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

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

Ron Natalie
Guest
 
Posts: n/a
#40: Jul 22 '05

re: Undefined behaviour



"Default User" <first.last@boeing.com.invalid> wrote in message news:40F6AFBD.FDB9AF1E@boeing.com.invalid...[color=blue]
> Duane Hebert wrote:[color=green]
> >
> > "Ron Natalie" <ron@sensor.com> wrote in message news:40f45c55$0$28065$9a6e19ea@news.newshosting.co m...[/color]
>[color=green][color=darkred]
> > > 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).[/color]
> >
> > I've heard this before but you mean basically that:[/color]
>
> 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[/color]

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.

Ron Natalie
Guest
 
Posts: n/a
#41: Jul 22 '05

re: Undefined behaviour



"Duane Hebert" <spoo@flarn2.com> wrote in message news:70jJc.123199$wQ5.1898602@weber.videotron.net. ..
[color=blue]
>
> 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?[/color]

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

Ron Natalie
Guest
 
Posts: n/a
#42: Jul 22 '05

re: Undefined behaviour



"tom_usenet" <tom_usenet@hotmail.com> wrote in message news:a7v7f0datspj8rcivetq4d279ob2l77cig@4ax.com...[color=blue]
> 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.[/color]

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

[color=blue]
> IMHO, any decent operator[] should at the very least have an assert in
> it.[/color]

And this is an improvement over throwing how?
Default User
Guest
 
Posts: n/a
#43: Jul 22 '05

re: Undefined behaviour


Ron Natalie wrote:[color=blue]
>
> "Default User" <first.last@boeing.com.invalid> wrote in message news:40F46AFD.32652269@boeing.com.invalid...
>[color=green]
> >
> > The C99 standard says virtually the same thing.
> >[/color]
>
> No, it does not. As a matter of fact, the passage you are quoting doesn't even exist
> in C99.[/color]

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.

[color=blue]
> 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).[/color]

Please quote the actual text.
[color=blue]
> Further, 6.5 / 7 clearly makes it undefined behavior in C.[/color]

Again, please quote.

I'm not seeing what you are seeing.



Brian Rodenborn
Default User
Guest
 
Posts: n/a
#44: Jul 22 '05

re: Undefined behaviour


Ron Natalie wrote:[color=blue]
>
> "Default User" <first.last@boeing.com.invalid> wrote in message news:40F6AFBD.FDB9AF1E@boeing.com.invalid...[/color]
[color=blue][color=green]
> > 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[/color][/color]

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.
[color=blue]
> 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++):[/color]

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
Rolf Magnus
Guest
 
Posts: n/a
#45: Jul 22 '05

re: Undefined behaviour


Ron Natalie wrote:
[color=blue]
>
> "tom_usenet" <tom_usenet@hotmail.com> wrote in message
> news:a7v7f0datspj8rcivetq4d279ob2l77cig@4ax.com...[color=green]
>> 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.[/color]
>
> 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).
>
>[color=green]
>> IMHO, any decent operator[] should at the very least have an assert
>> in it.[/color]
>
> And this is an improvement over throwing how?[/color]

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[].

Duane Hebert
Guest
 
Posts: n/a
#46: Jul 22 '05

re: Undefined behaviour



"Rolf Magnus" <ramagnus@t-online.de> wrote in message news:cd5ksn$omt$06$4@news.t-online.com...
[color=blue]
> 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.[/color]

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.


tom_usenet
Guest
 
Posts: n/a
#47: Jul 22 '05

re: Undefined behaviour


On Fri, 16 Jul 2004 14:25:38 -0400, "Ron Natalie" <ron@sensor.com>
wrote:
[color=blue]
>
>"tom_usenet" <tom_usenet@hotmail.com> wrote in message news:a7v7f0datspj8rcivetq4d279ob2l77cig@4ax.com...[color=green]
>> 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.[/color]
>
>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).[/color]

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.
[color=blue][color=green]
>> IMHO, any decent operator[] should at the very least have an assert in
>> it.[/color]
>
>And this is an improvement over throwing how?[/color]

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
Ron Natalie
Guest
 
Posts: n/a
#48: Jul 22 '05

re: Undefined behaviour



"Default User" <first.last@boeing.com.invalid> wrote in message news:40F859B5.A7F01F1C@boeing.com.invalid...[color=blue]
> Ron Natalie wrote:[color=green]
> >
> > "Default User" <first.last@boeing.com.invalid> wrote in message news:40F46AFD.32652269@boeing.com.invalid...
> >[color=darkred]
> > >
> > > The C99 standard says virtually the same thing.
> > >[/color]
> >
> > No, it does not. As a matter of fact, the passage you are quoting doesn't even exist
> > in C99.[/color]
>
> Unless it was removed after the last draft was released, then yes it
> does.
>[/color]
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.

Default User
Guest
 
Posts: n/a
#49: Jul 22 '05

re: Undefined behaviour


Ron Natalie wrote:

[color=blue]
> Please stop telling me I'm wrong unless you are willing to bother to actually READ the
> standard.[/color]

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
Closed Thread