| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| JAM2014 
 
 
 Joined: 24 Apr 2014
 Posts: 140
 
 
 
			    
 
 | 
			
				| Problem with a Structure.... |  
				|  Posted: Mon Feb 03, 2020 5:43 pm |   |  
				| 
 |  
				| Hi All, 
 Admittedly a Structure 'newbie' here.....
 
 I have the following structure definition:
 
  	  | Code: |  	  | typedef struct _AzElInfo
 {
 int16 AZ;
 int8 EL;
 } AzElInfo;
 
 | 
 
 I try to use the elements in the Structure like this:
 
  	  | Code: |  	  | AzElInfo.AZ = 90;
 AzElInfo.EL = 90;
 
 | 
 
 But, for each I get the compiler error 'element is not a member'!
 
 Compiler is PCH v5.050
 
 What am I doing wrong?
 
 Jack
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Feb 03, 2020 5:49 pm |   |  
				| 
 |  
				| You typedef'ed it.  This creates a type.  You should then use the type to declare an instance of the structure.  Here's an example:
 
 This test program compiles with no errors:
 
  	  | Code: |  	  | #include <18F46K22.h> #fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOPBADEN
 #use delay(clock=4M)
 #use rs232(baud=9600, UART1, ERRORS)
 
 typedef struct _AzElInfo
 {
 int16 AZ;
 int8 EL;
 } AzElInfo;
 
 AzElInfo my_struct;
 
 //==============================
 void main()
 {
 
 //AzElInfo.AZ = 90;
 //AzElInfo.EL = 90;
 
 
 my_struct.AZ = 90;
 my_struct.EL = 90;
 
 
 
 while(TRUE);
 }
 | 
 |  | 
	
		|  | 
	
		| JAM2014 
 
 
 Joined: 24 Apr 2014
 Posts: 140
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Feb 04, 2020 4:16 pm |   |  
				| 
 |  
				| Hi PCM, 
 I actually wanted that TypeDef, but I should have mentioned those details explicitly. This structure exists in an include file that handles the decoding/parsing of a data string passed to it. After reading your reply, I realized I needed to do the following:
 
 
  	  | Code: |  	  | AzElInfo->AZ = 90; //<--- This is test code. An actual calculation goes here!
 
 | 
 
 In my main program I have the following:
 
 
  	  | Code: |  	  | //Needed for the AZ_EL_Decode Parsing Routines.....
 AZELInfo MyAZELInfo;
 
 //Here we put the Az & El data into the AZEL structure...
 AZEL_decode(Msg_Buffer, &MyAZELInfo);
 
 Azimuth = MyAZELInfo.AZ;
 Elevation = MyAZELInfo.EL;
 | 
 
 It's all working like a champ now!
   
 Thanks!
 
 Jack
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Feb 04, 2020 10:29 pm |   |  
				| 
 |  
				| I don't like your comment here: 
  	  | JAM2014 wrote: |  	  | //Needed for the AZ_EL_Decode Parsing Routines.....
 AZELInfo MyAZELInfo;
 
 | 
 Your comment implies that the line of code above is a "bodge" designed
 to get around a limitation or something.
 
 But in fact, it's needed to create an instance of the structure defined
 in the typedef statement.   If that line is not there, the compiler will
 not allocate any RAM for the structure.  It will not exist.
 
 This method, typedef of a structure and the creation of an instance of it,
 is part of the C language.  It's not a bodge.
 
 Here I've made a test program with two structures.  One is typedef'ed
 and the other is not:
 
  	  | Code: |  	  | #include <18F46K22.h>
 #fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOPBADEN
 #use delay(clock=4M)
 #use rs232(baud=9600, UART1, ERRORS)
 
 // This one is typedef'ed:
 typedef struct _AzElInfo_typdef
 {
 int16 AZ;
 int8 EL;
 } AzElInfo_typedef;
 
 
 // This one is not:
 struct _AzElInfo_not_typedef
 {
 int16 AZ;
 int8 EL;
 } AzElInfo_not_typedef;
 
 //==============================
 void main()
 {
 
 
 while(TRUE);
 }
 | 
 
 Now let's look at the .SYM file to see how the compiler allocated RAM:
 
  	  | Quote: |  	  | 000     @SCRATCH
 001     @SCRATCH
 001     _RETURN_
 002     @SCRATCH
 003     @SCRATCH
 004     rs232_errors
 005-007 AzElInfo_not_typedef
 F55     CCP_5
 F55     CCP_5_LOW
 F56     CCP_5_HIGH
 F58     CCP_4_LOW
 F58     CCP_4
 F59     CCP_4_HIGH
 
 | 
 We see that it allocated RAM for the structure that's not typedef'ed,
 but it did not do it for the typdef'ed one.
 
 If you create a typedef, it is essential to use the new type to declare
 an instance of the type, to get the compiler to actually create it in RAM.
 |  | 
	
		|  | 
	
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Feb 05, 2020 1:24 am |   |  
				| 
 |  
				| To 'reinforce' this, it is worth simply 'reading the manual'. Quote from the typedef manual page:
 
  	  | Quote: |  	  | The identifier does not allocate space but rather may be used as a type specifier in other data definitions
 
 | 
 
 Typedef is a way of declaring a 'shorthand' for a declaration. It declares a
 new type by name, that can then be used to declare variables. It does
 not itself declare the variable.
 |  | 
	
		|  | 
	
		| JAM2014 
 
 
 Joined: 24 Apr 2014
 Posts: 140
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Feb 10, 2020 5:15 pm |   |  
				| 
 |  
				| Hello PCM, 
 Of course, everything you say is 100% correct! Thank you for your help, and for reiterating that point!
 
 That comment was poorly worded! Sometimes I cut-n-paste comments with minimal editing, and this was one of them. I should have done a better job!
 
 Thanks again for the reminder!
   
 Jack
 |  | 
	
		|  | 
	
		|  |