DannyD
DannyD

Reputation: 2901

Having trouble understanding a struct in C

I'm working on a networking project and I came across this struct in the skeleton code I'm working with:

struct sr_icmp_hdr {
   uint8_t icmp_type;
   uint8_t icmp_code;
   uint16_t icmp_sum;
} __attribute__ ((packed)) ;
typedef struct sr_icmp_hdr sr_icmp_hdr_t;

Can someone explain what the code following the struct is? What is __attribute__ or a typedef?

I'm used to seeing this in C++:

struct hi{
    int thisIsAnInt;
    double thisIsADouble;
} 

and declaring a struct like this:

hi hello;
cout << hello.thisIsAnInt;

Is this different in C?

Upvotes: 0

Views: 125

Answers (3)

M.M
M.M

Reputation: 141648

For the last part of your question, C does not have overloaded operators for output, but you could go:

hi hello = { 2, 1. };
printf("%d\n", hello.thisIsAnInt);

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 755064

In C++, when you define or declare a class or struct, the tag name is automatically available for use as a type name.

In C, this does not happen, so to get the same effect as in C++, you have to add:

typedef struct xxx xxx;

Some people prefer to keep the structure tags separate from the type names, though they're in separate namespaces and it isn't necessary. I almost always use the same name for the tag and the type name to emphasize that they're referring to the same type.

Hence:

struct sr_icmp_hdr {
   uint8_t icmp_type;
   uint8_t icmp_code;
   uint16_t icmp_sum;
} __attribute__ ((packed));

This defines struct sr_icmp_hdr; the attribute is noise. The attribute is not a standardized part of C, but is implemented in GCC. It ensures that there are no padding bytes within the structure, though the layout is such that only a perverse compiler would add padding bytes in the first place. Hence my characterization of it as 'noise'. (I've been coding in C for quite a while and not had cause to use it. Clearly, other people have different experiences or it wouldn't be in the compiler.)

typedef struct sr_icmp_hdr sr_icmp_hdr_t;

This defines a type name sr_icmp_hdr_t that is an alias for struct sr_icmp_hdr. More generally, typedef introduces an alternative name for a type. For example, uint8_t is a typedef defined in <stdint.h> in C; likewise uint16_t. Such names are used to promote portability, in general.

Note that C++ permits typedef struct xxx xxx; even though it is not necessary.

Upvotes: 2

Ashalynd
Ashalynd

Reputation: 12573

1) attribute packed is a GCC specific declaration (not part of C standard). It is described here: http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html

This particular attribute is a hint for the compiler to use as little memory as possible to store the objects of the described struct.

2) Unlike C++, in C, without that typedef you would have to declare the objects of the given struct as:

struct sr_icmp_hdr mystruct;

Upvotes: 1

Related Questions