Search code examples
cgccgdblabview

why a difference of opinion between gcc and gdb


GCC thinks I have

sql_LV.c:543:35: error: request for member ‘str’ in something not a structure or union
        &(((**functions).String[i]).str)

GDB is thinks differently:

(gdb) print &(((**functions).String[0]).str)
$1 = (uChar (*)[1]) 0xf550514c
(gdb) print (((**functions).String[0]).str)
$2 = "N"

And here's the code:

typedef struct {
    int32 cnt;      /* number of bytes that follow */
    uChar str[1];   /* cnt bytes */
} LStr, *LStrPtr, **LStrHandle;

typedef struct {
    int32 dimSize;
    LStrHandle String[1];
    } LStrArry;
typedef LStrArry **LStrArryHdl;

char IsFunction(LStrArryHdl functions, char* InStr, int32 InStrLen) {
    if (functions == NULL) return 0;
    for (int i = 0; i< (**functions).dimSize; i++) {
        if (strncmp(InStr,
                            &(((**functions).String[i]).str),
                            (InStrLen < ((**functions).String[i].cnt) ? InStrLen : ((**functions).String[i].cnt))
                            ) == 0) return 1; 
    }
    return 0;
}

So what's the discrepancy? I've included the typedefs.


Solution

  • To understand what's going on you just need to break the types down, so in:

    &(((**functions).String[i]).str)
    

    the type of String[i] is LStrHandle, which is **LStr. And so you can't apply the . operator.

    If you dereference String[i] then you'll have a *Lstr, to which -> could be applied, as in:

    &((*((**functions).String[i]))->str)
    

    The same error has been made with your uses of .cnt in the following lines.

    I'm also a little suspicious of your use of & in this line. As str is defined as uChar str[1]; (assuming typedef unsigned char uChar), then the type of this line &((*((**functions).String[i]))->str) will be unsigned char **, when I suspect you really wanted unsigned char *. You might want to drop the leading &?