Header files and good practice. Harder than I thought

Dear forum.

I have a hard time grasping the ‘good practice’ rules for header files. Got a main.cpp file and I have put most of the includes and global variables in the main.h file. Also all function declaration go into the main.h file.

And -also good practice I thought- I defined a version string as in:

#define VERSION “Version 1.0 10 february 2025”.

And put that in the main.h header file as well.

Now I have another cpp file -lets call it 2nd.cpp) with some function(s) in which the #define VERSION is used (as in Serial.println(VERSION)).
However the compiler complains that VERSION is not declared. Ok I get that, every cpp file is an Island for the compiler so I have to declare VERSION as external. But it is a #define. mmh problem.
So I made another header file (2nd.h) for this 2nd.cpp file. And put in an
#include “main.h”

Problem solved? Well for the #define it is, however, now I have declared some global variables twice. I get that too, I defined an array and set its size to 1500.

char tempspace1500[1500];

I ended up in creating a third header file called ‘defines.h’, put the #define VERSION … in there and included defines.h in both main.cpp as the 2nd.cpp file. But this can not be the correct way can it?

Is there a good tutorial in howto do header files. A tutorial that is complete?

Thanks.

Header files should look like

#ifndef _MY_HEADER_FILE_NAME_H_
#define _MY_HEADER_FILE_NAME_H_

/* include all headers whose types you need */
#include <Arduino.h>

/* define macros */
#define VERSION 0x010203
#define MANIPULATE(x) ((x) + 1)

/* declare global variables */
extern int myGlobalInt;
extern String myGlobalString;
extern char myBuf[1500];

/* declare global functions */
String my_global_function(int a, int b);

#endif /* _MY_HEADER_FILE_NAME_H_ */

And the corresponding cpp file should look like

#include "myHeaderName.h"

/* define global variables once */
int myGlobalInt = 123;
String myGlobalString = "ABC";
char myBuf[1500] = {0};

/* define global functions once */
String my_global_function(int a, int b) {
  return String(a + b);
}

General C/C++ tutorials already cover this, e.g.,

Thanks @maxgerhardt

So a header file contains declarations without settings. You then set (give a value) to these declarations in the cpp file.
That seems clear, although I will probably get back to this forum for the more advanced exceptions and ambiguities.

Now in your example you set

extern char myBuf[1500];

and then (again putting 1500 in the size) in the cpp file:

char myBuf[1500] = {0};

Would it be possible to set the array size=1500 in only one of these files? In this example I must keep track of both. Whenever I want/need to change the one I would have to change the other as well?

Thanks again.

That’s where a #define becomes handy:

.h

#define MAX_BUFSIZE 1500
extern char buf[MAX_BUFSIZE];

.cpp

char buf[MAX_BUFSIZE];
1 Like

With the following I have no idea what to do. I copied a class that essentially streams a print, println and/or printf statement to two different streams, in my case a Telnetstream and the Serial stream:

// Following class to stream a print(f) statement to two streams
// from Juraj (see telnetstream @ github)
class TeePrint: public Print {
    Print &out1;
    Print &out2;
    public:
      TeePrint(Print &_out1, Print &_out2) : out1(_out1), out2(_out2) {}
    virtual size_t write(uint8_t b) {
      out1.write(b);
      out2.write(b);
      return 1;
    }
  };

And in my main.cpp:

TeePrint tee(Serial, TelnetStream); // stream print(f) statements to both Serial as Telnet.

I can now use tee.println(“Hello World”); and that will be streamed to both Telnet as Serial.

I have several .cpp files in one project and some of them also will use this tee.print() class. But I get errors in compilation. I read you’d have to put the class in a .h file, e.g. functions.h.

I tried several solutions, but none work. Since I am not skilled (at all) in cpp I am aiming in the dark. Pls explain where I would put this class, how to define it in other cpp files and where do I put the actual declaration:

TeePrint tee(Serial, TelnetStream);

??? Again, pls be very specific as I do not know how to program CPP.

Thanks

Refactoring a class in .h and .cpp is covered in https://www.learncpp.com/cpp-tutorial/classes-and-header-files/.