Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

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

Programming languages, Coding, Executables, Package Creation, and Scripting.
Post Reply
Message
Author
Caitlin
Posts: 329
Joined: 2012-05-24 07:32
Has thanked: 3 times
Been thanked: 2 times

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

#1 Post by Caitlin »

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.

luvr
Posts: 85
Joined: 2016-07-21 19:39
Location: Boom - The Home Town of Tomorrowland, Belgium

Re: The Right Way To Type Cast A Pointer

#2 Post by luvr »

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;};

Caitlin
Posts: 329
Joined: 2012-05-24 07:32
Has thanked: 3 times
Been thanked: 2 times

Re: The Right Way To Type Cast A Pointer

#3 Post by Caitlin »

Hi luvr,

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

I also tried {if ((t-> (struct XUNDO2*)xthing)-> xnewstep != 0) break;}; and {if (((struct XUNDO2*)(t-> xthing))-> xnewstep != 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

luvr
Posts: 85
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

#4 Post by luvr »

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?

imazighen-thamzgha
Posts: 38
Joined: 2017-04-21 09:38

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

#5 Post by imazighen-thamzgha »

why there's a space before

Code: Select all

 xnewstep[s]
?
ⵉⵎⴰⵣⵉⵖⴻⵏ / imaZighen

User avatar
ralph.ronnquist
Posts: 342
Joined: 2015-12-19 01:07
Location: Melbourne, Australia
Been thanked: 6 times

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

#6 Post by ralph.ronnquist »

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.

luvr
Posts: 85
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

#7 Post by luvr »

Although this is an ancient thread, I just recently bumped into it again. I got curious about this issue, so I experimented a little.
I eventually came up with the following, which compiles fine with gcc 7.5 under Ubuntu 18.04:

Code: Select all

{if (((struct XUNDO2*)(t-> xthing)) -> xnewstep[s] != 0) break;};
Just so you know... :wink:

Post Reply