PROS Header Files Help

So I’m getting a error with compiling PROS and I’m not sure how to fix it. I have a header file called functions.h which has some functions in it and that is #include "functions.h" in my main.h file. Now when ever I compile I get errors in the linking telling me that the function was first defined here To my understanding that means It has already been defined somewhere but I don’t understand how that would be. I would be much appreciative of any help given.

Here’s my code, I’m using C for this btw. Output of make at the very bottom.
main.h

#ifndef _PROS_MAIN_H_
#define _PROS_MAIN_H_

//#define PROS_USE_SIMPLE_NAMES //Allow for shorting naming of enum for things like buttons and the controller and other commonly used enums
#define E_CONTROLLER_MASTER master //Just makes thing shorter

//Defining ports for everything
#define FL_MTR_PORT 5 //FL_MTR:Front Left Motor
#define FR_MTR_PORT 15 //FR_MTR:Front Right Motor
#define BL_MTR_PORT 4 //BL_MTR:Back Left Motor
#define BR_MTR_PORT 13 //BR_MTR:Back Right Motor

//Holds the max velocity for each motors gear box
#define MOTOR_GEARBOX_RED             				100
#define MOTOR_GEARBOX_GREEN           				200
#define MOTOR_GEARBOX_BLUE            				600

//Includes should be put here
#include "api.h"
#include <math.h>
#include "types.h"
#include "functions.h"

//Prototypes for the competition control tasks are redefined here to ensure
//that they can be called from user code (i.e. calling autonomous from a
//button press in opcontrol() for testing purposes).
#ifdef __cplusplus
extern "C" {
#endif
void autonomous(void);
void initialize(void);
void disabled(void);
void competition_initialize(void);
void opcontrol(void);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
/**
 * You can add C++-only headers here
 */
//#include <iostream>
#endif

#endif  // _PROS_MAIN_H_

functions.h

#ifndef _FUNCTIONS_H_
#define _FUNCTIONS_H_

//Use this to clamp a interger.
//clampInteger (&n , Minimum , Maximum);
void clampInteger (int *ptrn, int f, int c)
{
	*ptrn = (*ptrn<f) ? f : *ptrn;
	*ptrn = (*ptrn>c) ? c : *ptrn;
}

//n = keepNegativeExponent (n, Exponent);
int keepNegativeExponent (int n, double e)
{
	int m;
	m = abs(n);
	return n = ((n>=0) ? pow(n, e) : pow(m, e) * -1);
};

#endif // _FUNCTIONS_H_

opcontrol.c

#include "main.h"

extern struct Base driver;

//Joystick vaules
int anlx, anly, anrx;

void opcontrol() {
	//Careful, this loop can not be exited from inside. Change if needed.
	for (;;) {

	}
}

initialize.c

#include "main.h"

void initialize()
{
	struct Base driver;

	//Setup for all of the motors
	//These are the drive motors, E_MOTOR_GEARSET_18 = 1, E_MOTOR_ENCODER_ROTATIONS = 1
	driver.motor[0] = FL_MTR_PORT; driver.motor[1] = FR_MTR_PORT; driver.motor[2] = BL_MTR_PORT; driver.motor[3] = BR_MTR_PORT;
	for (int i=0;i<4;i++)
	{
		motor_set_reversed (driver.motor[i], false);
		motor_set_gearing (driver.motor[i], 1);
		motor_set_encoder_units (driver.motor[i], 1);
	}
}

void disabled()
{

}

void competition_initialize()
{

}

autonomous.c is just the default template.
Output of prosv5 make

laptop :: ~/git/VEX-2019-Tower-takeover ‹testing*› » prosv5 make
Compiling src/autonomous.c [OK]
Compiling src/initialize.c [OK]
Compiling src/opcontrol.c [OK]
Adding timestamp [OK]
Linking project with libpros,okapilib [ERRORS]
/usr/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld: ./bin/initialize.c.o: in function `clampInteger':
initialize.c:(.text.clampInteger+0x0): multiple definition of `clampInteger'; ./bin/autonomous.c.o:autonomous.c:(.text.clampInteger+0x0): first defined here
/usr/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld: ./bin/initialize.c.o: in function `keepNegativeExponent':
initialize.c:(.text.keepNegativeExponent+0x0): multiple definition of `keepNegativeExponent'; ./bin/autonomous.c.o:autonomous.c:(.text.keepNegativeExponent+0x0): first defined here
/usr/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld: ./bin/opcontrol.c.o: in function `clampInteger':
opcontrol.c:(.text.clampInteger+0x0): multiple definition of `clampInteger'; ./bin/autonomous.c.o:autonomous.c:(.text.clampInteger+0x0): first defined here
/usr/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld: ./bin/opcontrol.c.o: in function `keepNegativeExponent':
opcontrol.c:(.text.keepNegativeExponent+0x0): multiple definition of `keepNegativeExponent'; ./bin/autonomous.c.o:autonomous.c:(.text.keepNegativeExponent+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [common.mk:191: bin/monolith.elf] Error 1
Error: Failed to build

Here are two responses to people who have made the same mistake as you.


In the same way you should not include source files into each other, you should not have definitions of functions in header files. When the header files propagate through the program, each function gets compiled over and over, and it creates duplicates of the same function name.
Instead, you need a single location for the functions (in a source file), and a header file (that can be duplicated endlessly) which contains forward declarations for those functions.

1 Like

Thank you, that clears things up. Was not aware that it is bad to put function definitions in header files.