type safety and reinterpret_cast<>

P

Pete Becker

werasm said:
How often does it lead to UB in practise (even though it hypothetically
can)?

There is no such thing as UB in practise. Undefined behavior means only
that the language definition does not tell you what should happen.

--

-- Pete

Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
 
F

Frederick Gotham

Noah Roberts:
Correct, any use of a reinterpret_casted pointer results in undefined
behavior. The only defined behavior is casting back and forth.

Bullshit. The behaviour of the following two snippets is defined by the C++
Standard:

Snippet (1)

unsigned i;

char unsigned *p = reinterpret_cast<char unsigned*>(&i);
char unsigned const *const pover = p + sizeof i;

do *p++ = 0; while (pover != p);


Snippet (2)

struct MyPOD { double a; int b; char *p; } obj;

double *const p = reinterpret_cast<double*>(&obj);

*p = 45.7;
The problem isn't necissarily that reinterpret_cast will change the
address of the pointer but that it won't. This becomes a major issue
when dealing with MI.

What does MI stand for?

In the previous two snippets, the Standard necessitates that
reinterpret_cast process the pointer value correctly.
 
N

Noah Roberts

Frederick said:
In the previous two snippets, the Standard necessitates that
reinterpret_cast process the pointer value correctly.

You'll have to quote the standard then.
 
F

Frederick Gotham

Noah Roberts:
You'll have to quote the standard then.


With regard to Snippet (2):

9.2.17

A pointer to a POD-struct object, suitably converted using a
reinterpret_cast, points to its initial member (or if that member is a bit-
field, then to the unit in which it resides) and vice versa. [Note: There
might therefore be unnamed padding within a POD-struct object, but not at its
beginning, as necessary to achieve appropriate alignment. ]

I'll post the quote relevant to Snippet (1) when I get the chance... although
you should note that we can treat any object as if it were an array of
unsigned char's, and we can only do that by converting pointers (or by
casting to a reference which is equivalent).
 
W

werasm

Pete said:
There is no such thing as UB in practise. Undefined behavior means only
that the language definition does not tell you what should happen.

Ok, rephrase: How often does it lead to unwanted behaviour in practise,
given the specific example?

Regards,

Werner
 
G

Gianni Mariani

werasm said:
Pete Becker wrote: ....

Ok, rephrase: How often does it lead to unwanted behaviour in practise,
given the specific example?

This is where the scientist and the engineer diverge.

There are many cases where it would not happen with the current
compilers and if in some wild future the compiler behaves differently,
in all likeliness the code would fail to run at all (SEGV and such) then
it's safe to use the compiler specific behaviour.

One case where it is not safe is things like:

int x = ..
int y = ..

return x << y; // if y is larger than the number of bits in an int it is UB

In this case some systems will return x and some will return 0. This
can lead to subtle errors that could one day trigger something very
undesirable giving little warning of the lurking failure mode.

On the other hand ...


char x[5];

int y = * reinterpret_cast< int * >( x + 1 );

will fail with a SIGBUS on systems that don't allow unaligned access.
You have plenty of warning in the form of the OS telling you to get
stuffed, in this case UB is well defined. Yes, theoretically, some new
platform can do something strange but in all likelihood that will not
happen for a number of reasons.

So the real response to Pete's question is :

"What is the current set of manifestations of UB for this example in
todays 4 most common compilers ?"

If the answer comes back, they all do the same thing, then you can
pretty much say it's a defacto standard and that any future compiler
will probably behave the same way.

At the then of the day, popular compilers have a very large intersection
in their problem space so it's safe to bet they more likely than not
will take the same UB design choices.
 
R

Richard Herring

In message
Gianni said:
This is where the scientist and the engineer diverge.

There are many cases where it would not happen with the current
compilers and if in some wild future the compiler behaves differently,
in all likeliness the code would fail to run at all (SEGV and such)
then it's safe to use the compiler specific behaviour.

One case where it is not safe is things like:

int x = ..
int y = ..

return x << y; // if y is larger than

-- or equal to! ---
the number of bits in an int it is UB

I wonder how many people that one has caught out?

<raises hand ;->
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top