473,396 Members | 1,832 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Advanced pointer typecasting

Hi!

I'm rather new at c++ and I'm totally confused with this kind of
typecasting:

typedef signed char int8_t;
typedef signed short int16_t;

typedef struct broadcast_hdr
{
broadcast_type_t broadcast_type;
uint16_t items_n;
uint16_t size_n;
} broadcast_hdr_t;

typedef struct broadcast_type
{
char ac;
char bc;
uint16_t number_n;
} broadcast_type_t;

typedef struct ob_levels_price
{
uint16_t maskA_n;
uint16_t maskB_n;
uint8_t levels_c;
uint8_t items_c;
char filler_2_s [2];
} ob_levels_price_t;

void HandleBroadcast(int8_t* broadcast, uint16_t length)
{
static broadcast_type_t typeA = {'B','I',9};
static broadcast_type_t typeB = {'B','D',6};
static broadcast_type_t typeC = {'B','O',14};

broadcast_type_t* bc;

bc = (broadcast_type_t*)broadcast;

if (memcmp(bc, &typeC, sizeof(broadcast_type_t)) == 0)
{
SpecificBroadcast(broadcast, length);
return;
}

}

void SpecificBroadcast(int8_t* broadcast, uint16_t length)
{

ob_levels_price_t* obPriceVolumes = (ob_levels_price_t*)broadcast;

broadcast_hdr_t* bc = (broadcast_hdr_t*)broadcast;
uint32_t substart = sizeof(*bc);
uint8_t *pBc = (uint8_t*)bc;
}

Can someone explain to me SpecificBroadcast. I don't understand how
the contents of an signed char (int8_t) can be converted to a struct
(ob_levels_price_t, broadcast_hdr_t) through its address. What could
possibly be the contents of the broadcast variable???

Really stumped.

Thanks in advance.
Jul 22 '05 #1
3 5552
On 19 Feb 2004 19:01:35 -0800, ro***********@mail.com (Robert Street)
wrote in comp.lang.c++:
Hi!

I'm rather new at c++ and I'm totally confused with this kind of
typecasting:
You should be, it almost certainly indicates bad design. It depends
on one guaranteed feature of the language, and a lot of things that
are not guaranteed.

One guarantee that the language makes is that a pointer to any type of
object can be converted, with a suitable cast, to a pointer to one of
the character types or to a pointer to void. If such a pointer
originally points to a valid object of its type, the char or void
pointer can later be cast back to a pointer of the original object
type and it will still point to the same object.

There is no such guarantee for any other type of pointer, as other
types of headers may use fewer bits of information than pointer to
char or void.

There is most certainly no guarantee that just any arbitrary pointer
to char or void can be cast to a pointer to another object type and be
valid. It might not have the proper alignment for the other object
type, and cause undefined behavior when used to access that type.
typedef signed char int8_t;
typedef signed short int16_t;

typedef struct broadcast_hdr
{
broadcast_type_t broadcast_type;
uint16_t items_n;
uint16_t size_n;
} broadcast_hdr_t;

typedef struct broadcast_type
{
char ac;
char bc;
uint16_t number_n;
} broadcast_type_t;

typedef struct ob_levels_price
{
uint16_t maskA_n;
uint16_t maskB_n;
uint8_t levels_c;
uint8_t items_c;
char filler_2_s [2];
} ob_levels_price_t;

void HandleBroadcast(int8_t* broadcast, uint16_t length)
{
static broadcast_type_t typeA = {'B','I',9};
static broadcast_type_t typeB = {'B','D',6};
static broadcast_type_t typeC = {'B','O',14};

broadcast_type_t* bc;

bc = (broadcast_type_t*)broadcast;

if (memcmp(bc, &typeC, sizeof(broadcast_type_t)) == 0)
The line above is very problematic. Even if "broadcast" was obtained
by casting the address a broadcast_type_t to pointer to signed char,
so there are no alignment issues, and even if the original
broadcast_type_t contained {'B', 'O', 14 }, there is no requirement
that the two structures compare equal when passed to memcmp().

Padding is allowed in structures everywhere except before the first
member. There can be padding in between members, and after the last
member. The value of the padding bytes can be different in two
structures whose actual members are identical, causing the memcmp() to
fail.
{
SpecificBroadcast(broadcast, length);
return;
}

}

void SpecificBroadcast(int8_t* broadcast, uint16_t length)
{

ob_levels_price_t* obPriceVolumes = (ob_levels_price_t*)broadcast;

broadcast_hdr_t* bc = (broadcast_hdr_t*)broadcast;
uint32_t substart = sizeof(*bc);
uint8_t *pBc = (uint8_t*)bc;
}

Can someone explain to me SpecificBroadcast. I don't understand how
the contents of an signed char (int8_t) can be converted to a struct
(ob_levels_price_t, broadcast_hdr_t) through its address. What could
possibly be the contents of the broadcast variable???

Really stumped.

Thanks in advance.


This code uses C casts, although a C++ static_cast could do the same
job.

As I said above, a pointer to void or one of the character types can
hold a pointer to any type of object. Unless the pointer originated
as a pointer to that type of object, you get undefined behavior if you
try to access an object of that type through it.

There is nothing particularly C++ about this code, it is completely
compatible with C. But it is a bad design in either language. There
are much more sensible, and portable, ways to do whatever this code
does, such as putting the structure types in a union and passing a
pointer to the union.

The code also depends on specifically non-portable behavior, the fact
that on some implementation there will be no padding in the
broadcast_type_t structure so that two structures with
member-by-member equality will compare equal when passed to memcmp().
There is no such guarantee in either C or C++, and there are compilers
where the memcmp() might fail a good part of the time even if all the
individual members of the two structures compare equal.

This code is bad, and should not be emulated.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #2

"Robert Street" <ro***********@mail.com> wrote in message
news:41**************************@posting.google.c om...
Hi!

I'm rather new at c++ and I'm totally confused with this kind of
typecasting:

typedef signed char int8_t;
typedef signed short int16_t;
snip
void SpecificBroadcast(int8_t* broadcast, uint16_t length)
{

ob_levels_price_t* obPriceVolumes = (ob_levels_price_t*)broadcast;

broadcast_hdr_t* bc = (broadcast_hdr_t*)broadcast;
uint32_t substart = sizeof(*bc);
uint8_t *pBc = (uint8_t*)bc;
}

Can someone explain to me SpecificBroadcast. I don't understand how
the contents of an signed char (int8_t) can be converted to a struct
(ob_levels_price_t, broadcast_hdr_t) through its address. What could
possibly be the contents of the broadcast variable???


This is what people always used to do for low level i/o stuff before void*.
Although they usually use a plain old char*

Some people still do this because when you are doing low level stuff you
often need to do byte address calculations
and that requires a pointer to something of size 1. e.g.

// read a message from a socket
void readn(int fd,void* buf,int size)
{
do
{
int nread = read(fd,buf,size); // read should take void*
size -= nread;
buf = (char*)buf + nread; // cast required purely to do
arithmetic
} while(size);
}

Even then it is best to make the function parameter void* because although
making it 'byte'* would make the function simpler
it would often force the caller to cast to something it is not.
eg.
ob_levels_price_t x;
SpecificBroadcast(&x,sizeof(x)); // will not coompile despite the fact
that it clearly should according to SpecificBroadcast
SpecificBroadcast((uint8_t*)&x,sizeof(x)); // will compile - using
reinterpret_cast only makes it uglier

Another good reason to use void* rather than some sort of char* is this is
that ostream<< will do the wrong thing and debuggers will spew garbage when
doing stack dumps or showing local vars.

IMHO It would be a nice idea to allow pointer arithmetic on void* as if it
was a pointer to 'byte' - I don't think it would
do any harm in real programs.

Jul 22 '05 #3
"Nick Hounsome" <nh***@blueyonder.co.uk> wrote in message news:<9w*****************@news-binary.blueyonder.co.uk>...
"Robert Street" <ro***********@mail.com> wrote in message
news:41**************************@posting.google.c om...
Hi!

I'm rather new at c++ and I'm totally confused with this kind of
typecasting:

typedef signed char int8_t;
typedef signed short int16_t;
snip
void SpecificBroadcast(int8_t* broadcast, uint16_t length)
{

ob_levels_price_t* obPriceVolumes = (ob_levels_price_t*)broadcast;

broadcast_hdr_t* bc = (broadcast_hdr_t*)broadcast;
uint32_t substart = sizeof(*bc);
uint8_t *pBc = (uint8_t*)bc;
}

Can someone explain to me SpecificBroadcast. I don't understand how
the contents of an signed char (int8_t) can be converted to a struct
(ob_levels_price_t, broadcast_hdr_t) through its address. What could
possibly be the contents of the broadcast variable???


This is what people always used to do for low level i/o stuff before void*.
Although they usually use a plain old char*

Some people still do this because when you are doing low level stuff you
often need to do byte address calculations
and that requires a pointer to something of size 1. e.g.

// read a message from a socket
void readn(int fd,void* buf,int size)
{
do
{
int nread = read(fd,buf,size); // read should take void*
size -= nread;
buf = (char*)buf + nread; // cast required purely to do
arithmetic
} while(size);
}

Even then it is best to make the function parameter void* because although
making it 'byte'* would make the function simpler
it would often force the caller to cast to something it is not.
eg.
ob_levels_price_t x;
SpecificBroadcast(&x,sizeof(x)); // will not coompile despite the fact
that it clearly should according to SpecificBroadcast
SpecificBroadcast((uint8_t*)&x,sizeof(x)); // will compile - using
reinterpret_cast only makes it uglier


Thanks for the help.

One more question, why can the code cast the uint8_t pointer to *both*
ob_levels_price_t* and broadcast_header_t*? Shouldn't the original
address be simply pointing to one type of struct? Any ideas?
Another good reason to use void* rather than some sort of char* is this is
that ostream<< will do the wrong thing and debuggers will spew garbage when
doing stack dumps or showing local vars.

IMHO It would be a nice idea to allow pointer arithmetic on void* as if it
was a pointer to 'byte' - I don't think it would
do any harm in real programs.

Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Arun Prasath | last post by:
Hi all, I have the following question regd pointer typecasting. Is the following type of pointer typecasting valid? #define ALLOC(type,num) ((type *)malloc(sizeof(type)*num)) /*begin...
2
by: Arun Prasath | last post by:
Hi all, I have the following question regd pointer typecasting. Is the following type of pointer typecasting valid? #define ALLOC(type,num) ((type *)malloc(sizeof(type)*num)) /*begin...
16
by: jose_luis_fdez_diaz_news | last post by:
Hi, If I don't include <libgen.h> I get then warnig below in regcmp call: warning: improper pointer/integer combination: op "=" but if I include it the warning is not shown, but them program...
3
by: jdm | last post by:
In the sample code for the SortedList class, I see the use of a string typecasting macro consisting of a single letter "S". i.e.: Sortedlist->Add(S"Keyval one", S"Item one"); Now I have...
4
by: st_ev_fe | last post by:
Hi people, I've been doing C for about 7 years now. But I'm new to C++. I've decided that C++'s operator overloading could be very handy. I'm writing something much like auto_ptr, except for...
10
by: lovecreatesbeauty | last post by:
Why (type*)pointer isn't equal to *(type**)pointer, In the code snippet, it shows that: (int *) == (int **) , (int *) != (*(int **)) . Does type-casting change the address? or...
16
by: Abhishek | last post by:
why do I see that in most C programs, pointers in functions are accepted as: int func(int i,(void *)p) where p is a pointer or an address which is passed from the place where it is called. what...
5
by: WittyGuy | last post by:
How to typecast a "function pointer" to "const void*" type in C++ way? int MyFunction (double money); // Function prototype const void* arg = (const void*)MyFunction; // type casting...
4
by: Schkhan | last post by:
Hi, I am sturggling with a peace of code mainly its about casting a pointer to one type of structure to a pointer to another type of structure. the confusion begins with the following...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.