"undefined reference" compiler error to a defined function

I have a lib.h file:

#ifndef LIB_H
#define LIB_H
#include <Arduino.h>

void printBits(size_t const size, void const * const ptr);

#endif

and a lib.c file:

#include "lib.h"

// Taken from https://stackoverflow.com/a/3974138/1124423
void printBits(size_t const size, void const * const ptr){
  //something
}

called from the ino file:

#include <Arduino.h>
#include "lib.h"

void setup() {
  int a = 5;
  printBits(sizeof(a), &a);
}

void loop() {
  // put your main code here, to run repeatedly:
}

And I am getting this error:
test.ino:6: undefined reference to `printBits(unsigned int, void const*)'

Why is this? I have my variable declared and defined in the lib files. Also, why is it thinking unsigned int and void const*? sizeof should return size_t. The code for the printBits is taken from here.

This should be written as

#ifndef LIB_H
#define LIB_H
#endif

#include <Arduino.h>

void printBits(size_t const size, void const * const ptr);

You will often find that compilers do not point to the line with the actual error, more likely it is from something that has been done prior to that line.

If you meant for the #include <Arduino.h> on the condition that LIB_H was defined, this needs to be in a separate #ifdef

#ifdef LIB_H
#include <Arduino.h>
#endif
1 Like

not if you want to protect against multiple includes

3 Likes

Arduino uses C++ for sketches and most libraries. Either use lib.cpp or conditionally add extern "C" in your header file, using this common pattern:

#ifdef __cplusplus
extern "C" {
#endif

// function declarations ...

#ifdef __cplusplus
} // extern "C"
#endif

This is because size_t happens to be an alias for unsigned int for this specific platform. The linker only sees the actual type, not its aliased name. (Note: on other platforms size_t might be an alias to a different type, so don't count on it being the same as unsigned int.)

1 Like

the issue here is probably that the parameters you are using do not match the prototype

EDIT: as rightly pointed out by @PieterP

As @J-M-L pointed out, I wanted to protect against multiple includes.

wow, I thought that C/C++ are compatible with each other, I did not know that putting C in C++ code requires special attention. Thanks!

They are compatible, but they are still different languages with different rules, so you have to tell the C++ compiler which functions are C functions. This is because in C++, in order to support function overloading, function argument types are part of the function's “name” as seen by the linker. This is not the case in C.

https://en.cppreference.com/w/cpp/language/language_linkage

1 Like

Is there some reason that your code must be compiled as C and not C++???

Just my thoughts as well… call the file lib.cpp and fix the types and be done with it :wink:

Not really. Since, I am not doing object oriented programming C seemed to be easier than C++. Therefore, I went with C code. Renaming the file worked immediately.

The main language is C++ so you are better off using .cpp files to stay out of trouble

If you're compiling C code, you can't #include <Arduino.h> as that file contains all the (C++) class declarations used in Arduino code.

Yes, you can. There are #ifdef __cplusplus checks to skip non-C code.

Does that include all the .h files #include(d) by Arduino.h and all the .h files #include(d) by those file, and so on, and so on....? If so, great, good to know, thanks.

Thanks for that.

I regard myself as a reasonably good hobby programmer in C. I understand a bit of C++ but a lot of it I find difficult to understand. Mostly I write Arduino code as if it were C but keep in mind that occasionally the differences between C and C++ will cause me problems. When that happens I don't generally have difficulty solving whatever the problem is. I suggest that if you are comfortable with C then write as if using C and be aware that there are differences.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.