#ifdef is a compile-time construct. Do you need this to work at compile time, or run time? Big difference. Either way, it is entirely possible, depending on exactly what you're trying to accomplish.
RayLivingston: #ifdef is a compile-time construct. Do you need this to work at compile time, or run time? Big difference. Either way, it is entirely possible, depending on exactly what you're trying to accomplish.
Regards,
Ray L.
Hmm.
I'm trying to accomplish making an if statement that is based on the data type of declared a variable.
The #IFDEF was just pseudo code, used to exaggerate the fact that I would prefer compile-time over run time as the data type won't change, can't change after download.
#define THING1 // Uncomment to use a Type 1 Thing
// #define THING2 // Uncomment to use a Type 2 Thing
#if defined(THING1)
#include "Type1Thing.h"
THING1 myThing = Type1Thing();
#elif defined(THING2)
#include "Type2Thing.h"
THING2 myThing = Type2Thing();
#endif
Good example on #IFDEF, but I don't see any check on the data type. Per the OP, I don't have THING1 and THING2. I have rtc and is either of type RTC_PCF8523 or type RTC_DS1307. rtc is always defined.
adwsystems:
Good example on #IFDEF, but I don't see any check on the data type. Per the OP, I don't have THING1 and THING2. I have rtc and is either of type RTC_PCF8523 or type RTC_DS1307. rtc is always defined.
From the class I know (are you using adafruit RTClib?) besides the "now()" method and a few other, the classes do not expose the exact same interface. so unless you use ONLY those API they have in common, the code would not be independent of the RTC.
Are you writing a new library or extending Adafruit's ? you could always add a new method that would return the RTC type a code number. that method would exist in all the classes (virtual in a base class, implemented in all subclasses for example, or just have that method in each class) and thus in your code you could do
switch(rtc.type()) {
case PCF8523_TYPE:
...
break;
case DS1307_TYPE:
...
break;
case DS3231_TYPE:
...
break;
}
where the XXXX_TYPE values would be defined in your library.
J-M-L:
From the class I know (are you using adafruit RTClib?) besides the "now()" method and a few other, the classes do not expose the exact same interface. so unless you use ONLY those API they have in common, the code would not be independent of the RTC.
Are you writing a new library or extending Adafruit's ? you could always add a new method that would return the RTC type a code number. that method would exist in all the classes (virtual in a base class, implemented in all subclasses for example, or just have that method in each class) and thus in your code you could do
switch(rtc.type()) {
case PCF8523_TYPE:
...
break;
case DS1307_TYPE:
...
break;
case DS3231_TYPE:
...
break;
}
where the XXXX_TYPE values would be defined in your library.
Good guess. I'm using Adafruit's library. Not interesting in modifying it and having to keep modifying it as they update it. You are correct they don't expose the same interface and therein lies the point of the question. Depending on the chip they have different functions to do the same thing. That is the point of the post. To be able to write one set of code and switch between the chips by merely changing the initial definition.
adwsystems:
Good example on #IFDEF, but I don't see any check on the data type. Per the OP, I don't have THING1 and THING2. I have rtc and is either of type RTC_PCF8523 or type RTC_DS1307. rtc is always defined.
I would think a type check is unnecessary, since the type is both known and enforced by the #ifdef. You SAID "I would prefer compile-time over run time as the data type won't change, can't change after download". So, make up your mind. If it can only be compiled with one type, why on earth do you need to check the type at run-time? If they are different types, they CANNOT be used inter-changeably - there HAS to be unique code to access each type, which means you HAVE to use #ifdef to include only the necessary code.
What you've given us so far makes no sense, and I'm not a big fan of 20 questions...
adwsystems:
Depending on the chip they have different functions to do the same thing.
Can you give an example ?
it looks likee where the function is the same, it seems they have the same method name. (begin, adjust, now). Other stuff is hardware related and thus not common?
J-M-L:
it looks likes where the function is the same, it seems they have the same method name. (begin, adjust, now). Other stuff is hardware related and thus not common?
RayLivingston:
I would think a type check is unnecessary, since the type is both known and enforced by the #ifdef. You SAID "I would prefer compile-time over run time as the data type won't change, can't change after download". So, make up your mind. If it can only be compiled with one type, why on earth do you need to check the type at run-time? If they are different types, they CANNOT be used inter-changeably - there HAS to be unique code to access each type, which means you HAVE to use #ifdef to include only the necessary code.
What you've given us so far makes no sense, and I'm not a big fan of 20 questions...
Regards,
Ray L.
You are using the pseudo code too literally. I don't have a #define statement. I have a declaration. Based on that declaration, and the data type of that declaration I am looking for a compile time method to select which functions are included in the downloaded program.
adwsystems:
You are using the pseudo code too literally. I don't have a #define statement. I have a declaration. Based on that declaration, and the data type of that declaration I am looking for a compile time method to select which functions are included in the downloaded program.
I don't get it either... if you don't write a library, your code does have the type of the rtc hardcoded... so you know what it is... and if you are writing a library that expect an Adafruit RTC object, then provide a method with different signature based on the possible types
J-M-L:
I don't get it either... if you don't write a library, your code does have the type of the rtc hardcoded... so you know what it is...
Exactly. I need the program to compile based on what the variable is declared as to include the correct functions and omit including the unused ones for the other chip. I don't want to have multiple versions of the program just because some have PCF8523 board and other the DS1307 board when that is the only difference between them. So back to the original question.
rtc will be declared as type RTC_PCF8523 or RTC_DS1307
then in the program
#IF rtc declared as type RTC_PCF8523 then do this #IF rtc declared as type RTC_DS1307 then do that
(this is pseudo code to show what I am trying to accomplish, this is not the exact or correct way to do it)
To put it another way, how do I only include function calls in a program based on the data type of a variable?
adwsystems:
I don't want to have multiple versions of the program just because some have PCF8523 board and other the DS1307 board when that is the only difference between them.
as you write the code, you can include your own abstractions/construct.. so either you go with the template stuff above or you define something you can use.... I would go like this
#include <RTClib.h>
/* uncomment the line with your RTC type */
#define USING_RTC_PCF8523
//#define USING_RTC_DS1307
//#define USING_RTC_DS3231
#if defined(USING_RTC_PCF8523)
RTC_PCF8523 rtc;
#elif defined(USING_RTC_DS3231)
RTC_DS3231 rtc;
#elif defined(USING_RTC_DS1307)
RTC_DS1307 rtc;
#endif
void setup() {
Serial.begin(115200);
#if defined(USING_RTC_PCF8523)
Serial.println("USING_RTC_PCF8523");
#elif defined(USING_RTC_DS3231)
Serial.println("USING_RTC_DS3231");
#elif defined(USING_RTC_DS1307)
Serial.println("USING_RTC_DS1307");
#endif
}
void loop() {}
Your thinking is backwards. Instead of trying to detect the variable's type, define a flag whose value SETS you its data type and is available for testing later. The code below uses different integer types rather than those RTC libraries that I don't have installed. But, the concept is the same.
#define SHORT 1
#define LONG 2
#define VARIABLE_TYPE SHORT
//#define VARIABLE_TYPE LONG
#if VARIABLE_TYPE == SHORT
uint8_t var;
#elif VARIABLE_TYPE == LONG
uint32_t var;
#else
#error illegal type
#endif
void setup() {
#if VARIABLE_TYPE == SHORT
// Do stuff
// Do more stuff
#elif VARIABLE_TYPE == LONG
// Do different stuff
// Do more different stuff
#endif
}
void loop() {}
gfvalvo:
Your thinking is backwards. Instead of trying to detect the variable's type, define a flag whose value SETS you its data type and is available for testing later. The code below uses different integer types rather than those RTC libraries that I don't have installed. But, the concept is the same.
I wouldn't say backwards. I was aiming for a more direct solution. To use the data type that was already there opposed to adding another item. But to add that item in such a way that is also selects the variable declaration definitely balances the pros with the cons. A 2-for-1 but have to add 1 to get the 2. Interesting.
Bottom line is there is no low hanging fruit there (endless debates around typeof, decltype etc)
You want to get rid of unneeded code at run time, and whilst you could cont on the optimizer to do this, the traditional way of doing this is conditional compiling through #if or #ifdef etc
That’s the approach I would take.
Side note - I would never buy a ds1307 it’s obsolete and not a stable clock nor is it financially more interesting than a ds3132 so why bother coding for this one