Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2015-08

alignment of records

13 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Xiangrong Fang

Hi All,

I try to port a program from C to Pascal, see the following example:

#include <stdio.h>
#include <sys/socket.h>
#include <linux/if.h>
void main() {
    printf("ifmap=%ld\n", sizeof(struct ifmap));
}

I converted it to:

est.c test.pas

       X
program test;
{$mode objfpc}{$PACKRECORDS C}
type
  ifmap = record
    mem_start: dword;
    mem_end: dword;
    base_addr: word;
    irq: byte;
    dma: byte;
    port: byte;
  end;
begin
  WriteLn('ifmap=', SizeOf(ifmap));
end.

The C struct's size is 24, but pascal record is 16. The ifmap struct is defined as:

struct ifmap {
    unsigned long mem_start;
    unsigned long mem_end;
    unsigned short base_addr;
    unsigned char irq;
    unsigned char dma;
    unsigned char port;
    /* 3 bytes spare */
};

How can I instruct FPC to align records exactly same as GCC?

Thanks!

Reply by email

Xiangrong Fang
to Xiangrong Fang

It seems that $packrecord does not did some research and found this document:

http://www.freepascal.org/docs-html/ref/refsu19.html

compiled and ran the example on that page, I got:

​​Size Trec1 : 4 Offset B : 2
Size Trec2 : 3 Offset B : 1
Size Trec3 : 2 Offset B : 1
Size Trec4 : 2 Offset B : 1
Size Trec5 : 5 Offset B : 1 Offset C : 4
Size Trec6 : 5 Offset B : 1 Offset C : 4
Size Trec7 : 9 Offset B : 1 Offset C : 8
Size Trec8 : 9 Offset B : 1 Offset C : 8

While the expected output, as stated in the document above, should be:

Size Trec1 : 4 Offset B : 2
Size Trec2 : 3 Offset B : 1
Size Trec3 : 2 Offset B : 1
Size Trec4 : 2 Offset B : 1
Size Trec5 : 8 Offset B : 4 Offset C : 7
Size Trec6 : 8 Offset B : 4 Offset C : 7
Size Trec7 : 12 Offset B : 4 Offset C : 11
Size Trec8 : 16 Offset B : 8 Offset C : 15

2015-08-07 10:48 GMT+08:00 Xiangrong Fang :

Show quoted text 52 lines
Hi All, I try to port a program from C to Pascal, see the following example: #include <stdio.h> #include <sys/socket.h> #include <linux/if.h> void main() { printf("ifmap=%ld\n", sizeof(struct ifmap)); } I converted it to: est.c test.pas X program test; {$mode objfpc}{$PACKRECORDS C} type ifmap = record mem_start: dword; mem_end: dword; base_addr: word; irq: byte; dma: byte; port: byte; end; begin WriteLn('ifmap=', SizeOf(ifmap)); end. The C struct's size is 24, but pascal record is 16. The ifmap struct is defined as: struct ifmap { unsigned long mem_start; unsigned long mem_end; unsigned short base_addr; unsigned char irq; unsigned char dma; unsigned char port; /* 3 bytes spare */ }; How can I instruct FPC to align records exactly same as GCC? Thanks!

Reply by email

Jonas Maebe
to Xiangrong Fang: I try to port a program from C to Pascal, see the following example: #include <stdio.h>…
Xiangrong Fang wrote 29 lines
program test; {$mode objfpc}{$PACKRECORDS C} type ifmap = record mem_start: dword; mem_end: dword; base_addr: word; irq: byte; dma: byte; port: byte; end; begin WriteLn('ifmap=', SizeOf(ifmap)); end. The C struct's size is 24, but pascal record is 16. The ifmap struct is defined as: struct ifmap { unsigned long mem_start; unsigned long mem_end; unsigned short base_addr; unsigned char irq; unsigned char dma; unsigned char port; /* 3 bytes spare */ }; How can I instruct FPC to align records exactly same as GCC?

By using the correct types for the fields:
http://www.freepascal.org/docs-html/rtl/ctypes/index-3.html

E.g., "unsigned long" is not (always) the same as "dword".

Jonas

Reply by email

Jonas Maebe
to Xiangrong Fang: It seems that $packrecord does not did some research and found this document:…
Xiangrong Fang wrote 6 lines
It seems that $packrecord does not works fine. I did some research and found this document: http://www.freepascal.org/docs-html/ref/refsu19.html

The documentation seems to be outdated regarding the alignment of arrays. Arrays probably used to be aligned based on the size of the entire array at one point (it's before recorded history, i.e. before September 2000), or maybe the record field insertion code used to contain some special (broken) logic for arrays that ignored their alignment and instead used their size.

In any case, the alignment requirement of an array is and has been for quite some time the alignment requirement of its individual elements, and the alignment of a field's type is what's used to determine its offset in a record (with a maximum of the current packrecords setting).

Jonas

Reply by email

Xiangrong Fang
to Jonas Maebe: By using the correct types for the fields: http://www.freepascal.org/docs-html/rtl/ctypes/…
Show quoted text 8 lines
By using the correct types for the fields: http://www.freepascal.org/docs-html/rtl/ctypes/index-3.html E.g., "unsigned long" is not (always) the same as "dword". ​ ​OK, as a matter of fact, the stuff was copied from output of h2pas

conversion program. :-) I will use ctypes to test again.

However, another issue: if I use this :

​{$CODEALIGN RECORDMIN=4}

It worked. i.e. output size same as C version. I wonder what's the difference between $CODEALIGN and $A/$PACKRECORDS?

Also, if I use "packed records", alignment will never take place, regardless of $A settings, right?

Thanks!
​Xiangrong​

Show quoted text 5 lines
Jonas _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

Jonas Maebe
to Xiangrong Fang
Xiangrong Fang wrote
​OK, as a matter of fact, the stuff was copied from output of h2pas conversion program. :-)

Then it seems that h2pas is pretty broken.

Show quoted text 5 lines
However, another issue: if I use this : ​{$CODEALIGN RECORDMIN=4} It worked.

No, it didn't. The record definition was still wrong.

i.e. output size same as C version.

That's coincidence.

I wonder what's the

difference between $CODEALIGN and $A/$PACKRECORDS?
Packrecords sets the maximum field alignment. As the name implies,
{$codealign recordmin} sets the minimum field alignment.
Also, if I use "packed records", alignment will never take place, regardless of $A settings, right?

Indeed.

Jonas

Reply by email

Sven Barth
to Xiangrong Fang: conversion program. :-) I will use ctypes to test again. However, another issue: if I…
"Xiangrong Fang" wrote
> > By using the correct types for the fields:

http://www.freepascal.org/docs-html/rtl/ctypes/index-3.html

Show quoted text 5 lines
> > E.g., "unsigned long" is not (always) the same as "dword". > ​ > ​OK, as a matter of fact, the stuff was copied from output of h2pas

conversion program. :-) I will use ctypes to test again.

If I remember correctly there's a parameter you to have h2pas use the ctypes unit and its types as well.

Regards,
Sven

Reply by email

Ralf Quint
to Xiangrong Fang: It seems that $packrecord does not did some research and found this document:…
Xiangrong Fang wrote
It seems that $packrecord does not always explicitly use PACKED Record as in

/T//ype////ifmap = PACKED Record/
/ mem_start: dword;/
/ mem_end: dword;/
///b//ase_addr: word;/
/ irq: byte;/
/ dma: byte;/
/ port: byte;/
/ end;//
/
and at least in/up to FPC 2.6.4, this works for me just fine

Ralf

---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Reply by email

Sven Barth
to Ralf Quint
"Ralf Quint" wrote 17 lines
On 8/6/2015 8:25 PM, Xiangrong Fang wrote: > > It seems that $packrecord does not work at all. I always explicitly use PACKED Record as in Type ifmap = PACKED Record mem_start: dword; mem_end: dword; base_addr: word; irq: byte; dma: byte; port: byte; end; and at least in/up to FPC 2.6.4, this works for me just fine

This depends however on the code you're interfacing with. Also the record you mentioned as an example shouldn't differ with and without packed anyway...

Regards,
Sven

Reply by email

Luca Olivetti
to Sven Barth

El 08/08/15 a les 09:30, Sven Barth ha escrit:

Show quoted text 23 lines
Am 08.08.2015 00:37 schrieb "Ralf Quint" < >: > > On 8/6/2015 8:25 PM, Xiangrong Fang wrote: >> >> It seems that $packrecord does not work at all. > > I always explicitly use PACKED Record as in > > Type ifmap = PACKED Record > mem_start: dword; > mem_end: dword; > base_addr: word; > irq: byte; > dma: byte; > port: byte; > end; > > and at least in/up to FPC 2.6.4, this works for me just fine This depends however on the code you're interfacing with. Also the record you mentioned as an example shouldn't differ with and without packed anyway...

With packed the above record is 13 bytes, without is 16 (the bytes are word aligned).
That's with fpc 2.6.4 x86_64 (though it should be the same with a 32 bits compiler).
Just to be sure, in such cases I also use "packed array" and most of the times bitpacked records.

Bye

Luca

Reply by email

Ralf Quint
to Sven Barth: This depends however on the code you're interfacing with. Also the record you mentioned…
Sven Barth wrote 26 lines
Am 08.08.2015 00:37 schrieb "Ralf Quint" < >: > > On 8/6/2015 8:25 PM, Xiangrong Fang wrote: >> >> It seems that $packrecord does not work at all. > > I always explicitly use PACKED Record as in > > Type ifmap = PACKED Record > mem_start: dword; > mem_end: dword; > base_addr: word; > irq: byte; > dma: byte; > port: byte; > end; > > and at least in/up to FPC 2.6.4, this works for me just fine This depends however on the code you're interfacing with. Also the record you mentioned as an example shouldn't differ with and without packed anyway...

I just copied and pasted the code snippet from the OP, to show how to use the PACKED Record statement explicitly for a specific record. I am using this for cross-platform/cross-compiler/cross-language software for at least 30 years now and probably for +20 years in FreePascal (when it was still called FPK and was an attempt of creating a 32bit compiler compatible with 16bit Turbo/Borland Pascal at that time)...

Beside, on the above record, the layout in fact SHOULD matter as it has 3 single bytes at the end and there for needs to be aligned on the byte, not on any word/dword/etc boundary...

Ralf

Ralf

---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Reply by email