All of lore.kernel.org
 help / color / mirror / Atom feed
* 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-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

* 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: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 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 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-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

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.