* sizeof problem in kernel modules
@ 2001-06-23 14:54 Der Herr Hofrat
2001-06-23 15:18 ` Keith Owens
` (3 more replies)
0 siblings, 4 replies; 18+ messages in thread
From: Der Herr Hofrat @ 2001-06-23 14:54 UTC (permalink / raw)
To: linux-kernel
Hi !
can someone explain to me whats happening here ?
--simple.c--
#include <linux/module.h>
#include <linux/kernel.h>
struct { short x; long y; short z; }bad_struct;
struct { long y; short x; short z; }good_struct;
int init_module(void){
printk("good_struct %d, bad_struct %d\n",sizeof(good_struct),sizeof(bad_struct));
return 0;
}
void cleanup_module(void){
}
--Makefile--
all: simple.o
CC= gcc
CFLAGS= -pipe -fno-strength-reduce -DCPU=686 -march=i686 \
-Wall -Wstrict-prototypes -g -D__KERNEL__ -DMODULE \
-D_LOOSE_KERNEL_NAMES -O2 -c
INCLUDE= -I/usr/include/linux
clean:
rm -f simple.o
---------------------------------------------------------------
I would expect both structs to be 8byte in size , or atleast the same size !
but good_struct turns out to be 8bytes and bad_struct 12 .
what am I doing wrong here ?
thx !
hofrat
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: sizeof problem in kernel modules 2001-06-23 14:54 sizeof problem in kernel modules Der Herr Hofrat @ 2001-06-23 15:18 ` Keith Owens 2001-06-23 15:30 ` Russell King ` (2 subsequent siblings) 3 siblings, 0 replies; 18+ messages in thread From: Keith Owens @ 2001-06-23 15:18 UTC (permalink / raw) To: Der Herr Hofrat; +Cc: linux-kernel On Sat, 23 Jun 2001 16:54:20 +0200 (CEST), Der Herr Hofrat <der.herr@hofr.at> wrote: >struct { short x; long y; short z; }bad_struct; >struct { long y; short x; short z; }good_struct; >I would expect both structs to be 8byte in size , or atleast the same size ! >but good_struct turns out to be 8bytes and bad_struct 12 . Read any C book about field alignment and padding in structures. Nothing to do with the kernel or modules. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-23 14:54 sizeof problem in kernel modules Der Herr Hofrat 2001-06-23 15:18 ` Keith Owens @ 2001-06-23 15:30 ` Russell King 2001-06-24 1:56 ` Richard B. Johnson 2001-06-25 4:33 ` Anil Kumar 3 siblings, 0 replies; 18+ messages in thread From: Russell King @ 2001-06-23 15:30 UTC (permalink / raw) To: Der Herr Hofrat; +Cc: linux-kernel On Sat, Jun 23, 2001 at 04:54:20PM +0200, Der Herr Hofrat wrote: > struct { short x; long y; short z; }bad_struct; > struct { long y; short x; short z; }good_struct; > > I would expect both structs to be 8byte in size , or atleast the same size ! > but good_struct turns out to be 8bytes and bad_struct 12 . > > what am I doing wrong here ? You're expecting the compiler to lay them out without any spacing between them. There is no such requirement in C. The compiler knows that its more efficient for long words to be accessed on a long word boundary, so it wastes two bytes after each short in your bad_struct case. However, it won't waste them in this case, because there isn't a long: struct { short x; short y; short z; } If you really really really want that layout, then use __attribute__((packed)) (read the gcc info files to find out what this does), but don't unless you absolutely must. Here is another struct layout example: struct foo { short x; char y; /* implicit 1 byte padding after this element */ short z; }; Again, the 1 byte padding can be removed by use of the __attribute__ above. -- Russell King (rmk@arm.linux.org.uk) The developer of ARM Linux http://www.arm.linux.org.uk/personal/aboutme.html ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-23 14:54 sizeof problem in kernel modules Der Herr Hofrat 2001-06-23 15:18 ` Keith Owens 2001-06-23 15:30 ` Russell King @ 2001-06-24 1:56 ` Richard B. Johnson 2001-06-24 2:12 ` Keith Owens 2001-06-25 4:33 ` Anil Kumar 3 siblings, 1 reply; 18+ messages in thread From: Richard B. Johnson @ 2001-06-24 1:56 UTC (permalink / raw) To: Der Herr Hofrat; +Cc: linux-kernel On Sat, 23 Jun 2001, Der Herr Hofrat wrote: > > Hi ! > > can someone explain to me whats happening here ? > > --simple.c-- > #include <linux/module.h> > #include <linux/kernel.h> > > struct { short x; long y; short z; }bad_struct; > struct { long y; short x; short z; }good_struct; > [SNIPPED...] > --------------------------------------------------------------- > > I would expect both structs to be 8byte in size , or atleast the same size ! > but good_struct turns out to be 8bytes and bad_struct 12 . > > what am I doing wrong here ? You are assuming something that is wrong. Many programmers use a structure as a "template", assuming that what they write is exactly what exists in memory. This is not how the 'C' standards are written! The only thing guaranteed by the standard is that the first structure member will exist as the same address as the structure itself -- nothing else. So that structures can be used as templates, many compilers including gcc, have non-standard extensions that can be used to "pack" structure members. __attribute__ ((packed)) will probably do what you want. FYI, structures are designed to be accessed only by their member-names. Therefore, the compiler is free to put members at any offset. In fact, members, other than the first, don't even have to be in the order written! Cheers, Dick Johnson Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips). "Memory is like gasoline. You use it up when you are running. Of course you get it all back when you reboot..."; Actual explanation obtained from the Micro$oft help desk. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-24 1:56 ` Richard B. Johnson @ 2001-06-24 2:12 ` Keith Owens 2001-06-24 2:43 ` Richard B. Johnson 0 siblings, 1 reply; 18+ messages in thread From: Keith Owens @ 2001-06-24 2:12 UTC (permalink / raw) To: root; +Cc: linux-kernel On Sat, 23 Jun 2001 21:56:06 -0400 (EDT), "Richard B. Johnson" <root@chaos.analogic.com> wrote: >FYI, structures are designed to be accessed only by their member-names. >Therefore, the compiler is free to put members at any offset. In fact, >members, other than the first, don't even have to be in the order >written! Bzzt! I don't know where people get these ideas from. Extracts from the C9X draft. A structure type describes a sequentially allocated nonempty set of member objects (and, in certain circumstances, an incomplete array), each of which has an optionally specified name and possibly distinct type. When two pointers are compared ... If the objects pointed to are members of the same aggregate object, pointers to structure members declared later compare greater than pointers to members declared earlier in the structure. Two objects may be adjacent in memory because they are adjacent elements of a larger array or adjacent members of a structure with no padding between them, As discussed in 6.2.5, a structure is a type consisting of a sequence of members, whose storage is allocated in an ordered sequence, Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared C requires that members of a structure be defined in ascending address order as specified by the programmer. The compiler may not reorder structure fields, although bitfields are a special case. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-24 2:12 ` Keith Owens @ 2001-06-24 2:43 ` Richard B. Johnson 2001-06-24 16:07 ` Lieven Marchand ` (2 more replies) 0 siblings, 3 replies; 18+ messages in thread From: Richard B. Johnson @ 2001-06-24 2:43 UTC (permalink / raw) To: Keith Owens; +Cc: linux-kernel On Sun, 24 Jun 2001, Keith Owens wrote: > On Sat, 23 Jun 2001 21:56:06 -0400 (EDT), > "Richard B. Johnson" <root@chaos.analogic.com> wrote: > >FYI, structures are designed to be accessed only by their member-names. > >Therefore, the compiler is free to put members at any offset. In fact, > >members, other than the first, don't even have to be in the order > >written! > > Bzzt! I don't know where people get these ideas from. Extracts from > the C9X draft. > > A structure type describes a sequentially allocated nonempty set of > member objects (and, in certain circumstances, an incomplete array), > each of which has an optionally specified name and possibly distinct > type. > > When two pointers are compared ... If the objects pointed to are > members of the same aggregate object, pointers to structure members > declared later compare greater than pointers to members declared > earlier in the structure. > > Two objects may be adjacent in memory because they are adjacent > elements of a larger array or adjacent members of a structure with no > padding between them, > > As discussed in 6.2.5, a structure is a type consisting of a sequence > of members, whose storage is allocated in an ordered sequence, > > Within a structure object, the non-bit-field members and the units > in which bit-fields reside have addresses that increase in the order > in which they are declared > > C requires that members of a structure be defined in ascending address > order as specified by the programmer. The compiler may not reorder > structure fields, although bitfields are a special case. > Previous to the "Draft" "Proposal" of C98, there were no such requirements. And so-called ANSI -C specifically declined to define any order within structures. Cheers, Dick Johnson Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips). "Memory is like gasoline. You use it up when you are running. Of course you get it all back when you reboot..."; Actual explanation obtained from the Micro$oft help desk. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-24 2:43 ` Richard B. Johnson @ 2001-06-24 16:07 ` Lieven Marchand 2001-06-24 16:11 ` frank 2001-06-25 0:26 ` Michael Meissner 2 siblings, 0 replies; 18+ messages in thread From: Lieven Marchand @ 2001-06-24 16:07 UTC (permalink / raw) To: root; +Cc: Keith Owens, linux-kernel "Richard B. Johnson" <root@chaos.analogic.com> writes: > On Sun, 24 Jun 2001, Keith Owens wrote: > > > On Sat, 23 Jun 2001 21:56:06 -0400 (EDT), > > "Richard B. Johnson" <root@chaos.analogic.com> wrote: > > >FYI, structures are designed to be accessed only by their member-names. > > >Therefore, the compiler is free to put members at any offset. In fact, > > >members, other than the first, don't even have to be in the order > > >written! > > > > Bzzt! I don't know where people get these ideas from. Extracts from > > the C9X draft. > > > > A structure type describes a sequentially allocated nonempty set of > > member objects (and, in certain circumstances, an incomplete array), > > each of which has an optionally specified name and possibly distinct > > type. > > > > When two pointers are compared ... If the objects pointed to are > > members of the same aggregate object, pointers to structure members > > declared later compare greater than pointers to members declared > > earlier in the structure. > > > > Two objects may be adjacent in memory because they are adjacent > > elements of a larger array or adjacent members of a structure with no > > padding between them, > > > > As discussed in 6.2.5, a structure is a type consisting of a sequence > > of members, whose storage is allocated in an ordered sequence, > > > > Within a structure object, the non-bit-field members and the units > > in which bit-fields reside have addresses that increase in the order > > in which they are declared > > > > C requires that members of a structure be defined in ascending address > > order as specified by the programmer. The compiler may not reorder > > structure fields, although bitfields are a special case. > > > > Previous to the "Draft" "Proposal" of C98, there were no such > requirements. And so-called ANSI -C specifically declined to > define any order within structures. It would be nice it you would occasionally check the stuff you pontificate about. The last sentence of the quoted paragraph appears verbatim in the ANSI X3.159-1989 specification in 3.5.2.1. -- Lieven Marchand <mal@wyrd.be> You can drag any rat out of the sewer and teach it to get some work done in Perl, but you cannot teach it serious programming. Erik Naggum ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-24 2:43 ` Richard B. Johnson 2001-06-24 16:07 ` Lieven Marchand @ 2001-06-24 16:11 ` frank 2001-06-25 0:26 ` Michael Meissner 2 siblings, 0 replies; 18+ messages in thread From: frank @ 2001-06-24 16:11 UTC (permalink / raw) To: Richard B. Johnson; +Cc: Keith Owens, linux-kernel On Sat, 23 Jun 2001, Richard B. Johnson wrote: > On Sun, 24 Jun 2001, Keith Owens wrote: > > > On Sat, 23 Jun 2001 21:56:06 -0400 (EDT), > > "Richard B. Johnson" <root@chaos.analogic.com> wrote: > > >FYI, structures are designed to be accessed only by their member-names. > > >Therefore, the compiler is free to put members at any offset. In fact, > > >members, other than the first, don't even have to be in the order > > >written! > > > > Bzzt! I don't know where people get these ideas from. Extracts from > > the C9X draft. > > > > A structure type describes a sequentially allocated nonempty set of > > member objects (and, in certain circumstances, an incomplete array), > > each of which has an optionally specified name and possibly distinct > > type. > > > > When two pointers are compared ... If the objects pointed to are > > members of the same aggregate object, pointers to structure members > > declared later compare greater than pointers to members declared > > earlier in the structure. > > > > Two objects may be adjacent in memory because they are adjacent > > elements of a larger array or adjacent members of a structure with no > > padding between them, > > > > As discussed in 6.2.5, a structure is a type consisting of a sequence > > of members, whose storage is allocated in an ordered sequence, > > > > Within a structure object, the non-bit-field members and the units > > in which bit-fields reside have addresses that increase in the order > > in which they are declared > > > > C requires that members of a structure be defined in ascending address > > order as specified by the programmer. The compiler may not reorder > > structure fields, although bitfields are a special case. > > > > Previous to the "Draft" "Proposal" of C98, there were no such > requirements. And so-called ANSI -C specifically declined to > define any order within structures. Maybe Ansi didn't but K&R certainly did Frank > > > Cheers, > Dick Johnson > > Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips). > > "Memory is like gasoline. You use it up when you are running. Of > course you get it all back when you reboot..."; Actual explanation > obtained from the Micro$oft help desk. > > > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > HI! I'm a .signature virus! cp me into your .signature file to help me spread! ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-24 2:43 ` Richard B. Johnson 2001-06-24 16:07 ` Lieven Marchand 2001-06-24 16:11 ` frank @ 2001-06-25 0:26 ` Michael Meissner 2001-06-25 11:32 ` Richard B. Johnson 2 siblings, 1 reply; 18+ messages in thread From: Michael Meissner @ 2001-06-25 0:26 UTC (permalink / raw) To: Richard B. Johnson; +Cc: Keith Owens, linux-kernel On Sat, Jun 23, 2001 at 10:43:14PM -0400, Richard B. Johnson wrote: > Previous to the "Draft" "Proposal" of C98, there were no such > requirements. And so-called ANSI -C specifically declined to > define any order within structures. As one of the founding members of the X3J11 ANSI committee, and having served on the committee for 10 1/2 years, I can state categorically that Appendix A of the original K&R (which was one of the 3 base documents for ANSI C) had the requirement that non-bitfield fields are required to have monotonically increasing addresses (bitfields don't have addresses, and different compiler ABIs do lay them out in different fashions within the words). C89 never changed the wording that mandates this. -- Michael Meissner, Red Hat, Inc. (GCC group) PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886, USA Work: meissner@redhat.com phone: +1 978-486-9304 Non-work: meissner@spectacle-pond.org fax: +1 978-692-4482 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-25 0:26 ` Michael Meissner @ 2001-06-25 11:32 ` Richard B. Johnson 2001-06-25 13:38 ` Alan Shutko 2001-06-25 20:43 ` Michael Meissner 0 siblings, 2 replies; 18+ messages in thread From: Richard B. Johnson @ 2001-06-25 11:32 UTC (permalink / raw) To: Michael Meissner; +Cc: Keith Owens, linux-kernel On Sun, 24 Jun 2001, Michael Meissner wrote: > On Sat, Jun 23, 2001 at 10:43:14PM -0400, Richard B. Johnson wrote: > > Previous to the "Draft" "Proposal" of C98, there were no such > > requirements. And so-called ANSI -C specifically declined to > > define any order within structures. > > As one of the founding members of the X3J11 ANSI committee, and having served > on the committee for 10 1/2 years, I can state categorically that Appendix A > of > the original K&R (which was one of the 3 base documents for ANSI C) had the > requirement that non-bitfield fields are required to have monotonically > increasing addresses (bitfields don't have addresses, and different compiler > ABIs do lay them out in different fashions within the words). C89 never > changed the wording that mandates this. > > -- > Michael Meissner, Red Hat, Inc. (GCC group) > PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886, USA > Work: meissner@redhat.com phone: +1 978-486-9304 > Non-work: meissner@spectacle-pond.org fax: +1 978-692-4482 > The layout of structures is logical, not physical, and in fact must be. This became a requirement after the 'const' keyword was accepted. If the structure members we located exactly as written, then the following structure would not be possible: struct s { int a; int b; const char c[0x10]; int d; } s = { 0x01, 0x02, "Hello World", 0x04 }; It is quite correct to mix read-only data and writable data within a structure. A correctly operating compiler will put the read-only data with other read-only data and, if this area is protected either because it's in ROM, or the OS traps, not allow it to be written. This means that it must be some place else than where it's denoted in a visual representation of the structure. This is one of the main reasons why one cannot assume that the memory layout is represented by the logical layout of the structure. In short, a structure is a logical representation of an array of aggregate types, not a physical representation. With `gcc` the following compiles with a warning about 'const', but it still compiles and runs. #include <stdio.h> #include <string.h> struct s { int a; int b; const char c[0x10]; int d; } s = { 0x01, 0x02, "Hello World", 0x04 }; int main() { printf("a = %p\n", &s.a); printf("b = %p\n", &s.b); printf("c = %p\n", s.c); printf("d = %p\n", &s.d); strcpy(s.c, "So much for rules"); puts(s.c); return 0; } This compiles and runs because gcc does not put the "const char" string in ".rodata" as it is supposed to do. It just throws it in with with ".data" so you get the behavior that many persons expect, while refusing to do what the code told it to do. This is an example of the Gnu-ism where the compiler thinks it "knows more than the programmer". Further, since gcc does this, many persons think that this is "correct" or "how it is supposed to be" or "complies with CX standard", etc. If you are writing execute-in-place code (NVRAM), with only a few kilobytes of RAM, you are in a world of hurt with such a compiler. That's why you don't use gcc for this. Instead, you use a compiler which produces code "as written" for such a project. .file "xxx.c" .version "01.01" gcc2_compiled.: .globl s .data .align 4 .type s,@object .size s,28 s: .long 1 .long 2 .string "Hello World" .zero 4 .long 4 .section .rodata .LC0: .string "a = %p\n" .LC1: .string "b = %p\n" .LC2: .string "c = %p\n" .LC3: .string "d = %p\n" .LC4: .string "So much for rules" .text .align 16 There is no additional overhead from putting data types where the programmer told the compiler to put them. When referencing the R/O data, the compiler "knows" where it put it. It is free to use whatever addressing it wants. In the code generated above, the compiler should have done: s: .long 1 .long 2 .section .rodata .string "Hello World" .zero 4 .previous .long 4 .section .rodata But if it did this, member 'd' would follow member 'b' in the structure, which is not what the usual programmer might expect. Member 'c', the R/O data would be, correctly, at some "strange" offset unrelated to the other structure members. Cheers, Dick Johnson Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips). "Memory is like gasoline. You use it up when you are running. Of course you get it all back when you reboot..."; Actual explanation obtained from the Micro$oft help desk. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-25 11:32 ` Richard B. Johnson @ 2001-06-25 13:38 ` Alan Shutko 2001-06-25 13:59 ` Alan Shutko 2001-06-25 14:49 ` Richard B. Johnson 2001-06-25 20:43 ` Michael Meissner 1 sibling, 2 replies; 18+ messages in thread From: Alan Shutko @ 2001-06-25 13:38 UTC (permalink / raw) To: root; +Cc: Michael Meissner, Keith Owens, linux-kernel "Richard B. Johnson" <root@chaos.analogic.com> writes: > This means that it must be some place else than where it's denoted > in a visual representation of the structure. No, that's not true. ISO/IEC 9899:1990 6.5.2.1: As discussed in 6.1.2.5, a structure is a type consisting of a sequence of named members, whose storage is allocated in an ordered sequence, and a union [stuff we don't care about]. Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides, and vice versa. There may therefore be unnammed padding withing a structure object, but not at its beginning, as necessary to achieve the appropriate alignment. There may also be unnamed padding at the end of a structure or union, as necessary to achieve the appropriate alignment were the structure or union to be an element of an array. You can look at other things too... you can memcpy structures, pass them into functions, call sizeof, put them in arrays... it _is_ a physical representation. -- Alan Shutko <ats@acm.org> - In a variety of flavors! Conscience is what hurts when everything else feels so good. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-25 13:38 ` Alan Shutko @ 2001-06-25 13:59 ` Alan Shutko 2001-06-25 15:07 ` Andreas Schwab 2001-06-25 21:25 ` Horst von Brand 2001-06-25 14:49 ` Richard B. Johnson 1 sibling, 2 replies; 18+ messages in thread From: Alan Shutko @ 2001-06-25 13:59 UTC (permalink / raw) To: root; +Cc: Michael Meissner, Keith Owens, linux-kernel Alan Shutko <ats@acm.org> writes: > You can look at other things too... you can memcpy structures, pass > them into functions, call sizeof, put them in arrays... it _is_ a > physical representation. One more tidbit: ISO/IEC 9899:1990 3.14 3.14 object: A region of data storage in the execution environment, the contents of which can represent values. Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, the number, order and encoding of which are either explicitely specified or implementation-defined. This would specifically prohibit separating any part of a structure from the rest. -- Alan Shutko <ats@acm.org> - In a variety of flavors! A king's castle is his home. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-25 13:59 ` Alan Shutko @ 2001-06-25 15:07 ` Andreas Schwab 2001-06-25 21:25 ` Horst von Brand 1 sibling, 0 replies; 18+ messages in thread From: Andreas Schwab @ 2001-06-25 15:07 UTC (permalink / raw) To: Alan Shutko; +Cc: linux-kernel Alan Shutko <ats@acm.org> writes: |> Alan Shutko <ats@acm.org> writes: |> |> > You can look at other things too... you can memcpy structures, pass |> > them into functions, call sizeof, put them in arrays... it _is_ a |> > physical representation. |> |> One more tidbit: ISO/IEC 9899:1990 3.14 |> |> 3.14 object: A region of data storage in the execution environment, |> the contents of which can represent values. Except for |> bit-fields, objects are composed of contiguous sequences of one or |> more bytes, the number, order and encoding of which are either |> explicitely specified or implementation-defined. |> |> This would specifically prohibit separating any part of a structure |> from the rest. But only under the as-if rule, that is, if you never take the address of a structure object the compiler can actually put the parts of it anywhere it likes, because you couldn't notice the difference. Andreas. -- Andreas Schwab "And now for something SuSE Labs completely different." Andreas.Schwab@suse.de SuSE GmbH, Schanzäckerstr. 10, D-90443 Nürnberg Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-25 13:59 ` Alan Shutko 2001-06-25 15:07 ` Andreas Schwab @ 2001-06-25 21:25 ` Horst von Brand 1 sibling, 0 replies; 18+ messages in thread From: Horst von Brand @ 2001-06-25 21:25 UTC (permalink / raw) To: Alan Shutko; +Cc: linux-kernel Alan Shutko <ats@acm.org> said: > One more tidbit: ISO/IEC 9899:1990 3.14 > > 3.14 object: A region of data storage in the execution environment, > the contents of which can represent values. Except for > bit-fields, objects are composed of contiguous sequences of one or > more bytes, the number, order and encoding of which are either > explicitely specified or implementation-defined. > > This would specifically prohibit separating any part of a structure > from the rest. It just prohibits separating bytes, not subobjects. I.e., everything can be handled as an array of bytes (of the appropiate length, as given by sizeof()) -- Dr. Horst H. von Brand Usuario #22616 counter.li.org Departamento de Informatica Fono: +56 32 654431 Universidad Tecnica Federico Santa Maria +56 32 654239 Casilla 110-V, Valparaiso, Chile Fax: +56 32 797513 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-25 13:38 ` Alan Shutko 2001-06-25 13:59 ` Alan Shutko @ 2001-06-25 14:49 ` Richard B. Johnson 2001-06-25 19:19 ` Alan Shutko 1 sibling, 1 reply; 18+ messages in thread From: Richard B. Johnson @ 2001-06-25 14:49 UTC (permalink / raw) To: Alan Shutko; +Cc: Michael Meissner, Keith Owens, linux-kernel On Mon, 25 Jun 2001, Alan Shutko wrote: > "Richard B. Johnson" <root@chaos.analogic.com> writes: > > > This means that it must be some place else than where it's denoted > > in a visual representation of the structure. > > No, that's not true. > > ISO/IEC 9899:1990 6.5.2.1: > > As discussed in 6.1.2.5, a structure is a type consisting of a > sequence of named members, whose storage is allocated in an ordered > sequence, and a union [stuff we don't care about]. > Does "ordered sequence" mean "incremental"? I think not. > Within a structure object, the non-bit-field members and the units > in which bit-fields reside have addresses that increase in the order > in which they declared. Really?? Did you TYPE this in or did you copy it from somewhere?? When I was on an ANSI committee (nothing to do with software), we made damn sure that we used the correct English. Look at: "have addresses that increase in the order in which they declared." I think this was added, in the copy you cite, by somebody who didn't know English grammar, to support the argument..." "in which they were declared." ^^^^ And... If this was a part of a C specification it would prevent the inclusion of const data within a structure unless the entire structure was of type const. And, it is well known that any data types may be structure members so this cannot be correct. A pointer to a structure object, suitably > converted, points to its initial member (or if that member is a > bit-field, then to the unit in which it resides, and vice versa. > There may therefore be unnammed padding withing a structure object, ^^^^^^^^ ^^^^^^^ Unnamed and within are spelled incorrectly. This is not a valid document. > but not at its beginning, as necessary to achieve the appropriate > alignment. > > There may also be unnamed padding at the end of a structure or > union, as necessary to achieve the appropriate alignment were the > structure or union to be an element of an array. > > You can look at other things too... you can memcpy structures, pass > them into functions, call sizeof, put them in arrays... it _is_ a > physical representation. > memcpy()... Maybe you can memcpy() structures. Maybe you and I usually get away with it, but provisions were made to handle the problems previously discussed, by using the assigment operator "=" to copy structures. This way, the compiler "knows" where things are and handles duplication accordingly. And copying a structure that contains a mix of const and writable data is probably a bug since the copy can't support data of type 'const'. Pass to functions... Since any memory object(s) including structure members are simply data contained at addresses, of course you can pass them to functions although doing this is probably done by mistake, rather than design. Generally, one would pass a pointer to a structure. Which, according to previously-cited rules, represents the address of the first structure member. "call?" sizeof... Returns the allocation size of the structure. So? The compiler can certainly add up the length of all the structure members plus any padding and return the result. Note that you can't allocate data of type 'const' so when copying any structure by any means, the copy contains no 'const' data, even if the original structure contained 'const' data members. The const data is/are not missing, they are just no longer const. Put into arrays... Of course. Nothing has to be physical representation as a requisite for being put into arrays. Cheers, Dick Johnson Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips). "Memory is like gasoline. You use it up when you are running. Of course you get it all back when you reboot..."; Actual explanation obtained from the Micro$oft help desk. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-25 14:49 ` Richard B. Johnson @ 2001-06-25 19:19 ` Alan Shutko 0 siblings, 0 replies; 18+ messages in thread From: Alan Shutko @ 2001-06-25 19:19 UTC (permalink / raw) To: root; +Cc: Michael Meissner, Keith Owens, linux-kernel "Richard B. Johnson" <root@chaos.analogic.com> writes: > > ISO/IEC 9899:1990 6.5.2.1: > > > > As discussed in 6.1.2.5, a structure is a type consisting of a > > sequence of named members, whose storage is allocated in an ordered > > sequence, and a union [stuff we don't care about]. > > > > Does "ordered sequence" mean "incremental"? I think not. It does mean there is an order, as defined below. > > > Within a structure object, the non-bit-field members and the units > > in which bit-fields reside have addresses that increase in the order > > in which they declared. > > > Really?? Did you TYPE this in or did you copy it from somewhere?? I typed it in and forgot an "are". Forgive me, but this doesn't change the point, and you could have easily looked in the standard yourself to see where I mistyped. > And... If this was a part of a C specification Which it is. > it would prevent the inclusion of const data within a structure > unless the entire structure was of type const. No. The C standard does not guarantee that const items be placed in RO memory. It does not even require that the host have RO memory, or that an implementation do the same thing with a const object as a const member of a structure. > > There may therefore be unnammed padding withing a structure object, > Unnamed and within are spelled incorrectly. This is not a valid > document. Geez, would you rather I scan it for you? > This way, the compiler "knows" where things are and handles duplication > accordingly. Of course it knows where things are, since a structure is a single contiguous range of memory, according to the standard. Would you care to offer counter citations? Have you even looked at the standard? -- Alan Shutko <ats@acm.org> - In a variety of flavors! Please keep your hands off the secretary's reproducing equipment. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: sizeof problem in kernel modules 2001-06-25 11:32 ` Richard B. Johnson 2001-06-25 13:38 ` Alan Shutko @ 2001-06-25 20:43 ` Michael Meissner 1 sibling, 0 replies; 18+ messages in thread From: Michael Meissner @ 2001-06-25 20:43 UTC (permalink / raw) To: Richard B. Johnson; +Cc: Michael Meissner, Keith Owens, linux-kernel On Mon, Jun 25, 2001 at 07:32:32AM -0400, Richard B. Johnson wrote: > On Sun, 24 Jun 2001, Michael Meissner wrote: > > > On Sat, Jun 23, 2001 at 10:43:14PM -0400, Richard B. Johnson wrote: > > > Previous to the "Draft" "Proposal" of C98, there were no such > > > requirements. And so-called ANSI -C specifically declined to > > > define any order within structures. > > > > As one of the founding members of the X3J11 ANSI committee, and having served > > on the committee for 10 1/2 years, I can state categorically that Appendix A > > of > > the original K&R (which was one of the 3 base documents for ANSI C) had the > > requirement that non-bitfield fields are required to have monotonically > > increasing addresses (bitfields don't have addresses, and different compiler > > ABIs do lay them out in different fashions within the words). C89 never > > changed the wording that mandates this. > > > > -- > > Michael Meissner, Red Hat, Inc. (GCC group) > > PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886, USA > > Work: meissner@redhat.com phone: +1 978-486-9304 > > Non-work: meissner@spectacle-pond.org fax: +1 978-692-4482 > > > > The layout of structures is logical, not physical, and in fact > must be. This became a requirement after the 'const' keyword > was accepted. Wrong. While the footnote (# 103 in C99) does say a compiler MAY place a const object in read-only memory, it does not require it (and in fact technically, footnotes are not consider part of the standard). However, a const field within a structure is still embedded in that whole structure, and the whole structure is not const. > If the structure members we located exactly as written, then > the following structure would not be possible: > > struct s { > int a; > int b; > const char c[0x10]; > int d; > } s = { 0x01, 0x02, "Hello World", 0x04 }; > > It is quite correct to mix read-only data and writable data within > a structure. A correctly operating compiler will put the read-only > data with other read-only data and, if this area is protected either > because it's in ROM, or the OS traps, not allow it to be written. > This means that it must be some place else than where it's denoted > in a visual representation of the structure. This is one of > the main reasons why one cannot assume that the memory layout > is represented by the logical layout of the structure. Wrong again. The standard quite clearly requires that an object be continous. > In short, a structure is a logical representation of an array > of aggregate types, not a physical representation. > > With `gcc` the following compiles with a warning about 'const', but it > still compiles and runs. > > #include <stdio.h> > #include <string.h> > > struct s { > int a; > int b; > const char c[0x10]; > int d; > } s = { 0x01, 0x02, "Hello World", 0x04 }; > > int main() > { > printf("a = %p\n", &s.a); > printf("b = %p\n", &s.b); > printf("c = %p\n", s.c); > printf("d = %p\n", &s.d); > strcpy(s.c, "So much for rules"); > puts(s.c); > return 0; > } > > This compiles and runs because gcc does not put the "const char" > string in ".rodata" as it is supposed to do. It just throws it in > with with ".data" so you get the behavior that many persons expect, > while refusing to do what the code told it to do. This is an example > of the Gnu-ism where the compiler thinks it "knows more than the > programmer". Further, since gcc does this, many persons think that > this is "correct" or "how it is supposed to be" or "complies with > CX standard", etc. > > If you are writing execute-in-place code (NVRAM), with only a few > kilobytes of RAM, you are in a world of hurt with such a compiler. > That's why you don't use gcc for this. Instead, you use a compiler > which produces code "as written" for such a project. No, you properly use the standard, instead of reading your own misinterpretations into it. In this case, it means keeping parallel data structures if you feel some parts need to be in read-only memory and some not. -- Michael Meissner, Red Hat, Inc. (GCC group) PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886, USA Work: meissner@redhat.com phone: +1 978-486-9304 Non-work: meissner@spectacle-pond.org fax: +1 978-692-4482 ^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: sizeof problem in kernel modules 2001-06-23 14:54 sizeof problem in kernel modules Der Herr Hofrat ` (2 preceding siblings ...) 2001-06-24 1:56 ` Richard B. Johnson @ 2001-06-25 4:33 ` Anil Kumar 3 siblings, 0 replies; 18+ messages in thread From: Anil Kumar @ 2001-06-25 4:33 UTC (permalink / raw) To: Der Herr Hofrat, linux-kernel struct { short x; long y; short z; }bad_struct; struct { long y; short x; short z; }good_struct; I would expect both structs to be 8byte in size , or atleast the same size ! but good_struct turns out to be 8bytes and bad_struct 12 . what am I doing wrong here ? thx ! hofrat /////////////////////////////////////// It's general padding performed everywhere for a 32-bit m/c. Since the short number is considered to be of 2 bytes whereas new data should start at the next 32 bit alignment( if the data length exceeds the padding required ) hence next 2 bytes are left as padding, so the actual struct. of your defined structutres are as follows, struct{ short x; /* 2- bytes */ /* again 2- bytes padding */ long y; /* 4 - bytes */ short z; /* 2 - bytes */ /* again 2 - bytes padding }bad_struct; struct{ long y; /* 4 - bytes */ short x; /* 2 - bytes */ short z; /* 2 - bytes */ }good_struct; anil ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2001-06-25 21:26 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2001-06-23 14:54 sizeof problem in kernel modules Der Herr Hofrat 2001-06-23 15:18 ` Keith Owens 2001-06-23 15:30 ` Russell King 2001-06-24 1:56 ` Richard B. Johnson 2001-06-24 2:12 ` Keith Owens 2001-06-24 2:43 ` Richard B. Johnson 2001-06-24 16:07 ` Lieven Marchand 2001-06-24 16:11 ` frank 2001-06-25 0:26 ` Michael Meissner 2001-06-25 11:32 ` Richard B. Johnson 2001-06-25 13:38 ` Alan Shutko 2001-06-25 13:59 ` Alan Shutko 2001-06-25 15:07 ` Andreas Schwab 2001-06-25 21:25 ` Horst von Brand 2001-06-25 14:49 ` Richard B. Johnson 2001-06-25 19:19 ` Alan Shutko 2001-06-25 20:43 ` Michael Meissner 2001-06-25 4:33 ` Anil Kumar
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.