[CANNOT BE SOLVED] The Right Way To Type Cast A Pointer

Need help with C, C++, perl, python, etc?

[CANNOT BE SOLVED] The Right Way To Type Cast A Pointer

Postby Caitlin » 2017-08-13 18:49

I have this C program, and I keep getting compile warnings. (The entire program is thousands of lines long, so I can't post the whole thing -- but I'll include all the relevant parts.)

The problem occurs when one structure, TPARAMS, points to another structure, XUNDO2, and that structure points to a short table, xnewstep[], which points to yet another structure, ELEMENT. But the pointer to XUNDO2 can also point to XUNDO1 or XUNDO3, so it is defined as a void* pointer.

Since THAT pointer is NOT defined as struct XUNDO2*, the compiler doesn't know where to find the xnewstep table. I want to use a type cast to say, in this case, the pointer indeed points to an XUNDO2 structure.

Code: Select all
struct XUNDO1
   {struct ELEMENT* xnewstep[9];
    struct ELEMENT* xoldstep[9];
    char xvalue[9];};

struct XUNDO2
   {struct ELEMENT* xnewstep[9];};

struct XUNDO3
   {struct ELEMENT* xpostreq[100];};

struct TPARAMS
   {short int action;
    char kind;
    char newtsnum[6];
    char newstat;
    struct ELEMENT* newtask;
    struct ELEMENT* oldtask;
    struct ELEMENT* addpoint;
    struct ELEMENT* topstep;
    struct UNDO* unthing;
    void*          /* points to the extended undo area; this could */
     xthing;};     /* be the structure XUNDO1, XUNDO2, or XUNDO3   */

struct ELEMENT
   {struct ELEMENT* chain1;
    struct ELEMENT* chain2;
    struct ELEMENT* chain3;
    short int duetime;
    short unsigned int duedate;
    char status;
    char priority[2];
    char tasktype;
    char tasknum[4];
    char stepnum;
    char descript[2];};

void edittask(struct ELEMENT* origtask)
   {struct TPARAMS t;
    . . .
       {t.oldtask = ((struct XUNDO2*)t.xthing)-> xnewstep[i];  /* WORKS FINE */
    . . .
    baseopts(&t);
    . . .

void baseopts(struct TPARAMS* t)
    . . .
       {addopts(descbuf, t);
    . . .

void addopts(char descbuf[], struct TPARAMS* t)
    . . .
               {if ((struct XUNDO2*)t-> xthing-> xnewstep[s] != 0) break;};
    . . .

The last line of code above, with the break keyword, is the one that has the problem.

When I compile this, I get Warning . . . 'xnewstep' not part of structure in function addopts .

I want to be able to use the type cast "(struct XUNDO2*)" to let the compiler know I'm pointing to an XUNDO2 structure -- but I can't seem to figure out exactly where to put it.

I can work around this problem by assigning t-> xthing to a temporary variable then type casting that, or by redefining xthing as a struct XUNDO2* variable. But either of these solutions would reduce the readability of the program.

I've googled type casts and pointers, but nothing I found covers this exact situation.

I'm using Turbo C and running the binary under DOSBox under Debian Stretch with the MATE desktop. (Later on, I will rewrite this in a more modern language.) But if someone can give me a syntax that works under gcc, I'll accept that as solution to the problem.

Caitlin
Last edited by Caitlin on 2017-08-15 10:36, edited 1 time in total.
Caitlin
 
Posts: 236
Joined: 2012-05-24 07:32

Re: The Right Way To Type Cast A Pointer

Postby luvr » 2017-08-15 07:18

If I understand correctly, then "t-> xthing" should be the pointer to the XUNDO2 structure. My knowledge of C is getting a bit rusty, but inserting a pair of parentheses should help, then:
Code: Select all
{if ((struct XUNDO2*)(t-> xthing)-> xnewstep[s] != 0) break;};
luvr
 
Posts: 79
Joined: 2016-07-21 19:39
Location: Boom - The Home Town of Tomorrowland, Belgium

Re: The Right Way To Type Cast A Pointer

Postby Caitlin » 2017-08-15 10:35

Hi luvr,

I tried {if ((struct XUNDO2*)(t-> xthing)-> xnewstep[s] != 0) break;}; -- didn't work.

I also tried {if ((t-> (struct XUNDO2*)xthing)-> xnewstep[s] != 0) break;}; and {if (((struct XUNDO2*)(t-> xthing))-> xnewstep[s] != 0) break;}; -- those didn't work, either.

Perhaps the inability to correctly type cast it is an anomaly of the compiler I'm using. So I'm closing this problem as cannot be solved.

Thanks anyway.

Caitlin
Caitlin
 
Posts: 236
Joined: 2012-05-24 07:32

Re: [CANNOT BE SOLVED] The Right Way To Type Cast A Pointer

Postby luvr » 2017-08-16 13:40

Not sure if this is still relevant, but perhaps you could store the "t-> xthing" value into a temporary "struct XUNDO2*" variable, say "px", and then dereference that?
luvr
 
Posts: 79
Joined: 2016-07-21 19:39
Location: Boom - The Home Town of Tomorrowland, Belgium

Re: [CANNOT BE SOLVED] The Right Way To Type Cast A Pointer

Postby imazighen-thamzgha » 2017-10-15 09:37

why there's a space before
Code: Select all
 xnewstep[s]
?
ⵉⵎⴰⵣⵉⵖⴻⵏ / imaZighen
imazighen-thamzgha
 
Posts: 38
Joined: 2017-04-21 09:38

Re: [CANNOT BE SOLVED] The Right Way To Type Cast A Pointer

Postby ralph.ronnquist » 2017-10-15 11:41

Since "->" is prior to type cast. you'll need to be more explicit about priority, as in the following
Code: Select all
{if (((struct XUNDO2*)t-> xthing)-> xnewstep[s] != 0) break;};
I.e., you have to indicate to the compiler that the type cast of "((struct XUNDO2*)" need to be applied before the final de-reference.
User avatar
ralph.ronnquist
 
Posts: 308
Joined: 2015-12-19 01:07
Location: Melbourne, Australia


Return to Programming

Who is online

Users browsing this forum: No registered users and 2 guests

fashionable