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 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
"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
"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
"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
"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
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
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
"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.
>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.
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
"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.
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
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
"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).
"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 []")
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
"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
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
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.
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
"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?
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
"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 ...
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.
"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
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.
"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
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
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
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
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
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
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
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?
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
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
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
"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).
"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.
"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.
"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?
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
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
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[].
"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.
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
"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.
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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)
|
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:...
|
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?
|
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...
|
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...
|
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>
>>>...
|
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...
|
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.
...
|
by: subramanian100in |
last post by:
Consider the following code:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
const double& ref = 100;
|
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....
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
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...
|
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...
|
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...
|
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)...
|
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...
|
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....
|
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
|
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...
| |