Forum > FPC development

Imported C Structure is not mapped correctly

(1/2) > >>

domibay_hugo:
I'm developing an Application that interacts with an External Shared Library over a C Language Structure:

--- Code: C  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---#define MAX_RESULT 128 typedef struct FooResult {  uint32_t iversion;  int8_t iresultcount;  int8_t ierrorcode;  int64_t arrresult[MAX_RESULT];} FooResult; 
So I created this Pascal Structure:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---const  MAX_RESULT = 128; type  PResultArray = ^TResultArray;  TResultArray = array[0..(MAX_RESULT - 1)] of Int64;   PFooResult = ^TFooResult;  TFooResult = packed record    iversion: cuint32;    iresultcount: cint8;    ierrorcode: cint8;    arrresult: TResultArray;  end; 
The issue that I'm observing is that the Array TFooResult.arrresult cannot be accessed correctly.
But when reading the Array TResultArray FreePascal shows the values correctly.

The Library Code is:

--- Code: C  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---#include <stdint.h>#include <stdlib.h>#include <stdio.h>   #define MAX_RESULT 128  typedef struct FooResult {  uint32_t iversion;  int8_t iresultcount;  int8_t ierrorcode;  int64_t arrresult[MAX_RESULT];} FooResult;  /* fooutils.h */ extern FooResult* foo_get_result();extern void foo_build_result(FooResult*);extern const int64_t* foo_get_result_array(const FooResult*);extern void foo_result_debug(const FooResult*);extern void foo_result_free(FooResult*);    FooResult* foo_get_result(){        FooResult* pfooresult = (FooResult*)malloc(sizeof(FooResult));        int irs;          pfooresult->iversion = 0;        pfooresult->iresultcount = -1;        pfooresult->ierrorcode = 0;         for(irs = 0; irs < MAX_RESULT; irs++)        {                pfooresult->arrresult[irs] = -1;        }          return pfooresult;} void foo_build_result(FooResult* pfooresult){        if(pfooresult != NULL)        {                pfooresult->iversion += 1;                pfooresult->ierrorcode = 0;                 if(pfooresult->iresultcount <= 127)            {                if(pfooresult->iresultcount != -1)                {                        pfooresult->arrresult[pfooresult->iresultcount] = pfooresult->iversion;                         pfooresult->iresultcount += 1;                } else {                        pfooresult->arrresult[0] = pfooresult->iversion;                   pfooresult->iresultcount = 1;                }  //if frs.iresultcount != -1              } else {                  pfooresult->ierrorcode = 4;              }  //if(pfooresult->iresultcount <= 127)        }  //if(pfooresult != Null)} const int64_t* foo_get_result_array(const FooResult* pfooresult){        if(pfooresult != NULL)        {                return pfooresult->arrresult;        }        else        {                return NULL;        }} void foo_result_debug(const FooResult* pfooresult){        if(pfooresult != NULL)        {                int irs;                  printf("FooResult* Debug: '*FooResult { iversion: %d, iresultcount: %d, ierrorcode: %d"                                , pfooresult->iversion, pfooresult->iresultcount, pfooresult->ierrorcode);                printf(", arrresult: [");                 for(irs = 0; irs < MAX_RESULT; irs++)                {                        if(irs > 0) { printf(", "); }                         printf("%d", (int)pfooresult->arrresult[irs]);                }                 printf("] }'\n");        }        else  //FooResult is not set        {                printf("FooResult Debug: 'NULL'\n");        }       //if(pfooresult != Null) } void foo_result_free(FooResult* pfooresult){        if(pfooresult != NULL)        {                free(pfooresult);        } } 
the C Language Host Application is this:

--- Code: C  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---#include <stdint.h>#include <stdio.h>  #define MAX_RESULT 128  typedef struct FooResult {  uint32_t iversion;  int8_t iresultcount;  int8_t ierrorcode;  int64_t arrresult[MAX_RESULT];} FooResult;  /* foo-utils.h */ extern FooResult* foo_get_result();extern void foo_build_result(const FooResult*);extern const int64_t* foo_get_result_array(const FooResult*);extern void foo_result_debug(const FooResult*);extern void foo_result_free(FooResult*);    int main (){        FooResult* pfoors;        const uint64_t* parrrs;    int irs, igtcnt;     printf("FooResult: building ...\n");     pfoors = foo_get_result();     if(pfoors != NULL)    {        printf("FooResult: built.\n");         printf("FooResult - Debug 0:\n");         foo_result_debug(pfoors);         printf("FooResult - Content:\n");         printf("FooResult - Code: [%d]\n", pfoors->ierrorcode);        printf("FooResult: Version '%d'\n", pfoors->iversion);        printf("FooResult: (Count: '%d / %d'):\n", pfoors->iresultcount, MAX_RESULT);         for(irs = 0; irs < pfoors->iresultcount; irs++)        {          printf("FooResult: Result[%d]: '%d'\n", irs, pfoors->arrresult[irs]);        }       printf("FooResult: 3 Results filling ...\n");       printf("FooResult: Result 1 filling ...\n");       foo_build_result(pfoors);       printf("FooResult - Debug 1:\n");       foo_result_debug(pfoors);       printf("FooResult: Result 2 filling ...\n");       foo_build_result(pfoors);       printf("FooResult - Debug 2:\n");       foo_result_debug(pfoors);       printf("FooResult: Result 3 filling ...\n");       foo_build_result(pfoors);       printf("FooResult - Debug 3:\n");       foo_result_debug(pfoors);       printf("FooResult: 3 Results filled.\n");       printf("FooResult - Code: [%d]\n", pfoors->ierrorcode);      printf("FooResult: Version '%d'\n", pfoors->iversion);      printf("FooResult: (Count: '%d / %d'):\n", pfoors->iresultcount, MAX_RESULT);       for(irs = 0; irs < pfoors->iresultcount; irs++)      {          printf("FooResult: Result[%d]: '%d'\n", irs, pfoors->arrresult[irs]);      }       igtcnt = pfoors->iresultcount;       printf("FooResult: Array getting ...\n");       parrrs = foo_get_result_array(pfoors);       if(parrrs != NULL)      {        for(irs = 0; irs < igtcnt; irs++)        {                printf("FooResult: Array[%d]: '%d'\n", irs, *(parrrs + irs));        }       }      else  //if(parrrs != NULL)          printf("FooResult: Array get failed!\n");     }    else  //if(pfoors != NULL)      printf("FooResult: Build failed!\n");     printf("FooResult: deleting ...\n");     foo_result_free(pfoors);     printf("FooResult: deleted.\n");         printf("FooResult: App done.\n");   return 0;} 
The C Language Host Application can interact with the Library perfectly and reading the field without any issue:

$ ./foo_result
FooResult: building ...
FooResult: built.
FooResult - Debug 0:
FooResult* Debug: '*FooResult { iversion: 0, iresultcount: -1, ierrorcode: 0, arrresult: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] }'
FooResult - Content:
FooResult - Code: [ 0 ]
FooResult: Version '0'
FooResult: (Count: '-1 / 128'):
FooResult: 3 Results filling ...
FooResult: Result 1 filling ...
FooResult - Debug 1:
FooResult* Debug: '*FooResult { iversion: 1, iresultcount: 1, ierrorcode: 0, arrresult: [1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] }'
FooResult: Result 2 filling ...
FooResult - Debug 2:
FooResult* Debug: '*FooResult { iversion: 2, iresultcount: 2, ierrorcode: 0, arrresult: [1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] }'
FooResult: Result 3 filling ...
FooResult - Debug 3:
FooResult* Debug: '*FooResult { iversion: 3, iresultcount: 3, ierrorcode: 0, arrresult: [1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] }'
FooResult: 3 Results filled.
FooResult - Code: [ 0 ]
FooResult: Version '3'
FooResult: (Count: '3 / 128'):
FooResult: Result[0]: '1'
FooResult: Result[1]: '2'
FooResult: Result[2]: '3'
FooResult: Array getting ...
FooResult: Array[0]: '1'
FooResult: Array[1]: '2'
FooResult: Array[2]: '3'
FooResult: deleting ...
FooResult: deleted.
FooResult: App done.


Now the corresponding FreePascal Host Application reads only Rubbish.
Which seems to me to be an Issue of Memory Outlay.

The FreePascal Application is this:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program demofooresult;  uses  SysUtils, ctypes; const  External_library='libfoo_utils.so'; {Setup as you need} {$IFDEF FPC}{$PACKRECORDS C}{$ENDIF}  const  MAX_RESULT = 128;  type  PFooStruct = Pointer;   PResultArray = ^TResultArray;  TResultArray = array[0..(MAX_RESULT - 1)] of Int64;   PFooResult = ^TFooResult;  TFooResult = packed record    iversion: cuint32;    iresultcount: cint8;    ierrorcode: cint8;    arrresult: TResultArray;  end;  function foo_get_result(): PFooResult; cdecl; external External_library name 'foo_get_result';procedure foo_build_result(pfoo: PFooResult); cdecl; external External_library name 'foo_build_result';function foo_get_result_array(pfoo: PFooResult): PResultArray; cdecl; external External_library name 'foo_get_result_array';procedure foo_result_debug(pfoo: PFooResult); cdecl; external External_library name 'foo_result_debug';procedure foo_result_free(pfoo: PFooResult); cdecl; external External_library name 'foo_result_free';  var  pfoors: PFooResult;  parrrs: PResultArray;  irs, igtcnt: Integer;begin  WriteLn('FooResult: building ...');   pfoors := foo_get_result;   if pfoors <> Nil then  begin    WriteLn('FooResult: built.');     WriteLn('FooResult - Debug 0:');     foo_result_debug(pfoors);     WriteLn('FooResult - Content:');    WriteLn('FooResult - Code: [', pfoors^.ierrorcode, ']');    WriteLn('FooResult: Version '#39, pfoors^.iversion, #39);    WriteLn('FooResult: (Count: '#39, pfoors^.iresultcount, ' / ', MAX_RESULT, #39'):');     for irs := 0 to pfoors^.iresultcount - 1 do      WriteLn('FooResult: Result[', irs, ']: '#39, pfoors^.arrresult[irs], #39'):');     WriteLn('FooResult: 3 Results filling ...');     WriteLn('FooResult: Result 1 filling ...');     foo_build_result(pfoors);     WriteLn('FooResult - Debug 1:');     foo_result_debug(pfoors);     WriteLn('FooResult: Result 2 filling ...');     foo_build_result(pfoors);     WriteLn('FooResult - Debug 2:');     foo_result_debug(pfoors);     WriteLn('FooResult: Result 3 filling ...');     foo_build_result(pfoors);     WriteLn('FooResult - Debug 3:');     foo_result_debug(pfoors);     WriteLn('FooResult: 3 Results filled.');     WriteLn('FooResult - Code: [', pfoors^.ierrorcode, ']');    WriteLn('FooResult: Version '#39, pfoors^.iversion, #39);    WriteLn('FooResult: (Count: '#39, pfoors^.iresultcount, ' / ', MAX_RESULT, #39'):');     for irs := 0 to pfoors^.iresultcount - 1 do      WriteLn('FooResult: Result[', irs, ']: '#39, pfoors^.arrresult[irs], #39);     igtcnt := pfoors^.iresultcount;     WriteLn('FooResult: Array getting ...');     parrrs := foo_get_result_array(pfoors);     if parrrs <> Nil then    begin      for irs := 0 to igtcnt - 1 do        WriteLn('FooResult: Array[', irs, ']: '#39, parrrs^[irs], #39);     end    else  //if parrrs <> Nil then      WriteLn('FooResult: Array get failed!');   end  else  //if pfoors <> Nil then    WriteLn('FooResult: Build failed!');   WriteLn('FooResult: deleting ...');   foo_result_free(pfoors);   WriteLn('FooResult: deleted.');   WriteLn('App: done.');end. 
which prints this Output:

$ ./demofooresult
FooResult: building ...
FooResult: built.
FooResult - Debug 0:
FooResult* Debug: '*FooResult { iversion: 0, iresultcount: -1, ierrorcode: 0, arrresult: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] }'
FooResult - Content:
FooResult - Code: [ 0 ]
FooResult: Version '0'
FooResult: (Count: '-1 / 128'):
FooResult: 3 Results filling ...
FooResult: Result 1 filling ...
FooResult - Debug 1:
FooResult* Debug: '*FooResult { iversion: 1, iresultcount: 1, ierrorcode: 0, arrresult: [1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] }'
FooResult: Result 2 filling ...
FooResult - Debug 2:
FooResult* Debug: '*FooResult { iversion: 2, iresultcount: 2, ierrorcode: 0, arrresult: [1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] }'
FooResult: Result 3 filling ...
FooResult - Debug 3:
FooResult* Debug: '*FooResult { iversion: 3, iresultcount: 3, ierrorcode: 0, arrresult: [1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] }'
FooResult: 3 Results filled.
FooResult - Code: [ 0 ]
FooResult: Version '3'
FooResult: (Count: '3 / 128'):
FooResult: Result[0]: '65536'
FooResult: Result[1]: '131072'
FooResult: Result[2]: '196608'
FooResult: Array getting ...
FooResult: Array[0]: '1'
FooResult: Array[1]: '2'
FooResult: Array[2]: '3'
FooResult: deleting ...
FooResult: deleted.
App: done.
Heap dump by heaptrc unit of /plath/to/demofooresult
6 memory blocks allocated : 719/728
6 memory blocks freed     : 719/728
0 unfreed memory blocks : 0
True heap size : 327680
True free heap : 327680


the direct access to TFooResult.arrresult prints only Rubbish although the Array is as Static Array defined:

FooResult - Code: [ 0 ]
FooResult: Version '3'
FooResult: (Count: '3 / 128'):
FooResult: Result[0]: '65536'
FooResult: Result[1]: '131072'
FooResult: Result[2]: '196608'

marcov:
You declare your Pascal structure as packed. You don't declare your C struct as packed.

Solution: declare your C struct as packed by whatever means your C compiler allows.

(or remove the packed and add {$packrecords C} above the record in Pascal, which is the most likely packing default for a C compiler).

domibay_hugo:
Thank you very much for this Tip!
the access to the Array TFooResult.arrresult works now correctly.

Although I had the understanding that the packed record definition is required to match with C Language Library Definitions.

I also found that the unit ctypes includes the .inc file /rtl/linux/ptypes.inc
which again defines the directives:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$I ctypes.inc}{$packrecords c} 

PascalDragon:

--- Quote from: domibay_hugo on January 04, 2021, 04:48:11 pm ---Although I had the understanding that the packed record definition is required to match with C Language Library Definitions.
--- End quote ---

No. packed ensures that there is no padding between fields of a record. That is not the case by default in C.


--- Quote from: domibay_hugo on January 04, 2021, 04:48:11 pm ---I also found that the unit ctypes includes the .inc file /rtl/linux/ptypes.inc
which again defines the directives:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$I ctypes.inc}{$packrecords c} 
--- End quote ---

That only applies to the records declared inside the ctypes unit (and only if they aren't declared as packed).

marcov:

--- Quote from: domibay_hugo on January 04, 2021, 04:48:11 pm --- Although I had the understanding that the packed record definition is required to match with C Language Library Definitions.

--- End quote ---

I was not aware that the C language standard said something about packing. Usually standards are very restrictive to specify too much about it.

Navigation

[0] Message Index

[#] Next page

Go to full version