473,326 Members | 2,113 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,326 software developers and data experts.

Typecasting Structures?

I'm struggling with the concept of typecasting when
setting up a TCP client.

Here's a code snip (modified from W. Richard Stevens Unix Programming
book) to demonstrate where I am struggling:

int sockfd;
struct sockaddr_in servaddr;

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13); /* PORT 13 */

/* argv[1] = "127.0.0.1" */

if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr)) <= 0 ) {
perror("inet_pton()");
exit(1);
}

if ( (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) <
0) {
perror("connect()");
exit(1);
}

When this line occurs:

(struct sockaddr *) &servaddr

the previously assigned values within servaddr are typecast to struct
sockaddr,
which is defined as:

struct sockaddr {
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};

My confusion is how sa_data[14] becomes populated. I do not
understand the conversion.

Can anyone help me out?

I stepped through the code creating a pointer of type struct sockaddr
and pointed it to the address of servaddr. But I do not understand
why sa_data[14] would have data looking like \111\0\r\0\0 . . .
nor do I understand how to convert that string back to it's original
form.

Any help would be appreciated.

Thanks,

Brian

P.S. I'm compiling using gcc, and debuggin with gdb.
Nov 14 '05 #1
8 7817
In <kd_xc.30342$My6.16406@fed1read05> tweak <bw********@cox.net> writes:
When this line occurs:

(struct sockaddr *) &servaddr

the previously assigned values within servaddr are typecast to struct
sockaddr,


Nonsense! This is a *pointer* cast that has no effect on the values of
the members of servaddr. To understand the effect, you have to
compare the definitions of the two structures.

IIRC, reading the book provides all the enlightenment. Don't play with
the examples *without* reading *all* the relevant text.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #2
Dan Pop wrote:
In <kd_xc.30342$My6.16406@fed1read05> tweak <bw********@cox.net> writes:

When this line occurs:

(struct sockaddr *) &servaddr

the previously assigned values within servaddr are typecast to struct
sockaddr,

Nonsense! This is a *pointer* cast that has no effect on the values of
the members of servaddr. To understand the effect, you have to
compare the definitions of the two structures.

IIRC, reading the book provides all the enlightenment. Don't play with
the examples *without* reading *all* the relevant text.

Dan


I understand the text just fine. It's when I assign the pointer to
another pointer of the type being cast to and look at the dereferenced
values that I get confused.

If I declare the structure

struct sockaddr_in servaddr

and I put in

servaddr.sin_family = AF_INET; /* which corresponds to a value */

and I put in

servaddr.sin_port = htons(13) /* which converts port 13 and assigns it
to sin_port */

and I place a value in sin_addr. According to my debugger, my structure
looks like:

servaddr = {sin_family =2, sin_port = 3328, sin_addr = {s_addr =
16777343}, sin_zero = "\0\0\0\0\0\0\0"}

Now, for the connect() function, I am passing a pointer and typecasting
it. I'm okay with that.

If I want to see what the values change to during that typecast, I
create a structure of the type being cast to as follows:

struct sockaddr *test;

I then make the assignment:

test = (struct sockaddr *) &servaddr

now, in my debugger, I just ask to display the deference to that pointer
*test, and I get:

*test = {sa_family = 2, sa_data = "\0\r\177\0\0\001\0\0\0\0\0\0\0"}

I do not understand why sa_data is converted to that string.

I hope that clarifies. I am okay with setting up clients and servers;
I'm just stuck on how C is working above.

Cheers,

Brian
Nov 14 '05 #3
"tweak" <bw********@cox.net> wrote in message
news:DD7yc.30429$My6.1362@fed1read05...
I understand the text just fine. It's when I assign the pointer to
another pointer of the type being cast to and look at the dereferenced
values that I get confused. .... servaddr = {sin_family =2, sin_port = 3328, sin_addr = {s_addr =
16777343}, sin_zero = "\0\0\0\0\0\0\0"} .... *test = {sa_family = 2, sa_data = "\0\r\177\0\0\001\0\0\0\0\0\0\0"}

I do not understand why sa_data is converted to that string.


It isn't "converted" to that string. That is your machine's representation
of the sin_port, sin_addr, and sin_zero fields in your sockaddr_in.

sin_port = 3328 = 0x0D00
sin_addr = 16777343 = 0x0100007f
sin_zero = 0x00000000000000

Once you adjust for your machine being little endian, you get:

sa_data = 0x000D7F00000100000000000000

Casting one pointer type to another merely causes the compiler to interpret
the object pointed to in a different manner -- it doesn't change what's
actually there.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin

Nov 14 '05 #4
On Thu, 10 Jun 2004 18:08:37 -0700, tweak <bw********@cox.net> wrote
in comp.lang.c:

First your title displays a fundamental misunderstanding that is
augmenting your confusion.

You _are not_ casting structures, and you _cannot_ cast structures in
C.

You can cast a pointer to any type of object to a pointer to any other
type of object at all, and that is what you are doing here.
I understand the text just fine. It's when I assign the pointer to
another pointer of the type being cast to and look at the dereferenced
values that I get confused.
As far as the C standard is concerned, there is no requirement that
dereferencing such a pointer has defined behavior at all.
If I declare the structure

struct sockaddr_in servaddr
Not a standard C data type.
and I put in

servaddr.sin_family = AF_INET; /* which corresponds to a value */

and I put in

servaddr.sin_port = htons(13) /* which converts port 13 and assigns it
to sin_port */
Not a standard C function.

[snip]
I hope that clarifies. I am okay with setting up clients and servers;
I'm just stuck on how C is working above.


As far as C is concerned, when you play type punning you are
responsible for knowing what you are doing, with any sort of undefined
behavior as a consequence. If the members of the two structure types
are different there is a good chance that when accessing some of the
members you will be accessing objects with different lvalues than the
objects were written with. In that case, C is not working at all,
this produces undefined behavior in which case the C standard makes no
guarantees or requirements at all about what will happen.

Exactly what might or might not happen on your implementation, if it
is predictable at all, depends on a combination of at least three
things.

One of these is the definition of the data types, and neither of these
structure types are defined by standard C. They are non-standard
extensions provided by your compiler/OS, and so off-topic here.

The second factor is the underlying hardware architecture of your
platform, which is also not defined by the C standard and is off-topic
here.

The final factor is your particular compiler, and how it chooses to
act in this instance. Specific compilers are also off-topic here.

So your question is about how your specific compiler reacts when you
invoke undefined behavior by punning two non-standard structure types.
There is not one single aspect of this question that is NOT off-topic
here.

You need to ask this question in a group that supports your particular
compiler/OS combination, such as news:comp.os.linux.development.apps
or news:comp.unix.programmer. It is just plain not a C language
question at all.

--
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
Nov 14 '05 #5
This is what I was looking for. Sorry about being cryptic.

Cheers,

Brian

Stephen Sprunk wrote:
"tweak" <bw********@cox.net> wrote in message
news:DD7yc.30429$My6.1362@fed1read05...
I understand the text just fine. It's when I assign the pointer to
another pointer of the type being cast to and look at the dereferenced
values that I get confused.


...
servaddr = {sin_family =2, sin_port = 3328, sin_addr = {s_addr =
16777343}, sin_zero = "\0\0\0\0\0\0\0"}


...
*test = {sa_family = 2, sa_data = "\0\r\177\0\0\001\0\0\0\0\0\0\0"}

I do not understand why sa_data is converted to that string.

It isn't "converted" to that string. That is your machine's representation
of the sin_port, sin_addr, and sin_zero fields in your sockaddr_in.

sin_port = 3328 = 0x0D00
sin_addr = 16777343 = 0x0100007f
sin_zero = 0x00000000000000

Once you adjust for your machine being little endian, you get:

sa_data = 0x000D7F00000100000000000000

Casting one pointer type to another merely causes the compiler to interpret
the object pointed to in a different manner -- it doesn't change what's
actually there.

S

Nov 14 '05 #6
So that I can ask questions on topic, what do you consider C?

ANSI C? C99 C? K&R2 C? ISO C?

Even a simple type will change size based on the system it is
running on. How do you talk about programming C without
talking about how to write portable C software? Isn't that part
of the art? Programs like Mozilla and Apache that can run
on different systems and OS's are impressive.

Cheers,

Brian
Jack Klein wrote:
On Thu, 10 Jun 2004 18:08:37 -0700, tweak <bw********@cox.net> wrote
in comp.lang.c:

First your title displays a fundamental misunderstanding that is
augmenting your confusion.

You _are not_ casting structures, and you _cannot_ cast structures in
C.

You can cast a pointer to any type of object to a pointer to any other
type of object at all, and that is what you are doing here.

I understand the text just fine. It's when I assign the pointer to
another pointer of the type being cast to and look at the dereferenced
values that I get confused.

As far as the C standard is concerned, there is no requirement that
dereferencing such a pointer has defined behavior at all.

If I declare the structure

struct sockaddr_in servaddr

Not a standard C data type.

and I put in

servaddr.sin_family = AF_INET; /* which corresponds to a value */

and I put in

servaddr.sin_port = htons(13) /* which converts port 13 and assigns it
to sin_port */

Not a standard C function.

[snip]

I hope that clarifies. I am okay with setting up clients and servers;
I'm just stuck on how C is working above.

As far as C is concerned, when you play type punning you are
responsible for knowing what you are doing, with any sort of undefined
behavior as a consequence. If the members of the two structure types
are different there is a good chance that when accessing some of the
members you will be accessing objects with different lvalues than the
objects were written with. In that case, C is not working at all,
this produces undefined behavior in which case the C standard makes no
guarantees or requirements at all about what will happen.

Exactly what might or might not happen on your implementation, if it
is predictable at all, depends on a combination of at least three
things.

One of these is the definition of the data types, and neither of these
structure types are defined by standard C. They are non-standard
extensions provided by your compiler/OS, and so off-topic here.

The second factor is the underlying hardware architecture of your
platform, which is also not defined by the C standard and is off-topic
here.

The final factor is your particular compiler, and how it chooses to
act in this instance. Specific compilers are also off-topic here.

So your question is about how your specific compiler reacts when you
invoke undefined behavior by punning two non-standard structure types.
There is not one single aspect of this question that is NOT off-topic
here.

You need to ask this question in a group that supports your particular
compiler/OS combination, such as news:comp.os.linux.development.apps
or news:comp.unix.programmer. It is just plain not a C language
question at all.

Nov 14 '05 #7
tweak wrote:
Jack Klein wrote:
On Thu, 10 Jun 2004 18:08:37 -0700, tweak <bw********@cox.net> wrote
in comp.lang.c:

First your title displays a fundamental misunderstanding that is
augmenting your confusion.


"Typecasting" is something that happens to thespians.

--
pete
Nov 14 '05 #8
tweak <bw********@cox.net> scribbled the following:
So that I can ask questions on topic, what do you consider C? ANSI C? C99 C? K&R2 C? ISO C?


AFAIK "ANSI C" and "ISO C" are the same thing, and "C99 C" is a form
of "ANSI C" or "ISO C". ANSI and ISO are standards organisations, while
C99 is a standard. Therefore C89 C, C90 C and C99 C are all "ANSI C" or
"ISO C".
"K&R2 C" is pretty much the same as "ANSI C" or "ISO C" technically, but
juridically, it does not define C.

This newsgroup is only for discussion about the standard C programming
language. System-specific extensions are off-topic, no matter how great
they are.
I'll leave it to someone else to explain in more detail.

PS. Please don't top-post.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"To know me IS to love me."
- JIPsoft
Nov 14 '05 #9

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

Similar topics

3
by: Robert Street | last post by:
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 {
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...
1
by: b83503104 | last post by:
When are they not consistent?
63
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...
11
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...
13
by: brian | last post by:
Quick question: if I have a structure: struct foo { unsigned char *packet; unsigned char *ip_src; };
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...
12
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...
13
by: aki | last post by:
i am receiving a buffer from network as char pointer. char * buffer; this is an argument of my function. well i want to decode this buffer. buffer contain a packet with different fields as ...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.