Preprocessor tricks to detect library include in .ino

I have the following library (I just add the files to my sketch folder rather than stick them in a separate library)

I have constructors like the following:

CTime(RealTimeClockDS1307& rtc);

However there might be some sketches where I don't won't to use #include <RealTimeClockDS1307.h>

Are there any pre-processor tricks to detect whether RealTimeClockDS1307.h has been included in the .ino?

So that these constrcutors are only compiled if that library has been included in the sketch.

Of course I could just comment them out if I don't wish to use RealTimeClockDS1307.h.

But it would be rather convenient if there was a way not to have to do this manually.

DateTime.cpp (16.7 KB)

DateTime.h (6.56 KB)

Most well designed libraries will define an include guard macro in the header file. Something like this:

#ifndef RealTimeClockDS1307_h
#define RealTimeClockDS1307_h

If so, you can use that macro in your sketch to detect whether the the file has been included.

pert:
Most well designed libraries will define an include guard macro in the header file. Something like this:

#ifndef RealTimeClockDS1307_h

#define RealTimeClockDS1307_h



If so, you can use that macro in your sketch to detect whether the the file has been included.

That did occur to me but is RealTimeClockDS1307_h 'visible' in DateTime.cpp/h from the .ino?

Or only if I include RealTimeClockDS1307.h in DateTime.cpp/h?

It must be the latter because if I don't include RealTimeClockDS1307.h then I get compile errors.

I was thinking there might be other more sophisticated preprocessor constructs that I have not yet encountered.

To date I have only ever used the very common preporcessor constructs.

But I know there is a lot more available.

Does Arduino support #pragma?

Just read that, if the compiler does not support it, then you don't get any compiler error.

Well this was totally unexpected....

Just did a bit of an experiment.

If I put this in datetime.cpp:

#ifdef RealTimeClockDS1307_h
XXXXXX
#endif

And removed #include RealTimeClockDS1307.h

I get a compile error for XXXXXXX, so #define RealTimeClockDS1307_h from the .ini carries over into datetime.cpp.

But I still get a compile error at the point I try to use class RealTimeClockDS1307

boylesg:
so #define RealTimeClockDS1307_h from the .ini carries over into datetime.cpp.

Any file that does '#include RealTimeClockDS1307.h' will have the 'RealTimeClockDS1307_h' macro defined. That's the whole point of it.

Put your .cpp file back the way it was and put this in your .ino file:

#ifdef RealTimeClockDS1307_h
CTime(RealTimeClockDS1307& rtc);
#endif

If

#include RealTimeClockDS1307.h

preceeds that, then the code within will be compiled. I'm thinking you need to define the rtc variable also, so maybe it should be:

#ifdef RealTimeClockDS1307_h
RealTimeClockDS1307 rtc;
CTime(RealTimeClockDS1307& rtc);
#endif

boylesg:
Does Arduino support #pragma?

Yes, but it's recommended to use a standard include guard instead of #pragma once. The only thing I've used #pragma for is #pragma message to display a message for the user in the compilation output, rather than using #warning for that purpose.

I don't understand your question. Are there cases when you don't want to #include <RealTimeClockDS1307.h>? If so, can't you leave it to the programmer to include that header in the .ino file?

comments:

char strDayMonthName[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

const char* getMonthName(const uint8_t nMonthNum, const bool bShort)
{
  memset(strDayMonthName, 0, 10);

  if (nMonthNum == 1)
    strcpy(strDayMonthName, "January");
  else if (nMonthNum == 2)
    strcpy(strDayMonthName, "February");
  else if (nMonthNum == 3)
    strcpy(strDayMonthName, "March");
  else if (nMonthNum == 4)
    strcpy(strDayMonthName, "April");
  else if (nMonthNum == 5)
    strcpy(strDayMonthName, "May");
  else if (nMonthNum == 6)
    strcpy(strDayMonthName, "June");
  else if (nMonthNum == 7)
    strcpy(strDayMonthName, "July");
  else if (nMonthNum == 7)
    strcpy(strDayMonthName, "August");
  else if (nMonthNum == 7)
    strcpy(strDayMonthName, "September");
  else if (nMonthNum == 7)
    strcpy(strDayMonthName, "October");
  else if (nMonthNum == 7)
    strcpy(strDayMonthName, "November");
  else if (nMonthNum == 7)
    strcpy(strDayMonthName, "December");
  else
    strcpy(strDayMonthName, "Invalid day number");

  if ((strlen(strDayMonthName) > 3) && bShort)
    strDayMonthName[3] = 0;

  return strDayMonthName;
}

how does "Invalid day number" fit into a 10 element char array?

you should use strcpy's safer cousin: strncpy

actually, why build the string to return? you are wasting memory using that strDayMonthName buffer

why are you not using arrays? Just return a pointer to the string constant held in an arry...

Take a look at this link , my post #3

https://forum.arduino.cc/index.php?topic=530472.0

I did try my best, but basically each .h/.cpp pair gets compiled to object files first so each pair needs to have its own and correct #includes.

Standard #ifndef #includes guard or #pragma is still required if the #includes headers /cpp have multiple entries so the .h /.cpp pair uses them only once.