Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > type safety and reinterpret_cast<>

Reply
Thread Tools

type safety and reinterpret_cast<>

 
 
Bart
Guest
Posts: n/a
 
      10-31-2006
Noah Roberts wrote:
> Jim Langston wrote:
> > Other that that, if you use it wrong you shoot yoru self in the foot.

>
> very insightfull.


Indeed. People often forget that C++ is a language where you can shoot
yourself in the foot and blow your whole leg off. That stems directly
from the "the programmer knows best" philosophy.

If you want Java you know where to find it.

Regards,
Bart.

 
Reply With Quote
 
 
 
 
Frederick Gotham
Guest
Posts: n/a
 
      11-01-2006
Bart:

>> MyClass obj;
>>
>> char unsigned *p = reinterpret_cast<char unsigned*>(&obj);

>
> I don't know what you mean by "proper conversion".


By proper conversion, I mean that the behaviour of the following snippet is
well-defined:

int arr[10];

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

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

The reinterpret_cast doesn't merely take the bits of an int* and stick them
in a char*, it actually renders the address accurately as a char*. The
different will definitely be noticeable on systems where sizeof(char*) >
sizeof(int*).


> The mapping performed by reinterpret_cast is always
> implementation-defined.



Not when it comes to pointers; it's well-defined when it comes to pointers.

--

Frederick Gotham
 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      11-01-2006
Frederick Gotham wrote:

> Bart:
>
>>> MyClass obj;
>>>
>>> char unsigned *p = reinterpret_cast<char unsigned*>(&obj);

>>
>> I don't know what you mean by "proper conversion".

>
> By proper conversion, I mean that the behaviour of the following snippet
> is well-defined:
>
> int arr[10];
>
> char unsigned *p = reinterpret_cast<char unsigned*>(arr);
> char unsigned const *const pover = p + sizeof arr;
>
> do *p++ = 0;
> while (pover != p);
>
> The reinterpret_cast doesn't merely take the bits of an int* and stick
> them in a char*, it actually renders the address accurately as a char*.
> The different will definitely be noticeable on systems where sizeof(char*)
> > sizeof(int*).

>
>
>> The mapping performed by reinterpret_cast is always
>> implementation-defined.

>
>
> Not when it comes to pointers; it's well-defined when it comes to
> pointers.


This last statement seems to be overly general. Is the following defined
behavior?

int main ( ) {

int i;
int* ip = &i;
unsigned* up = reinterpret_cast< unsigned* >( ip );
*up = 0;

}

I cannot find the anything in the standard that would prevent *up = 0 from
segfaulting.


Best

Kai-Uwe Bux
 
Reply With Quote
 
Frederick Gotham
Guest
Posts: n/a
 
      11-01-2006
Kai-Uwe Bux:

> Is the following defined
> behavior?
>
> int main ( ) {
>
> int i;
> int* ip = &i;
> unsigned* up = reinterpret_cast< unsigned* >( ip );
> *up = 0;
>
> }



There's no problem with the code, because:

sizeof(int) == sizeof(unsigned)
alignof(int) == alignof(unsigned)

You might have a little problem though if you try to read the value of "i"
subsequent to the zero assignment, but only if:

(1) An unsigned int contains padding.
(2) An unsigned int has an object representation of the value zero in which
the padding bits are not all set to zero.
(3) The bit-pattern for the value from (2) is an invalid object
representation for an int.

In such a system, the zero assignment could result in an object
representation of:

1111 0000 0000 0000 0000
(i.e. 4 padding bits, 16 value bits)

, which may be invalid for an int.

--

Frederick Gotham
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      11-01-2006
Frederick Gotham wrote:

> Kai-Uwe Bux:
>
>> Is the following defined
>> behavior?
>>
>> int main ( ) {
>>
>> int i;
>> int* ip = &i;
>> unsigned* up = reinterpret_cast< unsigned* >( ip );
>> *up = 0;
>>
>> }

>
>
> There's no problem with the code, because:
>
> sizeof(int) == sizeof(unsigned)
> alignof(int) == alignof(unsigned)
>
> You might have a little problem though if you try to read the value of "i"
> subsequent to the zero assignment, but only if:
>
> (1) An unsigned int contains padding.
> (2) An unsigned int has an object representation of the value zero in
> which the padding bits are not all set to zero.
> (3) The bit-pattern for the value from (2) is an invalid object
> representation for an int.
>
> In such a system, the zero assignment could result in an object
> representation of:
>
> 1111 0000 0000 0000 0000
> (i.e. 4 padding bits, 16 value bits)
>
> , which may be invalid for an int.


I think you are assuming in your argument that up points to the same object
(i.e., region of memory) as ip. I do not find that guarantee in the
standard. All it requires is that if you convert back from up, you get the
original ip. Otherwise, the result of a pointer conversion is unspecified.
In particular, up could be an invalid pointer.

The only case where I know of a requirement that pointer conversion
preserves the actual memory location is conversion to and from (unsigned)
char*.


Best

Kai-Uwe Bux
 
Reply With Quote
 
Frederick Gotham
Guest
Posts: n/a
 
      11-01-2006
Kai-Uwe Bux:

> I think you are assuming in your argument that up points to the same object
> (i.e., region of memory) as ip. I do not find that guarantee in the
> standard. All it requires is that if you convert back from up, you get the
> original ip. Otherwise, the result of a pointer conversion is unspecified.
> In particular, up could be an invalid pointer.



Given that:

sizeof(int) == sizeof(unsigned)
alignof(int) == alignof(unsigned)

, there's no reason to think that their pointers would be any different.

--

Frederick Gotham
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      11-01-2006
Frederick Gotham wrote:

> Kai-Uwe Bux:
>
>> I think you are assuming in your argument that up points to the same
>> object (i.e., region of memory) as ip. I do not find that guarantee in
>> the standard. All it requires is that if you convert back from up, you
>> get the original ip. Otherwise, the result of a pointer conversion is
>> unspecified. In particular, up could be an invalid pointer.

>
>
> Given that:
>
> sizeof(int) == sizeof(unsigned)
> alignof(int) == alignof(unsigned)
>
> , there's no reason to think that their pointers would be any different.


The problem is that there is no reason to think that they would be equal,
either. As I pointed out in some other thread, the C++ standard does allow
for pointers that store more information than just a location in memory.
This additional information would not be used in finding the location but
just for defining undefined behavior in surprising ways


Best

Kai-Uwe Bux
 
Reply With Quote
 
Frederick Gotham
Guest
Posts: n/a
 
      11-01-2006
Kai-Uwe Bux:

> The problem is that there is no reason to think that they would be equal,
> either. As I pointed out in some other thread, the C++ standard does allow
> for pointers that store more information than just a location in memory.
> This additional information would not be used in finding the location but
> just for defining undefined behavior in surprising ways



Then maybe C++ is too loosely defined.

--

Frederick Gotham
 
Reply With Quote
 
werasm
Guest
Posts: n/a
 
      11-01-2006

Kai-Uwe Bux wrote:

> The problem is that there is no reason to think that they would be equal,
> either. As I pointed out in some other thread, the C++ standard does allow
> for pointers that store more information than just a location in memory.
> This additional information would not be used in finding the location but
> just for defining undefined behavior in surprising ways


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

W

 
Reply With Quote
 
Noah Roberts
Guest
Posts: n/a
 
      11-01-2006

Kai-Uwe Bux wrote:

> I think you are assuming in your argument that up points to the same object
> (i.e., region of memory) as ip. I do not find that guarantee in the
> standard. All it requires is that if you convert back from up, you get the
> original ip. Otherwise, the result of a pointer conversion is unspecified.
> In particular, up could be an invalid pointer.


Correct, any use of a reinterpret_casted pointer results in undefined
behavior. The only defined behavior is casting back and forth.
>
> The only case where I know of a requirement that pointer conversion
> preserves the actual memory location is conversion to and from (unsigned)
> char*.


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.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Implementing Interfaces and Type Safety (OOP Newbie in Perl) Veli-Pekka Tštilš Perl Misc 7 08-20-2005 10:02 AM
Enumerators, Templates, and Type Safety Matt Taylor C++ 6 07-13-2004 01:16 PM
newbie question on "Type Safety" Raymond Du ASP .Net 1 06-21-2004 11:42 AM
type safety in java 1.5 (bug or hole?) York Werres Java 24 05-25-2004 06:05 PM
Runtime type-safety (for linked lists) Dave C Programming 2 09-29-2003 09:42 AM



Advertisments