Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #22867 > unrolled thread
| Started by | "Mark" <mark_cruzNOTFORSPAM@hotmail.com> |
|---|---|
| First post | 2012-06-27 12:33 -0400 |
| Last post | 2012-06-27 18:03 -0700 |
| Articles | 8 — 8 participants |
Back to article view | Back to comp.lang.c
struct with one member: padding? "Mark" <mark_cruzNOTFORSPAM@hotmail.com> - 2012-06-27 12:33 -0400
Re: struct with one member: padding? John Gordon <gordon@panix.com> - 2012-06-27 16:40 +0000
Re: struct with one member: padding? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-27 18:27 +0100
Re: struct with one member: padding? Ben Pfaff <blp@cs.stanford.edu> - 2012-06-27 09:57 -0700
Re: struct with one member: padding? China Blue Meanies <chine.bleu@yahoo.com> - 2012-06-27 12:15 -0700
Re: struct with one member: padding? Andrew Cooper <amc96@cam.ac.uk> - 2012-06-27 22:52 +0100
Re: struct with one member: padding? scott@slp53.sl.home (Scott Lurndal) - 2012-06-27 23:42 +0000
Re: struct with one member: padding? William Ahern <william@wilbur.25thandClement.com> - 2012-06-27 18:03 -0700
| From | "Mark" <mark_cruzNOTFORSPAM@hotmail.com> |
|---|---|
| Date | 2012-06-27 12:33 -0400 |
| Subject | struct with one member: padding? |
| Message-ID | <jsfckr$drq$1@speranza.aioe.org> |
Hello
on many (all?) unix implementations IP address structure is designed this
way:
struct in_addr
{
unsigned long s_addr;
};
Does the Standard allow a C comiler to add padding in such structure? If it
so, then we have to always 'memset' in_addr to 0 before use.
Thanks.
Mark
[toc] | [next] | [standalone]
| From | John Gordon <gordon@panix.com> |
|---|---|
| Date | 2012-06-27 16:40 +0000 |
| Message-ID | <jsfd2q$r2u$1@reader1.panix.com> |
| In reply to | #22867 |
In <jsfckr$drq$1@speranza.aioe.org> "Mark" <mark_cruzNOTFORSPAM@hotmail.com> writes:
> struct in_addr
> {
> unsigned long s_addr;
> };
> Does the Standard allow a C comiler to add padding in such structure? If it
> so, then we have to always 'memset' in_addr to 0 before use.
If you're accessing in_addr.s_addr, why do you care if there is padding
before or after?
If you're trying to access in_addr as though it were not a struct I can
see why you would care, but that seems to be a pretty egregious error.
--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-06-27 18:27 +0100 |
| Message-ID | <0.c0f7244cec4de6609095.20120627182742BST.87k3yshdgx.fsf@bsb.me.uk> |
| In reply to | #22869 |
John Gordon <gordon@panix.com> writes:
> In <jsfckr$drq$1@speranza.aioe.org> "Mark" <mark_cruzNOTFORSPAM@hotmail.com> writes:
>
>> struct in_addr
>> {
>> unsigned long s_addr;
>> };
>
>> Does the Standard allow a C comiler to add padding in such structure? If it
>> so, then we have to always 'memset' in_addr to 0 before use.
>
> If you're accessing in_addr.s_addr, why do you care if there is padding
> before or after?
>
> If you're trying to access in_addr as though it were not a struct I can
> see why you would care, but that seems to be a pretty egregious error.
I think that depends how you do it.
It's probably worth pointing out that there can't be any padding before
s_addr, only after. I.e. sizeof (struct in_addr) may be greater than
sizeof (long) but
struct in_addr a;
assert((void *)&a == (void *)&a.s_addr);
can't fail. Thus
unsigned char bytes[sizeof (long)];
memcpy(bytes, &a, sizeof bytes);
kind of fits your "access in_addr as though it were not a struct" but it's
safe.
None the less, I agree that the question hints that something dangerous
might be being considered!
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ben Pfaff <blp@cs.stanford.edu> |
|---|---|
| Date | 2012-06-27 09:57 -0700 |
| Message-ID | <87bok4wv44.fsf@blp.benpfaff.org> |
| In reply to | #22867 |
"Mark" <mark_cruzNOTFORSPAM@hotmail.com> writes:
> on many (all?) unix implementations IP address structure is designed this
> way:
>
> struct in_addr
> {
> unsigned long s_addr;
> };
>
> Does the Standard allow a C comiler to add padding in such
> structure?
Yes. (I don't know of any implementations that will.)
[toc] | [prev] | [next] | [standalone]
| From | China Blue Meanies <chine.bleu@yahoo.com> |
|---|---|
| Date | 2012-06-27 12:15 -0700 |
| Message-ID | <chine.bleu-59CFD2.12151527062012@news.eternal-september.org> |
| In reply to | #22867 |
In article <jsfckr$drq$1@speranza.aioe.org>,
"Mark" <mark_cruzNOTFORSPAM@hotmail.com> wrote:
> Hello
>
> on many (all?) unix implementations IP address structure is designed this
> way:
>
> struct in_addr
> {
> unsigned long s_addr;
> };
>
> Does the Standard allow a C comiler to add padding in such structure? If it
> so, then we have to always 'memset' in_addr to 0 before use.
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
--
My name Indigo Montoya. | The Dude abides.
You flamed my father. | I'm whoever you want me to be.
Prepare to be spanked. | Annoying Usenet one post at a time.
Stop posting that! | At least I can stay in character.
[toc] | [prev] | [next] | [standalone]
| From | Andrew Cooper <amc96@cam.ac.uk> |
|---|---|
| Date | 2012-06-27 22:52 +0100 |
| Message-ID | <dgLGr.338518$C_6.224852@fx28.am4> |
| In reply to | #22889 |
On 27/06/2012 20:15, China Blue Meanies wrote:
> In article <jsfckr$drq$1@speranza.aioe.org>,
> "Mark" <mark_cruzNOTFORSPAM@hotmail.com> wrote:
>
>> Hello
>>
>> on many (all?) unix implementations IP address structure is designed this
>> way:
>>
>> struct in_addr
>> {
>> unsigned long s_addr;
>> };
>>
>> Does the Standard allow a C comiler to add padding in such structure? If it
>> so, then we have to always 'memset' in_addr to 0 before use.
>
> 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
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2012-06-27 23:42 +0000 |
| Message-ID | <sTMGr.43373$0I1.319@news.usenetserver.com> |
| In reply to | #22901 |
Andrew Cooper <amc96@cam.ac.uk> writes:
>On 27/06/2012 20:15, China Blue Meanies wrote:
>> In article <jsfckr$drq$1@speranza.aioe.org>,
>> "Mark" <mark_cruzNOTFORSPAM@hotmail.com> wrote:
>>
>>> Hello
>>>
>>> on many (all?) unix implementations IP address structure is designed this
>>> way:
>>>
>>> struct in_addr
>>> {
>>> unsigned long s_addr;
>>> };
>>>
>>> Does the Standard allow a C comiler to add padding in such structure? If it
>>> so, then we have to always 'memset' in_addr to 0 before use.
>>
>> 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.
>
If your code depends on sizeof(struct in_addr) in any way, it's broken
by design. There should be no need for an application to do anything
with the fields in in_addr, other than specific copy operations between
two in_addr structures. There are library functions to modify or set
the correct values in this structure, for example:
/*
* Listen on all interfaces
*/
self.sin_addr.s_addr = INADDR_ANY;
/*
* Translate a text hostname/dotted-quad to in_addr
*/
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;
diag = getaddrinfo(n_hostname, NULL, &hints, &res);
if (diag != 0) {
n_logger->log("%s Unable to determine"
" interface address for '%s': %s\n",
n_subsys, n_hostname, gai_strerror(diag));
n_logger->log("%s Using INADDR_ANY\n", n_subsys);
self.sin_addr.s_addr = INADDR_ANY;
} else {
struct sockaddr_in *sinp = (struct sockaddr_in *)res->ai_addr;
self.sin_addr.s_addr = sinp->sin_addr.s_addr;
}
[toc] | [prev] | [next] | [standalone]
| From | William Ahern <william@wilbur.25thandClement.com> |
|---|---|
| Date | 2012-06-27 18:03 -0700 |
| Message-ID | <a3nsb9-3pf.ln1@wilbur.25thandClement.com> |
| In reply to | #22867 |
In comp.unix.programmer Mark <mark_cruzNOTFORSPAM@hotmail.com> wrote:
> Hello
> on many (all?) unix implementations IP address structure is designed this
> way:
In 2012 there are IPv4 addresses and IPv6 addresses, and all extant systems
support both. Therefore, your statement is incorrect because struct in_addr
is no longer sufficient to store an IP address. Indeed, there is no standard
data structure to hold an IP address anymore, for better or worse. The
closest standard data structure is a struct sockaddr_storage.
If you need to manipulate IP addresses in non-trivial ways, it's probably
best to just define your own data structures.
> struct in_addr
> {
> unsigned long s_addr;
> };
> Does the Standard allow a C comiler to add padding in such structure? If
> it so, then we have to always 'memset' in_addr to 0 before use.
There's no requirement that you must use memset. Assigning 0 to .s_addr
should suffice. In fact, I don't believe it's common to use memset that
way at all. You may be thinking of using memset to 0 initialize struct
sockaddr and cousins.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web