cgcc64-bit

C Size of array is too big


Been given the task to convert code from the 80's to 64 bit.

Error given error: size of array "spare2" is too large

This is line 76 of a header file

Line 76 uchar spare2[1018-XVIEWS*sizeof(view)-4*12] ;

Full Block


#define XVIEWS  25        /* max would be 26.9          */

typedef struct { struct {
    rec_noi root        ; /* seqtree root           */
    ushort  nlevels     ; /* # levels in seqtree        */

#if LALIGN
    ushort  del_head    ; /* [al] wunaligned long       */
    ushort  del_head2   ;
    ushort  ndel        ; /* [al] ditto             */
    ushort  ndel2       ;
#else
    ulong   del_head    ; /* first deleted seq# + 1     */
                  /* (0 or 0x0FFFFFFF if none)      */
    ulong   ndel        ; /* # deleted seq#s            */
#endif
                  /* remainder of record is waligned    */
    uchar   flags       ; /* bitfield set with DCRF_values  */
    bool1   tobedeleted ; /* database to be deleted?        */
    rec_no  idr[4]      ; /* list of: index defn records    */
    rec_no  irtab       ; /* irule record chain head        */
    ulong   spare1      ; /* help yourself          */
    rec_no  viewselect  ; /* view selection record      */
    view    V[XVIEWS]   ; /* view information           */
    rec_no  vcont       ; /* view continuation record       */
    uchar   spare2[1018-XVIEWS*sizeof(view)-4*12] ;
    } DCRREC ; } dcrrec ;

Tried gcc -g -march=x86-64 -v file.c -o file.o -Wl,--heap,SIZE

But no matter what I try to change the heap size to, I keep getting the same the same error. I also tried changing heap to stack and both heap and stack. No change.

Should I be doing something else?

EDIT: I found out I left out another important piece of information. I am currently trying to figure out what is rec_no


typedef struct view {
    rec_no  canuse      ; /* master DDB index #'s in use record */
                  /* view:  fields allowed from view    */
    rec_no  permission  ; /* permission record          */
    rec_no  symrec      ; /* sym def rec fdrid          */
    rec_no  objrec      ; /* allowed function list      */
                  /*    (currently -> vdr)      */
    uchar   dbname[12]  ; /* database name (BASIC string)   */
    rec_no  autoglo     ; /* autoglobal record          */
    rec_no  sttab       ; /* storage rule table chain head  */
    } view ;```

Solution

  • The line uchar spare2[1018-XVIEWS*sizeof(view)-4*12]; is used to specify padding for the element size to be exactly 1018 bytes long.

    The definitions of all types used in this fragment are not posted: rec_noi, rec_no, ushort, ulong, uchar, bool1 and view. ushort, uchar and ulong are probably self explanatory, but might hide some surprising definitions.

    The problem is the view structure is larger on your 64-bit target than on the original system, and other fields are probably larger too as ulong may be 64-bit instead of 32 (as is the case on linux and macOS). The hard-coded computation evaluates to a negative quantity, which becomes a (very) large positive number because sizeof(view) has the unsigned type size_t (presumably 64-bit) and this makes the whole expression an unsigned value, hence the error message.

    Porting this code to 64-bit may prove difficult: you might first try and change the types to fixed width types such as uint16_t and uint32_t to avoid architecture dependent sizes.

    You can try and typedef ulong to uint32_t instead of unsigned long, but the code might use long too and you cannot easily change those with a typedef.

    If the project is open sourced, you can post a link to the source code for more porting recommendations.