473,770 Members | 1,787 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Typecasting Pointers

Quick question:

if I have a structure:

struct foo {

unsigned char *packet;
unsigned char *ip_src;
};

and another structure:

struct foo2 {

unsigned char *packet;
};

and I do:

struct foo *a;
struct foo2 *b;

a = malloc(sizeof(s truct foo));
if (a == NULL)
return NULL;

(void)memset(a, 1, sizeof(struct foo));

b = (struct foo2 *)a;

--

Would foo2 just strip off the *packet?

And what happens to *ip?

I am trying to understand how C handles the typecast if
one structure pointed to has a different number of members
than the other. I am trying to understand how C99 treats
this situation. Both of my pointers should be correctly
aligned.

Thanks,

Brian
Nov 14 '05 #1
13 2426
On Tue, 23 Nov 2004 14:03:36 -0700, brian <tw*****@cox.ne t> wrote in
comp.lang.c:
Quick question:

if I have a structure:

struct foo {

unsigned char *packet;
unsigned char *ip_src;
};

and another structure:

struct foo2 {

unsigned char *packet;
};

and I do:

struct foo *a;
struct foo2 *b;

a = malloc(sizeof(s truct foo));
if (a == NULL)
return NULL;

(void)memset(a, 1, sizeof(struct foo));

b = (struct foo2 *)a;


You put "-- ", which is a usenet and email signature delimiter, in the
middle of your post. My newsreader quite properly snipped it, and
everything that followed it. And like an awful lot of people these
days, you did not put a signature delimiter before your actual
signature. Sigh.

In any case, about the only guarantee that you have is based on the
fact that a pointer to a structure, when suitably cast, points to the
structure's first member. That means that on most platforms, you can
cast a pointer to either type of structure to a pointer to pointer to
char and use it to access the first member of each structure, which is
a pointer to char.

Anything beyond that is undefined behavior. Here is the relevant
paragraph from C99:

========
6.2.7 Compatible type and composite type
1 Two types have compatible type if their types are the same.
Additional rules for determining whether two types are compatible are
described in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers,
and in 6.7.5 for declarators.46) Moreover, two structure, union, or
enumerated types declared in separate translation units are compatible
if their tags and members satisfy the following requirements: If one
is declared with a tag, the other shall be declared with the same tag.
If both are complete types, then the following additional requirements
apply: there shall be a one-to-one correspondence between their
members such that each pair of corresponding members are declared with
compatible types, and such that if one member of a corresponding pair
is declared with a name, the other member is declared with the same
name. For two structures, corresponding members shall be declared in
the same order. For two structures or unions, corresponding bit-fields
shall have the same widths. For two enumerations, corresponding
members shall have the same values.
========

--
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.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #2
Jack Klein <ja*******@spam cop.net> wrote:
On Tue, 23 Nov 2004 14:03:36 -0700, brian <tw*****@cox.ne t> wrote in
comp.lang.c:
Quick question:
[ Snip ]
b = (struct foo2 *)a;
You put "-- ", which is a usenet and email signature delimiter, in the
middle of your post.


No, he didn't; that line did not contain a space.
My newsreader quite properly snipped it, and everything that followed it.
Get a better newsreader. Forte Free Agent didn't snip a thing.

(Yes, I know.)
And like an awful lot of people these days, you did not put a
signature delimiter before your actual signature. Sigh.
YMMV, but I do not consider a single name to be a signature...
--
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.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html


....and yours is far from McQ. I wouldn't have complained about that,
but...

Richard
Nov 14 '05 #3
Jack Klein wrote:
[snip]
You put "-- ", which is a usenet and email signature delimiter, in the
middle of your post. My newsreader quite properly snipped it, and
everything that followed it. And like an awful lot of people these
days, you did not put a signature delimiter before your actual
signature. Sigh.

In any case, about the only guarantee that you have is based on the
fact that a pointer to a structure, when suitably cast, points to the
structure's first member. That means that on most platforms, you can
cast a pointer to either type of structure to a pointer to pointer to
char and use it to access the first member of each structure, which is
a pointer to char.

Anything beyond that is undefined behavior. Here is the relevant
paragraph from C99:

========
6.2.7 Compatible type and composite type
1 Two types have compatible type if their types are the same.
Additional rules for determining whether two types are compatible are
described in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers,
and in 6.7.5 for declarators.46) Moreover, two structure, union, or
enumerated types declared in separate translation units are compatible
if their tags and members satisfy the following requirements: If one
is declared with a tag, the other shall be declared with the same tag.
If both are complete types, then the following additional requirements
apply: there shall be a one-to-one correspondence between their
members such that each pair of corresponding members are declared with
compatible types, and such that if one member of a corresponding pair
is declared with a name, the other member is declared with the same
name. For two structures, corresponding members shall be declared in
the same order. For two structures or unions, corresponding bit-fields
shall have the same widths. For two enumerations, corresponding
members shall have the same values.
========


Thanks for your help. I will post in this format:

[quoted post]
[my post]
[dashes]
[sig]

So as long as both pointers start on the same alignment boundary, I
should be fine with the cast. I will just be sure to include cast
alignment (-Wcast-align) warnings when I compile.

------

Thanks,

Brian
Nov 14 '05 #4
brian <tw*****@cox.ne t> writes:
[snip]
Thanks for your help. I will post in this format:

[quoted post]
[my post]
[dashes]
[sig]

So as long as both pointers start on the same alignment boundary, I
should be fine with the cast. I will just be sure to include cast
alignment (-Wcast-align) warnings when I compile.

------

Thanks,

Brian


The standard signature delimiter is a line consisting of two hyphens
and a single trailing space. A line of six hyphens is just a line of
six hyphens.

I see that you're using Mozilla Thunderbird 0.5 (consider upgrading to
0.9). If you read its documentation, it should tell you how to set up
a signature file (probably called ".signature " that will automatically
be included, with the proper delimiter, at the bottom of each post.

And incidentally, it's seldom necessary to quote the entire post to
which you're responding. Trim out anything that's not relevant to
your followup. See most of the articles in this newsgroup for good
examples.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #5
Keith Thompson wrote:
[snip]
I see that you're using Mozilla Thunderbird 0.5 (consider upgrading to
0.9). If you read its documentation, it should tell you how to set up
a signature file (probably called ".signature " that will automatically
be included, with the proper delimiter, at the bottom of each post.


I am using the latest available openBSD port of Thunderbird. I know
there is a later version, but I do not have the time to security audit
the latest version, nor do I know the C standard well enough to do a
good job. I am okay with using out of date software that has
been audited.

Also, I really have no need for a signature. My name should be enough.
It doesn't take that long to type five characters.

If you have suggestions for other e-mail/newsreaders, I will check the
port list and try using one of those. openBSD doesn't have the most
extensive collection of ports or most up to date, but the ports work.

Brian

ps Am I good concerning the typecast? I was a little unsure of the
standard and wanted to verify my understanding.
Nov 14 '05 #6
On Tue, 23 Nov 2004 14:03:36 -0700, brian <tw*****@cox.ne t> wrote:
Quick question:

if I have a structure:

struct foo {

unsigned char *packet;
unsigned char *ip_src;
};

and another structure:

struct foo2 {

unsigned char *packet;
};

and I do:

struct foo *a;
struct foo2 *b;

a = malloc(sizeof(s truct foo));
if (a == NULL)
return NULL;
So a now points to a dynamically allocated struct foo.

(void)memset(a , 1, sizeof(struct foo));
This sets every byte of that struct to the value 1. Since the struct
consists of nothing but pointers, odds are that none of the members of
the struct contain a useful (or even valid) value.

b = (struct foo2 *)a;
The address returned by malloc is guaranteed to be properly aligned
for any object so b is valid and you can use it to treat the area as a
struct foo2.
Would foo2 just strip off the *packet?
foo2 is the tag for a struct. It doesn't "do" anything. The address
that b points is the start of a struct foo and is guaranteed to be the
address of the member packet in that struct. It also happens to be
the start of a mythical struct foo2 and is therefore also the address
of the member packet in that struct.

And what happens to *ip?
It is still there in the allocated area. Assigning the value in a to
the pointer b did nothing to the data in the area a points to.

I am trying to understand how C handles the typecast if
one structure pointed to has a different number of members
than the other. I am trying to understand how C99 treats
This makes no sense. The only thing being typecast is a pointer to
struct and not a struct itself. A pointer doesn't care about the size
of or quantity of members in the struct it points to.
this situation. Both of my pointers should be correctly
aligned.


The pointers are correctly aligned by virtue of malloc. If you had
coded
struct foo x;
a = &x;
b = (struct foo2*)a;
there would be no guarantee that b would be correctly aligned for a
struct foo2. The assignment would still be legal since the standard
requires all pointers to struct to have the same alignment and
representation but you cannot dereference b portably.

<<Remove the del for email>>
Nov 14 '05 #7
Barry Schwarz wrote:
On Tue, 23 Nov 2004 14:03:36 -0700, brian <tw*****@cox.ne t> wrote: [snip]
(void)memset( a, 1, sizeof(struct foo));
This should be to 0 or NULL. My mistake.

[snip]
I am trying to understand how C handles the typecast if
one structure pointed to has a different number of members
than the other. I am trying to understand how C99 treats

This makes no sense. The only thing being typecast is a pointer to
struct and not a struct itself. A pointer doesn't care about the size
of or quantity of members in the struct it points to.


I understand that I am just typecasting pointers. I was just trying to
confirm that the following holds true:

[struct foo * ][member 1][member 2]

[struct foo2 *][member 1]

that the memory addresses will overlap, so I can use a struct foo2
pointer to access the values in struct foo member 1 after I have
assigned values to whatever is pointed to. That the address of the
first member in foo will be the same address in foo2 by virtue of
malloc(). I'm sorry for not being more clear.

[snip]
The assignment would still be legal since the standard
requires all pointers to struct to have the same alignment and
representation but you cannot dereference b portably.


And I cannot dereference portably because the alignment restrictions
could be different?

Thanks,

brian
Nov 14 '05 #8
On Wed, 24 Nov 2004 13:59:50 -0700
brian <tw*****@cox.ne t> wrote:
Barry Schwarz wrote:
On Tue, 23 Nov 2004 14:03:36 -0700, brian <tw*****@cox.ne t> wrote:

[snip]
(void)memset( a, 1, sizeof(struct foo));


This should be to 0 or NULL. My mistake.


<snip>

That doesn't help much. Since the second argument is an int and NULL
could be ((void *)0) a call of
(void)memset(a, NULL, sizeof(struct foo));
could require a diagnostic.

Even a 0 does not help much as this would set it to all bits 0 and all
bits 0 might not be the correct value.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #9
On Wed, 24 Nov 2004 13:59:50 -0700, brian <tw*****@cox.ne t> wrote:
Barry Schwarz wrote:
On Tue, 23 Nov 2004 14:03:36 -0700, brian <tw*****@cox.ne t> wrote:[snip]
(void)memset (a, 1, sizeof(struct foo));
This should be to 0 or NULL. My mistake.


Not really. NULL would not portable because some systems define NULL
to be (void*)0. 0 is not portable either since their is no guarantee
that a pointer value of all bits 0 has any meaning.

[snip]
I am trying to understand how C handles the typecast if
one structure pointed to has a different number of members
than the other. I am trying to understand how C99 treats

This makes no sense. The only thing being typecast is a pointer to
struct and not a struct itself. A pointer doesn't care about the size
of or quantity of members in the struct it points to.


I understand that I am just typecasting pointers. I was just trying to
confirm that the following holds true:

[struct foo * ][member 1][member 2]

[struct foo2 *][member 1]

that the memory addresses will overlap, so I can use a struct foo2
pointer to access the values in struct foo member 1 after I have
assigned values to whatever is pointed to. That the address of the
first member in foo will be the same address in foo2 by virtue of
malloc(). I'm sorry for not being more clear.


There is only one address, the one returned by malloc. The fact that
you have stored this address in two different pointers doesn't change
that.

[snip]
The assignment would still be legal since the standard
requires all pointers to struct to have the same alignment and
representation but you cannot dereference b portably.


And I cannot dereference portably because the alignment restrictions
could be different?


Yup.

<<Remove the del for email>>
Nov 14 '05 #10

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

Similar topics

63
3417
by: andynaik | last post by:
Hi, Whenever we type in this code int main() { printf("%f",10); } we get an error. We can remove that by using #pragma directive t direct that to the 8087. Even after that the output is 0.00000 and no 10.0000. Can anybody tell me why it is like that and why typecasting i not done in this case?
11
4424
by: Vinod Patel | last post by:
I have a piece of code : - void *data; ...... /* data initialized */ ...... struct known_struct *var = (struct known_struct*) data; /*typecasting*/ How is this different from simple assignment. int b = some_value;
3
3994
by: bnoordhuis | last post by:
Consider this: int foo(int *a, int *b); int (*bar)(void *, void *) = (void *)foo; How legal - or illegal - is the typecast and are there real-world situations where such code will cause trouble? I don't mean trouble like in 'not compiling' but trouble like in 'crashing hard'.
16
10397
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 do you mean by pointing to a void and why is it done? Aso, what happens when we typecast a pointer to another type. say for example int *i=(char *)p; under different situations? I am kind of confused..can anybody clear this confusion by clearly...
12
8396
by: srinivas.satish | last post by:
Hi, is it possible to typecast a function pointer to two different prototypes. eg., typedef void (functptr1 *) (int , int); typedef void (functptr2 *) (int); functptr1 fptr; fptr = somefunction_name; fptr(10,20); fptr = (functptr2)someotherfunction_name;
5
11246
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 function pointer to const void* in C-style void(*pFunc)() = (void(*)())(arg); // type casting const void* to function pointer in C-style (*pFunc)(); // Calling the function after type casting is done
12
4479
by: bwaichu | last post by:
What is the best way to handle this warning: warning: cast from pointer to integer of different size I am casting in and out of a function that requires a pointer type. I am casting an integer as a pointer, but the pointer is 8 bytes while the integer is only 4 bytes. Here's an example function:
12
1730
by: chadsspameateremail | last post by:
What I am trying to do is implement polymorphism in C. Why? This is to build a library which will be a C library and callable from C. However, I want to have polymorphic functions which are callable from outside the library. Specifically I want to have functions like Show() which will take a pointer to an object and do something different based on the type object passed to it. Of course this would be trival in C++ but I'm restricted to use...
3
13127
by: sritejv | last post by:
Hello everyone, I am having a problem with typecasting void pointers.I have read the pointer basics but still cant understand why the following test code doesnt work. void *xyz; struct abcd { int a; };
0
9617
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10257
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10037
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8931
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6710
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5354
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5482
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4007
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3609
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.