简体   繁体   中英

include changes sizeof in_addr in struct

Ok, I've got a struct containing a struct in_addr element. This should make struct addrlist_t at least 12 Bytes in size (8 + 4) . The platform is amd64 .

#include <netinet/in.h> // struct in_addr
#include <stdio.h> // printf()
#include <netdb.h> // toggles size of struct addrlist_t

struct addrlist_t {
    struct addrlist_t *next;
    struct in_addr h_addr;
};

int main(int argc, char *argv[]) {
    printf("%zu + %zu = %zu\n",
        sizeof (struct addrlist_t *), sizeof (struct in_addr), 
        sizeof (struct addrlist_t)
    );
    return 0;
}

This is the totally unexpected output:

$cc main.c -o main -Wall -Wwrite-strings -pedantic -std=gnu99 -Wall -Werror
$./main
8 + 4 = 8

This seems to make no sense. The combined size should be at least 12, not smaller!

But now, when #include &lt;netdb.h&gt; is removed, the expected output appears:

$./main
8 + 4 = 16

The same things happens when -std=gnu99 is replaced by -std=c99 .

Can someone explain this behavior?

For completeness:

$file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=709ab89d012d8b5a6ae7423fd80ce643288cba95, not stripped

Edit: formatting / words

This is because you have an unfortunate name for the struct in_addr h_addr member.

<netdb.h> in glibc contains this:

# define    h_addr  h_addr_list[0] /* Address, for backward compatibility.*/                       

Run gcc -E main.c to see how your code looks after preprossessing, your struct addrlist_t essentially becomes this:

struct addrlist_t {
    struct addrlist_t *next;
    struct in_addr h_addr_list[0];
};

Which is a very different thing from what you intended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM