Given
struct in_addr variable;
then
&variable == &(variable.s_addr)
however
sizeof(variable) =?= sizeof(variable.s_addr)
You can't make any safe portable assumptions about the sizeof the struct and
any/all of its fields.
In practice any CPU you're likely to use will not pad an unsigned long. If you
want to restrict your software to such machines, you're not going to lose too
many customers.
For my code I run a small program as part of the build which does like
int main(int argc, cahr**argv) {
FILE *f = fopen("sizes.h", "w");
fprintf(f,"#define size_unsigned_long %d\n", sizeof(unsigned long));
fprintf(f,"#define size_time_t %d\n", sizeof(time_t));
fprintf(f,"#define size_struct_in_addr %d\n", sizeof(struct in_addr));
...
return 0
}
Then you can do things like
#include "sizes.h"
#if size_unsigned_long!=size_struct_in_addr
#error Cannot compile: sizeof(unsigned long)!=sizeof(struct in_addr)
#endif
There is a different way of doing this which does not rely on a
generated file (so no chance of going stale or missing), nor pollute the
defines with lower case characters.
#define BUILD_BUG_IF(condition) ((void)sizeof(struct {
int:-!!(condition); }))
at which point, your code becomes
BUILD_BUG_IF(sizeof(unsigned long) != sizeof(struct in_addr));
True, your error message then becomes "error: negative width in
bit-field ‘<anonymous>’" or similar, but you do get the file and line
number of the failure, which then allows anyone to see why compiling failed.
~Andrew