Multiple definition error (ld returned 1 exit status)

Hi All,

I am trying to overcome a multiple definition error:
error: ld returned 1 exit status

I am in the process of refactoring my project from a monolithic file to lots of singleton classes. Some of these singletons import other singletons to access variables or functions. So far so good.

In the monolith app i used the following to sort arrays for me. ArduinoSort.h, no .cpp file.

#ifndef __ARDUINOSORT_H
#define __ARDUINOSORT_H

/**** These are the functions you can use ****/

// Sort an array
template<typename AnyType> void sortArray(AnyType array[], size_t sizeOfArray);

// Sort in reverse
template<typename AnyType> void sortArrayReverse(AnyType array[], size_t sizeOfArray);

// Sort an array with custom comparison function
template<typename AnyType> void sortArray(AnyType array[], size_t sizeOfArray, bool (*largerThan)(AnyType, AnyType));

// Sort in reverse with custom comparison function
template<typename AnyType> void sortArrayReverse(AnyType array[], size_t sizeOfArray, bool (*largerThan)(AnyType, AnyType));


/**** Implementation below. Do not use below functions ****/

namespace ArduinoSort {
	template<typename AnyType> bool builtinLargerThan(AnyType first, AnyType second) {
		return first > second;
	}

	template<> bool builtinLargerThan(char* first, char* second) {
		return strcmp(first, second) > 0;
	}

	template<typename AnyType> void insertionSort(AnyType array[], size_t sizeOfArray, bool reverse, bool (*largerThan)(AnyType, AnyType)) {
		for (size_t i = 1; i < sizeOfArray; i++) {
			for (size_t j = i; j > 0 && (largerThan(array[j-1], array[j]) != reverse); j--) {
				AnyType tmp = array[j-1];
				array[j-1] = array[j];
				array[j] = tmp;
			}
		}
	}
}

template<typename AnyType> void sortArray(AnyType array[], size_t sizeOfArray) {
	ArduinoSort::insertionSort(array, sizeOfArray, false, ArduinoSort::builtinLargerThan);
}

template<typename AnyType> void sortArrayReverse(AnyType array[], size_t sizeOfArray) {
	ArduinoSort::insertionSort(array, sizeOfArray, true, ArduinoSort::builtinLargerThan);
}

template<typename AnyType> void sortArray(AnyType array[], size_t sizeOfArray, bool (*largerThan)(AnyType, AnyType)) {
	ArduinoSort::insertionSort(array, sizeOfArray, false, largerThan);
}

template<typename AnyType> void sortArrayReverse(AnyType array[], size_t sizeOfArray, bool (*largerThan)(AnyType, AnyType)) {
	ArduinoSort::insertionSort(array, sizeOfArray, true, largerThan);
}


#endif

So I have added a new file to my src folder ArduinoSort.h. I then use #include "ArduinoSort.h" in one of my singleton loadcell.h files so that I can use the sort function in the singleton's loadcell.cpp file. This results in the multideclaration error:

src/ArduinoSort.h:26: multiple definition of `bool ArduinoSort::builtinLargerThan<char*>(char*, char*)'; ../../../build/target/user/platform-23-mlibuser.a(bench_test.o):src/ArduinoSort.h:26: first defined here
/root/.particle/toolchains/gcc-arm/10.2.1/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: ../../../build/target/user/platform-23-mlibuser.a(loadcells.o): in function `bool ArduinoSort::builtinLargerThan<char*>(char*, char*)':
src/ArduinoSort.h:26: multiple definition of `bool ArduinoSort::builtinLargerThan<char*>(char*, char*)'; ../../../build/target/user/platform-23-mlibuser.a(bench_test.o):src/ArduinoSort.h:26: first defined here
collect2: error: ld returned 1 exit status

The above error seems like the issue is that the ArduinoSort is getting redefined between the loadcell singleton and the bench_test singleton. My bench_test.h singleton does include my loadcell singleton (#include "loadcells.h"), but I am unsure why the ArduinoSort.h is causing an issue.

Hoping someone can help clarify, thanks.

It looks like you include ArduinoSort.h from more than one file.

Since you have an implementation in the .h file, if you include the .h file more than once you'll get multiple declarations. The easiest solution is usually to put the implementation in a .cpp file.

1 Like