0

I'm trying to get a rather large sketch working with a teensy LC. I'd like to break it into headers and C files, but the multi-file sketch fails to compile. When I put everything into a single, monolithic sketch, it runs fine. I've #included the h files where they are needed, using single quotes, and have confirmed that my h files are in the same folder as my sketch. Is there an additional step to go through specific to teensy? I've managed to do this tons of times using a standard arduino.

Here is a basic sketch:

This is the main sketch file:

   #include "tst.h"
void setup() {
  // put your setup code here, to run once:

}

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

This is tst.h

void doNothing();

This is tst.c

#include "tst.h"
void doNothing()
{
  int i = 0;
}

I get the error "undefined reference to doNothing() in function loop"

  • Could you provide source code and compilation errors ? I have created a small test with Arduino 1.6.13 + Teensyduino 1.33 with a mylib.cpp/mylib.h in the same folder as .INO file and after selecting "Teensy LC" device no problem detected to compile and link. – J. Piquard Dec 24 '16 at 10:38
  • My source code is quite long. I am using C, not c++. Would that matter? If I have time soon I'll make a trial sketch with just a few small functions to test and upload. – Michael Stachowsky Dec 24 '16 at 13:27
  • No problem, take your time to create a minimal source code. When you say "I am using C, not c++", did you use a ".c" file instead of ".cpp" ? – J. Piquard Dec 24 '16 at 13:54
  • Yes, that's right. I have three files, the main sketch, one .h file, and one .c file – Michael Stachowsky Dec 24 '16 at 14:07
  • I've edited the post to include a minimal sketch. I wonder, is the a build order setting I'm missing? – Michael Stachowsky Dec 24 '16 at 15:37
  • So, the first and easiest solution is to rename your "test.c" file to "test.cpp". This is the default extension expected by the C++ compiler used by Arduino IDE. – J. Piquard Dec 24 '16 at 15:51
  • Are all the *.c files opened (show up in the tabs near the top of the window) in the Arduino SDK when you compile? – st2000 Dec 24 '16 at 15:54
  • 1
    Even if the "test.c" and the "test.h" appear on the top, the "test.c" seems to be compiled "mylib.c.o" and the doNothing is present inside. But the error is always UsingCpp.ino:14: undefined reference to 'doNothing()'. – J. Piquard Dec 24 '16 at 16:35
  • Yes, they are all part of the sketch and are tabs at the top. @J.Piquard: do you see the same errors? – Michael Stachowsky Dec 24 '16 at 16:47
  • 1
    I duplicated your error (guessing you called the 1st file "tst.ino") using Arduino 1.8.0. @J.Piquard suggestion appears correct, you need to use the *.cpp extension. – st2000 Dec 24 '16 at 17:06
  • Yes, that fixed it handily. I wonder why, though? I was under the impression that Arduino used C, with a bunch of cpp functionality added in through emulation of some sort. I guess I'm wrong, obviously :-P – Michael Stachowsky Dec 24 '16 at 17:28

1 Answers1

1

I get the error "undefined reference to doNothing() in function loop"

The C++ compiler cannot find doNothing(). This is mainly due to the incomplete header file and mix of C and C++.

Two things are needed to avoid this type of problem; 1) protect the file from multiple includes (in the same compile), 2) make the function visible to the C++ compiler as a C function (without name mangling).

tst.h:

#ifndef TST_H
#define TST_H

#ifdef __cplusplus
extern "C"{
#endif

void doNothing();

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

Cheers!

Mikael Patel
  • 7,969
  • 2
  • 14
  • 21
  • I admit I'm still learning c++, but why is my function not c++? – Michael Stachowsky Dec 26 '16 at 14:14
  • The build rules for files with the extension .c will use the c-compiler (gcc). If you rename the file and use the extension .cpp the build rules will use the c++-compiler. – Mikael Patel Dec 26 '16 at 14:35
  • Oh, yes I see. So the function itself was not strictly c, but the fact that it was in A C file was the problem? – Michael Stachowsky Dec 26 '16 at 14:49
  • Correct! If you had used overloading, reference parameters, classes, etc (i.e. a language difference) then the C-compiler would have flagged an error. Now actually the linker flags the error as the C function does not have the same compiled name (aka manged name) as the C++ function. – Mikael Patel Dec 26 '16 at 14:54