CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

variable type forward declaration [solved]

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

variable type forward declaration [solved]
PostPosted: Fri Apr 11, 2014 12:41 pm     Reply with quote

Versions: 5.019 & 5.024...suspect more. PIC doesn't really matter.

I was trying to figure out how to forward declare a variable type in CCS. In most C compilers, I can do the following:

Code:

#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT

#use delay(clock=20000000)

struct nodeA;  //comment this out and it compiles

struct nodeA{
   int16 v;
};


void main (void){

   struct nodeA n;
   n.v= 0;
   
   while(TRUE);
}


but as my comment suggests, the forward declaration doesn't compile. Am I forgetting something simple? If not, is there an alternative in the CCS compiler? I'll be honest and say I am not as familiar with older versions of C, so maybe it is not supported, but I wanted to check.

I know the example is a bit non-sensical since there is no need for the forward declaration, but I wanted to have some structures that cross reference each other and this was a simple example I could produce of the error.


Last edited by jeremiah on Sat Apr 12, 2014 2:32 pm; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Fri Apr 11, 2014 2:20 pm     Reply with quote

Original C, does not allow forward declaration of variables.

A form was added in about C98 (don't quote me on the version...), but required the first declaration to use 'void', rather than an explicit type. So you declare as:

Code:

#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT

#use delay(clock=20000000)

extern void nodeA;  //forward declaration

struct nodeA
{ //This then overrides it for the local context.
   int16 v;
};

void main (void)
{
   struct nodeA n;
   n.v= 0;
   
   while(TRUE);
}

Then later, a form like you show was added (C99?).

The 'extern' void trick basically relies on an external variable always being 'overidden', if a local declaration is then made.

CCS appears to accept the slightly older form, but not the incomplete structure declaration. May do what you need?.

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

PostPosted: Fri Apr 11, 2014 5:32 pm     Reply with quote

Thanks! I'll try it out in my more complex program and see how it goes (should be pretty straight forward). The only way I was able to work around it was using void pointers and casting, but this would work much smoother.

I was guessing it wasn't allowed, but didn't have any older compilers to test out on.

Edit: no good. I appears it thinks I am defining a function with the extern. It errors expecting a parenthesis. If I toss struct in front it errors looking for braces.

Code:

#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT

#use delay(clock=20000000)

extern void nodeA;  //forward declaration

struct nodeB{
   struct nodeA *p;  //doesn't compile
   nodeA *p;         //doesn't compile
   int16 v;
};

struct nodeA{
   int16 v;
};


void main (void){

   struct nodeA n;
   n.v= 0;
   
   while(TRUE);
}


I might be out of luck with this. Any other ideas?
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Sat Apr 12, 2014 4:33 am     Reply with quote

OK.

What you want to do, is not generally supported in C. It is in C's that have C++ variants. You have what is known as an 'incomplete type' (basically the compiler doesn't know the size of it), and these can't be used in structure declarations.
Quote from a current C manual...
"Struct type declared by a forward declaration (i.e. an incomplete type) can be used only in a limited number of ways. You can't use incomplete types in object definitions and you cannot access data fields of incomplete struct types."

I suspect the compilers you are trying are ones that at least in part support C++ operations (that do allow this).
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

PostPosted: Sat Apr 12, 2014 7:26 am     Reply with quote

Yeah, GCC and VStudio are the ones I have used in the past.

A question:
Ttelmah wrote:

Quote from a current C manual...
"Struct type declared by a forward declaration (i.e. an incomplete type) can be used only in a limited number of ways. You can't use incomplete types in object definitions and you cannot access data fields of incomplete struct types."

While I understand that, I would have suspected declaring a pointer to an incomplete type would be fine since you aren't referencing size or elements of it to do that. Doing so would fit the manual excerpt you provided. Using a pointer of an incomplete type in another type declaration doesn't violate the "object definition" or "access data fields" parts that it highlights. I know I couldn't simply define an object of it because the compiler would have to know how to construct the object, but the compiler doesn't need to know how to construct the object from a pointer until you dereference the pointer.

In short, assuming I could forward declare the incomplete struct type, I would expect this to fail:
Code:

struct nodeB{
   struct nodeA n;
   int16 v;
};


But this to work:
Code:

struct nodeB{
   struct nodeA *p;
   int16 v;
};

Does that makes sense?

Now I am curious how older C programmers doing complex data structures constructed nodes that cross reference each other.
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Sat Apr 12, 2014 8:04 am     Reply with quote

Hi Jeremiah,

Take a look at this thread, maybe that will work for you.

http://www.ccsinfo.com/forum/viewtopic.php?t=51315

Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Sat Apr 12, 2014 1:07 pm     Reply with quote

An alternative if this doesn't work, is just to declare either a long integer, or a pointer to another type, and then cast this to be a pointer to the structure you want after this is declared.

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

PostPosted: Sat Apr 12, 2014 2:31 pm     Reply with quote

That's kind of what I was doing in the interim. I was using a void * and casting. I was trying to eliminate having to cast the type everywhere if possible. Alan's suggestion seems to work. I can only compile it at this time, but once I get to some hardware this week I can also test it out.

alan wrote:
Hi Jeremiah,

Take a look at this thread, maybe that will work for you.

http://www.ccsinfo.com/forum/viewtopic.php?t=51315

Regards


Thanks! This appears to do what I want.
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sat Apr 12, 2014 8:25 pm     Reply with quote

jeremiah wrote:

While I understand that, I would have suspected declaring a pointer to an incomplete type would be fine since you aren't referencing size or elements of it to do that


In traditional C this would have been a problem for pointer arithmetic so I am not surprised it did not work.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

PostPosted: Sat Apr 12, 2014 9:55 pm     Reply with quote

I'm not sure I can think of an example where pointer arithmetic happens in a variable declaration. I know once you proceed to assignment it could, but pointer declarations tend to be rather mundane in terms of requirements. You don't need to know the size of the pointer or anything about what it points to until you try to use it in some way (which is past the declaration stage). I would definitely expect pointer arithmetic to be an issue there, but in a declaration I'm not thinking of a scenario where that happens. Where would you run into that?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group