2

Is there a variable data type available for Arduino? I have a class that should have a member that will differ in data type, in the past I have used the "variable" keyword in c++ but when I tried to use it the compiler yelled at me. I searched online and found a couple of articles that mentioned that if you are using an alternate GUI (I am using eclipse mars) that you can enable the feature but I can not find the correct settings as the examples I had found were for Juno and below.

Here is an example of what I am trying to accomplish

class DisplayItem{

   public:
   variant *displayVar;

   void Display(){
      Serial.println(displayVar);
   }
}

int intDisplay;
String strDisplay;

DisplayItem item();
item.displayVar = &intDisplay;
item.Display();
item.displayVar = &strDisplay;
item.Display();

I realize I could create a overloaded function to display different data types but it would be allot easier if I could simply assign a reference to a variant datatype and reuse the variable.


Edit

So after looking through the answers I think I have this figured out. I needed to keep track of which variable was being set, I put together a quick example in hopes it will help someone else out with the same question.

class DisplayItem{

   private:
   int iVarType;

   union{
      int *i;
      float *f;
   } displayVar;

   public:
   void SetVar(int *var){
      displayVar.i = var;
      iVarType = 0;
   }

   void SetVar(float *var){
      displayVar.f = var;
      iVarType = 1;
   }

   void Display(){
      if (iVarType == 0){
         Serial.println(displayVar.i);
      }else if (iVarType == 1){
         Serial.println(displayVar.f);
      }
   }
}

int intDisplay = 1;
float floatDisplay = 0.123;

DisplayItem item();
item.SetVar(&intDisplay);
item.Display();
item.SetVar(&floatDisplay);
item.Display();

Will Display:

1
0.123

2 Answers 2

2

For the situation illustrated in the question – displaying data – polymorphic functions already exist, and might as well be used in this case. Specifically, use the Streaming.h contributed library. It adds some “syntactic sugar” to Arduino C. At compile time it converts C++-like << Serial stream operators to Serial.print statements, without increasing code size. You can install it via Streaming5.zip from arduiniana.org .

In other cases, a union data structure allows treating an area of memory different ways. Wikipedia's Union type article explains the general idea. See eg tutorialspoint.com/cprogramming for union syntax and usage. For some reason, arduino.cc's Language Reference page hasn't got union on its list of language features. However, mcgurrin.com has a page called There is Power in a Union that codes a simple Arduino C example two ways (where bearing is an int):

higherByte = compass.read();
lowerByte = compass.read();
bearing = ((higherByte<<8)+lowerByte)/10

-vs-

union Data {
  byte b[2];
  int value;
};
...
union Data data;
data.b[0] = compass.read();
data.b[1] = compass.read();
bearing = data.value/10;
2
  • Would you then use sizeof(data.b[0]) to determine if the variable has been used or is there a better way? Commented Dec 3, 2015 at 16:52
  • sizeof data.b[0] (the parentheses aren't needed if the argument is a variable rather than a type) is a constant, so has no bearing on whether a section of memory has been set to a value. Use a separate flag variable or some program flow analysis to keep track of whether a cell is occupied. Note, union is most useful in certain type conversions (eg changing endianness among integer types or getting the exponent field of a float) or when marshalling data for export, eg filling a buffer with a variety of data items before using a write to send the buffer on its way. Commented Dec 3, 2015 at 20:46
1

No, there is no such thing. The whole concept of "type" only exists during compilation, not at run-time.

However, you can "emulate" it using "setters" and keeping your own internal state information:

class Thing {
    private:
        String *strvar;
        int intvar;
        int type;

    public:
        void set(int val) {
            intvar = val;
            type = 1;
        }
        void set(String &str) {
            strval = &str;
            type = 2;
        }
        void Display() {
            if (type == 1) {
                Serial.print("Value: ");
                Serial.println(intval);
            } else if (type == 2) {
                Serial.print("String: ");
                Serial.println(strval);
            } else {
                Serial.println("Something went wrong");
            }
        }
};

Thing t;
String s = "This is a string";
int i = 23;
t.set(s);
t.Display();
t.set(i);
t.Display();

The multiple functions named the same but with different parameters are overloaded. The best match is picked at compile time.

4
  • I have in my question about using overloaded functions, I was hoping that there was a variable datatype as I have seen it in other c++ platforms. But if this is the only way to accomplish this I guess I don't have much choice. Commented Dec 2, 2015 at 16:44
  • It's down to the IDE preprocessing your code with its own keywords. The closest is a void * pointer which can point to the memory of any data type, however it doesn't have any concept of what that datatype is - it's just memory.
    – Majenko
    Commented Dec 2, 2015 at 16:45
  • 1
    Actually modern C++ provides run-time type information for classes. See Wiki for some examples. Unfortunately this is often disabled when compiling for small scale embedded systems to reduce memory foot-print. Last, in @Majenko 's example the value could be stored in a union. See Cosa/Types.h univ16_t and univ32_t for examples of universal type. Commented Dec 2, 2015 at 20:27
  • You mean dynamic_cast? Only useful when you're working with polymorphism.
    – Majenko
    Commented Dec 2, 2015 at 23:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.