I'm fairly certain this is a bug with the compiler, but just to be sure I am not making a silly mistake...
I have two files that include the same header file.
The header file looks like this:
#ifndef GYRO_H
#define GYRO_H
/*
This is a list of registers in the ITG-3200. Registers are parameters that
determine how the sensor will behave, or they can hold data that represent the
sensors current status. To learn more about the registers on the ITG-3200,
download and read the datasheet.
*/
char WHO_AM_I = 0x00;
char SMPLRT_DIV= 0x15;
char DLPF_FS = 0x16;
char GYRO_XOUT_H = 0x1D;
char GYRO_XOUT_L = 0x1E;
char GYRO_YOUT_H = 0x1F;
char GYRO_YOUT_L = 0x20;
char GYRO_ZOUT_H = 0x21;
char GYRO_ZOUT_L = 0x22;
/*
This is a list of settings that can be loaded into the registers.
DLPF, Full Scale Register Bits
FS_SEL must be set to 3 for proper operation
Set DLPF_CFG to 3 for 1kHz Fint and 42 Hz Low Pass Filter
*/
char DLPF_CFG_0 = 1<<0;
char DLPF_CFG_1 = 1<<1;
char DLPF_CFG_2 = 1<<2;
char DLPF_FS_SEL_0 = 1<<3;
char DLPF_FS_SEL_1 = 1<<4;
/*address of gyro on I2C*/
char itgAddress = 0x68;
/*write and read addressed on i2c for Gyro*/
void itgWrite(char address, char registerAddress, char data);
unsigned char itgRead(char address, char registerAddress);
/*get x, y, and z axis angular rates from gyro*/
int gyroReadX(void);
int gyroReadY(void);
int gyroReadZ(void);
#endif
Note the #ifndef/#define/#endif preprocessor directives.
Two files (myproject_gyrotest.ino and Gyro.cpp) include this "Gyro.h" via:
#include "Gyro.h"
I get the following errors when compiling:
myproject_gyrotest.cpp.o:(.data.itgAddress+0x0): multiple definition of `itgAddress'
Gyro.cpp.o:(.data.itgAddress+0x0): first defined here
c:/arduino/arduino-1.0.2-windows/arduino-1.0.2/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: Disabling relaxation: it will not work with multiple definitions
along with tons of other multiple inclusion problems.
I mean, am I being a complete idiot, or is this another compiler bug? (There are several other bugs with this Arduino compiler I have found the hard way that are documented elsewhere).
#defines are only defined within the compilation unit. You want each compilation unit to have your header file included exactly once. You don't want to do anything that allocates memory in a header file.
Thanks, johnwasser, for the post. I have since changed all of my allocated variables to pound defines to avoid the problem I was having. I will take your advice in the future about using const and externs.
While two files include "Gyro.h", the pre-processor directives should indicate to the compiler to only create one copy of Gyro.h and link the other files against it, which (I would think) prevent the multiple inclusion problem.
I will switch to my Ubuntu drive in a minute to see how gcc handles this situation.
desh:
Thanks, johnwasser, for the post. I have since changed all of my allocated variables to pound defines to avoid the problem I was having. I will take your advice in the future about using const and externs.
While two files include "Gyro.h", the pre-processor directives should indicate to the compiler to only create one copy of Gyro.h and link the other files against it, which (I would think) prevent the multiple inclusion problem.
I will switch to my Ubuntu drive in a minute to see how gcc handles this situation.
.h files aren't compiled. The compiler literally replaces the #include line with the file you want to include, so the contents of the .h file exist in every compiled file (.c, .cpp, .ino, .pde) that includes it. The include guards (#ifndef... #define) prevent the contents of the .h file to be copied in twice, but it will still be copied in every compiled file that includes it.