Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Dereferencing type-punned pointer

Reply
Thread Tools

Dereferencing type-punned pointer

 
 
John May
Guest
Posts: n/a
 
      07-18-2012
I keep getting this warning in GCC with the code segment below.

file.c:256 "warning: dereferencing type-punned pointer will break
strict-aliasing rules"

/*****************************************/
char buffer[SIZE];
int length, type;

/* Code to fill buffer */

length = ntohs( *((unsigned short *)buffer) );
type = ntohs( *((unsigned short *)buffer + 1) );

/*****************************************/


I'm trying to take the first two bytes (in network byte order) off the
buffer and put them in the length, followed by the next two bytes into
the type. GCC complains about the length conversion, but not the type.

What does this warning mean, and should I bother with it?

I don't want to keep checking this forum, so answers by email required.
Quick responses appreciated.

John
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      07-18-2012
John May <(E-Mail Removed)> writes:
> I keep getting this warning in GCC with the code segment below.
>
> file.c:256 "warning: dereferencing type-punned pointer will break
> strict-aliasing rules"
>
> /*****************************************/
> char buffer[SIZE];
> int length, type;
>
> /* Code to fill buffer */
>
> length = ntohs( *((unsigned short *)buffer) );
> type = ntohs( *((unsigned short *)buffer + 1) );
>
> /*****************************************/
>
>
> I'm trying to take the first two bytes (in network byte order) off the
> buffer and put them in the length, followed by the next two bytes into
> the type. GCC complains about the length conversion, but not the type.
>
> What does this warning mean, and should I bother with it?


Assuming buffer is aligned at an even address, buffer + 1 is at an odd
address; attempting to read a short object from an odd address can
easily crash your program. (x86 systems, I think, don't impose strict
alignment requirements.)

If you want to copy bytes from an array of char into a larger integer,
either do so explicitly or use memcpy().

You also appear to be making some assumptions about the sizes of short
and int. You should at least document those assumptions.

> I don't want to keep checking this forum, so answers by email required.
> Quick responses appreciated.


Answers posted here are not just for your benefit; they're for everyone
who reads this newsgroup. Feel free to explain why you should get
special treatment, but don't expect to convince anyone. Post here, get
your answers here.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      07-18-2012
John May <(E-Mail Removed)> writes:
[...]
> I don't want to keep checking this forum, so answers by email required.
> Quick responses appreciated.


Unless <(E-Mail Removed)> is your real e-mail address, how do you
expect to get answers by e-mail?

And if it isn't, you shouldn't use a real domain name as a fake address
(yes, there really is a nospam.com); it can result in the owners of that
domain receiving spam meant for you. "example.com" is guaranteed not to
exist.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-19-2012
Keith Thompson <(E-Mail Removed)> writes:

> John May <(E-Mail Removed)> writes:

<snip>
>> char buffer[SIZE];
>> int length, type;
>>
>> /* Code to fill buffer */
>>
>> length = ntohs( *((unsigned short *)buffer) );
>> type = ntohs( *((unsigned short *)buffer + 1) );

<snip>
>> I'm trying to take the first two bytes (in network byte order) off the
>> buffer and put them in the length, followed by the next two bytes into
>> the type. GCC complains about the length conversion, but not the type.
>>
>> What does this warning mean, and should I bother with it?

>
> Assuming buffer is aligned at an even address, buffer + 1 is at an odd
> address; attempting to read a short object from an odd address can
> easily crash your program.


The cast has higher precedence so unless the size of short is odd, the
second access uses an address with the same parity as the first.

I've phrased it like this because there's nothing actually wrong with
what you said -- it just isn't relevant to the code in question!

<snip>
--
Ben.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-19-2012
John May <(E-Mail Removed)> writes:

> I keep getting this warning in GCC with the code segment below.
>
> file.c:256 "warning: dereferencing type-punned pointer will break
> strict-aliasing rules"
>
> /*****************************************/
> char buffer[SIZE];
> int length, type;
>
> /* Code to fill buffer */
>
> length = ntohs( *((unsigned short *)buffer) );
> type = ntohs( *((unsigned short *)buffer + 1) );
>
> /*****************************************/
>
>
> I'm trying to take the first two bytes (in network byte order) off the
> buffer and put them in the length, followed by the next two bytes into
> the type. GCC complains about the length conversion, but not the type.
>
> What does this warning mean, and should I bother with it?


gcc assumes (as it is permitted to do) that an object is only accessed
via an expression of "the right type" -- usually just the declared type
of the object. The objects in 'buffer' are declared to be chars, but
the pointer cast and dereference causes them to be accessed using an
expression of type short. Because the breaks gcc's assumptions it warns
you. It's generally a bad way to do this kind of thing.

(The phrase "the right type" is in quotes because the actual rules are
rather complex so my explanation is very much a simplification.)

An alternative is to use a union:

union {
uint8_t bytes[SIZE];
uint16_t words[SIZE/2];
} buf_type;

but_type buffer;
...
length = ntohs(buffer.words[0]);
type = ntohs(buffer.words[1]);

(The uintN_t types are standard C types from stdint.h.)

Alternatively you can construct the two values from the individual
bytes:

length = ((unsigned)buffer[0] << + buffer[1];

but this is fiddly -- you should make the buffer an array of unsigned
char and you still need the cast before the shift for the code to be
properly portable.

> I don't want to keep checking this forum, so answers by email required.
> Quick responses appreciated.


Sorry -- impossible for reasons already explained.

--
Ben.
 
Reply With Quote
 
Ike Naar
Guest
Posts: n/a
 
      07-19-2012
On 2012-07-18, Keith Thompson <(E-Mail Removed)> wrote:
> Unless <(E-Mail Removed)> is your real e-mail address, how do you
> expect to get answers by e-mail?
>
> And if it isn't, you shouldn't use a real domain name as a fake address
> (yes, there really is a nospam.com); it can result in the owners of that
> domain receiving spam meant for you. "example.com" is guaranteed not to
> exist.


Are you sure about that? "example" does not exist as a top-level
domain, but is it also a reserved name for subdomains? (I thought
not).
Perhaps better choices would be "nospam.example" or "nospam.invalid".
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      07-19-2012
Ike Naar <(E-Mail Removed)> writes:
> On 2012-07-18, Keith Thompson <(E-Mail Removed)> wrote:
>> Unless <(E-Mail Removed)> is your real e-mail address, how do you
>> expect to get answers by e-mail?
>>
>> And if it isn't, you shouldn't use a real domain name as a fake address
>> (yes, there really is a nospam.com); it can result in the owners of that
>> domain receiving spam meant for you. "example.com" is guaranteed not to
>> exist.

>
> Are you sure about that? "example" does not exist as a top-level
> domain, but is it also a reserved name for subdomains? (I thought
> not).
> Perhaps better choices would be "nospam.example" or "nospam.invalid".


Yes, I'm sure. See <http://www.iana.org/domains/example/>
(<http://example.com> forwards to it).

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ike Naar
Guest
Posts: n/a
 
      07-19-2012
On 2012-07-19, Keith Thompson <(E-Mail Removed)> wrote:
> Ike Naar <(E-Mail Removed)> writes:
>> On 2012-07-18, Keith Thompson <(E-Mail Removed)> wrote:
>>> Unless <(E-Mail Removed)> is your real e-mail address, how do you
>>> expect to get answers by e-mail?
>>>
>>> And if it isn't, you shouldn't use a real domain name as a fake address
>>> (yes, there really is a nospam.com); it can result in the owners of that
>>> domain receiving spam meant for you. "example.com" is guaranteed not to
>>> exist.

>>
>> Are you sure about that? "example" does not exist as a top-level
>> domain, but is it also a reserved name for subdomains? (I thought
>> not).
>> Perhaps better choices would be "nospam.example" or "nospam.invalid".

>
> Yes, I'm sure. See <http://www.iana.org/domains/example/>
> (<http://example.com> forwards to it).


Thanks. I was only aware of the reserved toplevel domains "example",
"invalid", "test" and "localhost", and didn't know about "example.com",
"example.org" and "example.net".
 
Reply With Quote
 
Nobody
Guest
Posts: n/a
 
      07-20-2012
On Thu, 19 Jul 2012 01:56:03 +0100, Ben Bacarisse wrote:

> length = ntohs(buffer.words[0]);
> type = ntohs(buffer.words[1]);
>
> (The uintN_t types are standard C types from stdint.h.)


Also, the type of ntohs() as specified by POSIX is:

uint16_t ntohs(uint16_t);


 
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
dereferencing pointer to base Vam C++ 1 02-18-2005 05:08 PM
NULL pointer dereferencing - behaviour BigMan C++ 51 02-17-2005 06:16 PM
Dereferencing a pointer to an array of pointers to objects Richard Cavell C++ 4 02-16-2005 12:35 PM
*& dereferencing a pointer to a class Peter L. C++ 3 02-17-2004 01:03 PM
Dereferencing a pointer within a function Larry Lindsey C++ 1 09-24-2003 03:42 PM



Advertisments