Home > Archive > Fortran > June 2007 > sizeof(type) > than it should be ... help!
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
sizeof(type) > than it should be ... help!
|
|
|
| Hi,
i generted some structure:
type :: BPAR
character(len=10) :: name
character(len=10) :: einh
real*8 :: wert
end type BPAR
type :: PARBLK
integer*2 :: parlng
integer*2 :: grpanz
character(len=80) :: filkom
character(len=24) :: mesdat
character(len=18) :: parfil
character(len=18) :: pronam
character(len=10) :: prfstd
character(len=18) :: motnam
integer*2 :: mottyp
integer*2 :: tktanz
integer*2 :: geoein
real*8 :: hublng
real*8 :: pleuel
real*8 :: bohrng
real*8 :: kompre
real*8 :: desaxi
integer*4 :: grpflg
integer*4 :: datahandle
integer*2 :: version
character(len=12) :: reserve
type(BPAR) :: bpar(28)
end type PARBLK
then I make some variable of it:
type(PARBLK) :: dummy
but when i print its size
sizeof(dummy)
it says 1144, but it should be 1024
what am I doing wrong, can anybody help me?
thanks in advance.
| |
| Ian Bush 2007-06-26, 8:06 am |
|
Hi Nio,
As if by magic, Nio appeared !
> Hi,
>
> i generted some structure:
>
> type :: BPAR
> character(len=10) :: name
> character(len=10) :: einh
> real*8 :: wert
> end type BPAR
>
> type :: PARBLK
> integer*2 :: parlng
> integer*2 :: grpanz
> character(len=80) :: filkom
> character(len=24) :: mesdat
> character(len=18) :: parfil
> character(len=18) :: pronam
> character(len=10) :: prfstd
> character(len=18) :: motnam
> integer*2 :: mottyp
> integer*2 :: tktanz
> integer*2 :: geoein
> real*8 :: hublng
> real*8 :: pleuel
> real*8 :: bohrng
> real*8 :: kompre
> real*8 :: desaxi
> integer*4 :: grpflg
> integer*4 :: datahandle
> integer*2 :: version
> character(len=12) :: reserve
> type(BPAR) :: bpar(28)
> end type PARBLK
>
>
> then I make some variable of it:
>
> type(PARBLK) :: dummy
>
> but when i print its size
>
> sizeof(dummy)
>
> it says 1144, but it should be 1024
(n.b. I haven't checked the maths)
>
> what am I doing wrong, can anybody help me?
Well to start with
1) integer*2 is not standard Fortran
2) integer*4 is not standard Fortran
3) real*8 is not standard Fortran
4) sizeof is not standard Fortran
5) For non-sequence derived types compilers are free to put any
sort of padding they want in derived types, and many do. The
reason is to align objects on the appropriate boundaries to
maximise performance.
1-4 can probably be solved by the use of kind type parameters.
For 5 you can't solve it within the standard as you can not mix
numeric and character storage in sequence types
What are you trying to achieve ? Are you message passing ?
Ian
| |
| glen herrmannsfeldt 2007-06-26, 8:06 am |
| Nio wrote:
> type :: BPAR
> character(len=10) :: name
> character(len=10) :: einh
> real*8 :: wert
> end type BPAR
Some processors require that the (non-standard) REAL*8 variables
have an address that is a multiple of eight. After 20 characters
(assumed to be one byte each) there will be four bytes of padding
before the REAL*8 variable. If you move the REAL*8 variable
to the beginning of the structure, the padding will move to
the end such that structure array elements are spaced a multiple
of eight bytes apart.
> type :: PARBLK
> integer*2 :: parlng
> integer*2 :: grpanz
> character(len=80) :: filkom
> character(len=24) :: mesdat
> character(len=18) :: parfil
> character(len=18) :: pronam
> character(len=10) :: prfstd
> character(len=18) :: motnam
> integer*2 :: mottyp
> integer*2 :: tktanz
> integer*2 :: geoein
Six bytes of padding here to align the next variable.
> real*8 :: hublng
> real*8 :: pleuel
> real*8 :: bohrng
> real*8 :: kompre
> real*8 :: desaxi
> integer*4 :: grpflg
> integer*4 :: datahandle
> integer*2 :: version
> character(len=12) :: reserve
two more here.
> type(BPAR) :: bpar(28)
> end type PARBLK
> then I make some variable of it:
> type(PARBLK) :: dummy
> but when i print its size
> sizeof(dummy)
> it says 1144, but it should be 1024
> what am I doing wrong, can anybody help me?
The result is 6+2+28*4=120 byte of padding.
-- glen
| |
| Jugoslav Dujic 2007-06-26, 10:06 pm |
| glen herrmannsfeldt wrote:
| Nio wrote:
|
|| type :: BPAR
|| character(len=10) :: name
|| character(len=10) :: einh
|| real*8 :: wert
|| end type BPAR
|
| Some processors require that the (non-standard) REAL*8 variables
| have an address that is a multiple of eight. After 20 characters
| (assumed to be one byte each) there will be four bytes of padding
| before the REAL*8 variable. If you move the REAL*8 variable
| to the beginning of the structure, the padding will move to
| the end such that structure array elements are spaced a multiple
| of eight bytes apart.
Glen is right; the padding is automatically inserted by the
compiler to ensure that the variables are "naturally" aligned
(8-byte variables start at an address that is a multiple of 8).
I'd use the word "prefer" rather than "require" though -- most
modern processors are capable of handling unaligned data, on
the expense of efficiency in processing; the price depends on
underlying hardware.
An obvious cure is to list the variables within the TYPE in
descending size (and that's generally a good rule of thumb).
Fortran Standard, trying not to bind the language on any specific
architecture, is relatively silent on the issue on the alignment
and padding. Generally, it allows the compiler to reorder and/or
pad the elements of a structure as it prefers. Adding the SEQUENCE
keyword at the top of the TYPE declaration ensures
that the TYPE can be sequence-associated (e.g. part of a common
block); for most architectures, that means that the padding and
reordering will be eliminated (on the expense of the processing
efficiency, as I said). Still, I recommend the sort-by-size
approach.
--
Jugoslav
___________
www.xeffort.com
Please reply to the newsgroup.
You can find my real e-mail on my home page above.
| |
| Jugoslav Dujic 2007-06-26, 10:06 pm |
| Ian Bush wrote:
| For 5 you can't solve it within the standard as you can not mix
| numeric and character storage in sequence types
Um... no? Didn't know that (but it makes some sense); that sort of
makes my previous post (reply to Glen) moot.
--
Jugoslav
___________
www.xeffort.com
Please reply to the newsgroup.
You can find my real e-mail on my home page above.
| |
| Richard Maine 2007-06-26, 10:06 pm |
| Ian Bush <I.J.Bush@ku.ca.ld> wrote:
> 5) For non-sequence derived types compilers are free to put any
> sort of padding they want in derived types, and many do. The
> reason is to align objects on the appropriate boundaries to
> maximise performance.
>
> 1-4 can probably be solved by the use of kind type parameters.
> For 5 you can't solve it within the standard as you can not mix
> numeric and character storage in sequence types
Yes, you can. Numeric sequence type and character sequence types are
special subcategories of sequence types, but you can certainly have
sequence types that aren't in those categories. (The numeric sequence
type definition is much narower than you might think from the name, but
that's a side matter. The integer*2 in the code example cited would not
fit even if it were converted to use kinds and even if the character
components weren't around; that wouldn't be one of the kinds allowed).
However, also, note that compilers are also free to do the same kinds of
things to sequuence types. The restrictions against such things apply
only to numeric and character sequence types.
Bind(C) types in f2003 are a bit more restrictive. Mostly they just have
to match the C compiler. But C, I think, also allows padding in some
cases; I forget the details of that and I could be wrong.
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
| |
| Kevin G. Rhoads 2007-06-26, 10:07 pm |
| >Glen is right; the padding is automatically inserted by the
>compiler to ensure that the variables are "naturally" aligned
>(8-byte variables start at an address that is a multiple of 8).
>I'd use the word "prefer" rather than "require" though -- most
>modern processors are capable of handling unaligned data, on
>the expense of efficiency in processing; the price depends on
>underlying hardware.
Agreed. Padding is the issue for why size does not match expectations.
However, if this is for C interop, OP may not have the option of
rearranging the order, it may be required to match some pre-existing
C thing. THEN the real question is does the C side use padding or
not, and if using padding to what alignment level; as many C compilers
allow alignment requirements to be overridden using pragmas of various
ilk.
So, the real question is why does OP care about the size? Only if that
is answered can sensible recommendations be made. Until then we're
all just shooting in the dark.
| |
| glen herrmannsfeldt 2007-06-26, 10:07 pm |
| Kevin G. Rhoads wrote:
(snip)
> Agreed. Padding is the issue for why size does not match expectations.
> However, if this is for C interop, OP may not have the option of
> rearranging the order, it may be required to match some pre-existing
> C thing. THEN the real question is does the C side use padding or
> not, and if using padding to what alignment level; as many C compilers
> allow alignment requirements to be overridden using pragmas of various
> ilk.
Most C compilers do padding. Many RISC processors require
alignment. For IA32 (x86) it is faster if aligned, but not
fatal if misaligned.
> So, the real question is why does OP care about the size? Only if that
> is answered can sensible recommendations be made. Until then we're
> all just shooting in the dark.
Yes, that is the question.
-- glen
| |
| Ian Bush 2007-06-27, 4:18 am |
| As if by magic, Richard Maine appeared !
> Ian Bush <I.J.Bush@ku.ca.ld> wrote:
>
>
> Yes, you can. Numeric sequence type and character sequence types are
> special subcategories of sequence types, but you can certainly have
> sequence types that aren't in those categories. (The numeric sequence
> type definition is much narower than you might think from the name, but
> that's a side matter. The integer*2 in the code example cited would not
> fit even if it were converted to use kinds and even if the character
> components weren't around; that wouldn't be one of the kinds allowed).
>
> However, also, note that compilers are also free to do the same kinds of
> things to sequuence types. The restrictions against such things apply
> only to numeric and character sequence types.
>
Thanks for that, it was based on a misreading of MR&C. Live and learn,
though I can't see where I will ever use this knowledge
> Bind(C) types in f2003 are a bit more restrictive. Mostly they just have
> to match the C compiler. But C, I think, also allows padding in some
> cases; I forget the details of that and I could be wrong.
>
C also allows padding,
Ian
| |
| Ian Bush 2007-06-27, 4:18 am |
| As if by magic, Kevin G. Rhoads appeared !
>
> Agreed. Padding is the issue for why size does not match expectations.
>
> However, if this is for C interop
Unless I've misread MR&C again it can't be for C interop:
character(len=80) :: filkom
Ian
|
|
|
|
|