# C Structure Problem

Lancelot59
I have a function for my robot that reads multiple IR sensors, and I get a syntax error on the bolded lines.

Code:
//Performs An ADC Reading On All RLS Channels
{

}
Pretty simple. It access a structure located in the header file for that source file. It's declared as external so that functions in other files can find it.

Code:
//This structure contains the ADC values for each sensor
{
int RLS_LOuter;		//Outer Left Sensor
int RLS_LInner;		//Inner Left Sensor
int RLS_Centre;		//Centre Sensor
int RLS_RInner;		//Inner Right Sensor
int RLS_ROuter;		//Outer Right Sensor
};

//Tag for the above structure
extern struct Sensors_ADC SensorsADC;

I get a syntax error when I try to access the structure on the lines that have been bolded in the function declaration.

From what I can tell I haven't misdeclared anything, and the data type for the ReadADC() function matches according to the data sheet. I thought it might be cause I made a declare statement that used the same terms for each channel as the members of the structure, but I changed one of them and the error remained.

So what's going on here?

Last edited:

Homework Helper
Why is the structure declared as Sensors_ADC even though you were referring to SensorsADC in the code? Also, you have to actually declare the structure as an object, like this:

sensor_data.RLS_LOuter = whatever

Lancelot59
I thought that's what the tag did. I defined it as Sensors_ADC and declared it as an object called SensorsADC.

Unless my terminology is totally wrong. Pretty much everything I know about programming is self taught.

EDIT: Turns out that I did have some left over declares sitting around with the same names as the structure members...well that's embarrassing.

So moving onto an actual question now. With the way I've declared the structure, will functions defined in other files be able to read the structures?

Last edited:
Homework Helper
I just looked at the code again, and it looks like I overlooked a couple of things before.

First, you cannot use extern to declare a structure. extern is only for functions and variables. Second, you declared SensorsADC but never defined it. In your main program, you have to do:

to actually define the object. Of course, this makes the "extern struct Sensors_ADC SensorsADC;" meaningless unless you want SensorsADC to be visible from other files as well.

I'd recommend a simple approach: remove all the extern's, remove the declaration "extern struct Sensors_ADC SensorsADC;", and just #include the header file where the structure is declared, then define SensorsADC directly.

Staff Emeritus
Code:
	//Reads Left Outer Sensor

...
}
What is the RLS_LOuter you are passing to SetChanADC() in the above code snippet? I suspect that have you #defined it to some integer value. If so, the compiler is going to be very confused by the assignment to SensorsADC.RLS_LOuter.

I'd recommend a simple approach: remove all the extern's, remove the declaration "extern struct Sensors_ADC SensorsADC;", and just #include the header file where the structure is declared, then define SensorsADC directly.
The compiler might be happy with this setup, but the linker will not, and neither will the programmer. What this will do is make multiple copies of entities with the same name (SensorsADC). The linker might, and hopefully will, complain and die. Some linkers complain and take the first (or maybe last) one they come across (not good), others don't even complain.

The consequence of declaring a variable extern (e.g., extern struct Sensors_ADC SensorsADC;) is to tell the compiler that the variable lives somewhere else. The compiler will mark uses of that external entity as a undefined references to be resolved by the linker. The reason for declaring a variable extern is to serve as a behind-the-scenes form of communication.

Lancelot59: Those global variables will bite you, big time. Use of them is a strongly discouraged practice in many, many places. I suggest a different approach than the one you are taking:
2. Pass a pointer to that variable to the functions that need to use it, and only to those functions.

BTW, use of precompiler symbols will bite you too. I think that is what bit you here.

Homework Helper
The compiler might be happy with this setup, but the linker will not, and neither will the programmer. What this will do is make multiple copies of entities with the same name (SensorsADC). The linker might, and hopefully will, complain and die. Some linkers complain and take the first (or maybe last) one they come across (not good), others don't even complain.

Why would that happen? #include only inserts the struct declaration into the file. After that, a struct definition like "struct Sensors_ADC SensorsADC;" would create only 1 instance of SensorsADC.

Staff Emeritus
Depends on whether the declaration was at file scope or function scope.

This is a sensor structure for a set of sensors. There should be one instance per set of sensors in the program, and only one instance per set of sensors throughout the program. You don't want everything that needs sensor data going to the sensor to get the data.

In fact, most things that need sensor data don't really need the raw sensor data. They need data that has been properly filtered and converted to engineering units.

Lancelot59
In fact, most things that need sensor data don't really need the raw sensor data. They need data that has been properly filtered and converted to engineering units.

Well in this case I'm just taking in a raw ADC bin and comparing it to what I've defined as a threshold value. If it's over that threshold it's on the track. I that's why I have a second structure that just contains 1s and 0s depending on the status of each sensor.

I did catch that I named the members the same as the defines of the ADC channels, that's happened a few times. Not too many though. The compiler is now just sitting at the directional_control.c/.h files because they're empty. I still need to give this robot a brain.

But going back to the extern declaration, I've seen it being used on arrays and such, so why not structures?

EDIT:

I have a problem now. Nothing in any of the other files can see the structures.

This:
Code:
void LED_Sensor_Display(void)
{
setLED1(SensorsTrack.LOuter);
setLED2(SensorsTrack.LInner);
setLED3(SensorsTrack.Centre);
setLED4(SensorsTrack.RInner);
setLED5(SensorsTrack.ROuter);
}
controls a set of LEDs on the brainboard for the robot. The compiler isn't putting the two together.

Error:
Code:
Error - could not find definition of symbol 'SensorsTrack' in file './LED_control.o'.

Last edited:
Staff Emeritus
But going back to the extern declaration, I've seen it being used on arrays and such, so why not structures?
Because it doesn't sense. The extern keyword is a storage qualifier; it applies to things that occupy memory when the program is loaded -- in other words, variables and functions. Structure definitions aren't stored.

Example: Consider this program:
Code:
#include <stdio.h>
struct Foo {
double big_array[1024][1024][1024][1024][1024][1024];
};

int main () {
printf ("sizeof(Foo) = %lu\n", sizeof(Foo));
return 0;
}
This program defines a structure, a big, huge structure (8 exabytes!) that would never fit in any existing computer's memory (physical or virtual). However, because the structure is never used to allocate memory (e.g., define a variable), the resulting program's footprint is no bigger than this program:
Code:
#include <stdio.h>
struct Foo {
double number;
};

int main () {
printf ("sizeof(Foo) = %lu\n", sizeof(Foo));
return 0;
}

Now change the main in both versions so that they use the structure (other than measuring its size, which is a compile-time operation):
Code:
int main () {
Foo foo;
printf ("sizeof(foo) = %lu\n", sizeof(foo));
return 0;
}

The version with the 8 exabyte structure will now fail (segmentation fault on a unix machine).

I have a problem now. Nothing in any of the other files can see the structures.
That looks like a linker error.

Stop using global variables and a lot of your problems will go away. Using global variables is a bad practice. I suggest kicking that bad habit.

Lancelot59
I never use global variables. :/ I have the structure defined in the detector.h file, and I'm trying to make a LED control function read that structure's members.

Staff Emeritus