简体   繁体   中英

C++ Union with functions, Arduino compiler error “cannot be overloaded”

I am writing a library for an Arduino and am now stuck at converting a byte array which is in the wrong endian-ness to a float, uint32 oruint16.

I have gotten working code where i use memcpy to copy an array that is reversed for the correct endianness to the memory of a float, but now i found that union { uint8_t bytes[4]; float result; } union { uint8_t bytes[4]; float result; } union { uint8_t bytes[4]; float result; } is a quick and efficient way to do the same but using less resources.

The concept i made runs on my PC (C++14 on windows 10 using cygwin), but it won't compile in the Arduino IDE for my Arduino because 'float Converter::ToFloat(uint8_t*)' cannot be overloaded and i have no idea where the compiler gets the idea that i'm overloading anything.

union Converter {
  float ToFloat(uint8_t data[]) {
    inValue[0] = data[3];
    inValue[1] = data[2];
    inValue[2] = data[1];
    inValue[3] = data[0];
    return floatOutValue;
  };
  uint32_t ToUint32(uint8_t data[]) {
    inValue[0] = data[3];
    inValue[1] = data[2];
    inValue[2] = data[1];
    inValue[3] = data[0];
    return uint32OutValue;
  };
  uint32_t ToUint16(uint8_t data[]) {
    inValue[0] = data[1];
    inValue[1] = data[0];
    return uint16OutValue;
  };
private:
  uint8_t inValue[4];
  float floatOutValue;
  uint32_t uint32OutValue;
  uint16_t uint16OutValue;
};

void setup() {
  uint8_t t1[4] = {0x0A, 0xC3, 0x53, 0x48}; //180573000
  Converter converter;
  Serial.println(converter.ToUint32(t1));
  uint8_t t2[2] = {0x07, 0xE3}; //2019
  Serial.println(converter.ToUint16(t2));
  uint8_t t3 = 0x05; //5
  Serial.println(t3 * 1);
  uint8_t t4[9][4] = {
    {0x3F, 0x7F, 0xCC, 0x8C}, //0.99921
    {0x3D, 0x21, 0x43, 0x00}, //0.039371
    {0x3B, 0x92, 0x07, 0xDF}, //0.0044565
    {0xBD, 0x21, 0xBE, 0x6E}, //-0.039488
    {0x3F, 0x7F, 0xAE, 0x7E}, //0.99876
    {0x3C, 0xF9, 0x64, 0x38}, //0.030443
    {0xBB, 0x55, 0x26, 0x18}, //-0.0032524
    {0xBC, 0xFA, 0xA3, 0x24}, //-0.030595
    {0x3F, 0x7F, 0xE0, 0xFC}, //0.99953
  };
  for (int i = 0; i < 9; i++) {
    Serial.println(converter.ToFloat(t4[i]));
  }
}

So, why does this code not compile for an Arduino, but runs perfectly on windows 10 with the right outputs? What does the compiler error really mean?

Solution: Don't try to do what i did on arduino if it does not work.

I found that if i remove all functions inside the union except one it will compile if that function has the parameter list (uint8_t data[]) but not when i add any second parameter to the parameter list, and i have no idea why.

Much of the different issues i'm running into seem undocumented, so i'm going to abandon the union functions and take the easy but less elegant solution of placing the functions outside of the union and defining the union members as public, like this:

static union {
    float floatValue;
    uint32_t uint32Value;
    uint16_t uint16Value;
    uint8_t inValue[4];
};

float bytesToFloat(uint8_t data[]){
    inValue[ 0 ] = data[ 3 ];
    inValue[ 1 ] = data[ 2 ];
    inValue[ 2 ] = data[ 1 ];
    inValue[ 3 ] = data[ 0 ];
    return floatValue;
}
uint32_t bytesToUint32(uint8_t data[]){
    inValue[ 0 ] = data[ 3 ];
    inValue[ 1 ] = data[ 2 ];
    inValue[ 2 ] = data[ 1 ];
    inValue[ 3 ] = data[ 0 ];
    return uint32Value;
}
uint16_t bytesToUint16(uint8_t data[]){
    inValue[ 0 ] = data[ 1 ];
    inValue[ 1 ] = data[ 0 ];
    return uint16Value;
}

void setup() {
    uint8_t t1[4] = {0x0A, 0xC3, 0x53, 0x48}; //180573000
    cout << bytesToUint32(t1) << endl;
    uint8_t t2[2] = {0x07, 0xE3}; //2019
    cout << bytesToUint16(t2) << endl;
    uint8_t t3 = 0x05; //5
    cout << t3 * 1 << endl;
    cout.precision(5);
    uint8_t t4[9][4] = {
            {0x3F, 0x7F, 0xCC, 0x8C}, //0.99921
            {0x3D, 0x21, 0x43, 0x00}, //0.039371
            {0x3B, 0x92, 0x07, 0xDF}, //0.0044565
            {0xBD, 0x21, 0xBE, 0x6E}, //-0.039488
            {0x3F, 0x7F, 0xAE, 0x7E}, //0.99876
            {0x3C, 0xF9, 0x64, 0x38}, //0.030443
            {0xBB, 0x55, 0x26, 0x18}, //-0.0032524
            {0xBC, 0xFA, 0xA3, 0x24}, //-0.030595
            {0x3F, 0x7F, 0xE0, 0xFC}, //0.99953
    };
    for (int i = 0; i < 9; i++) {
        cout << bytesToFloat(t4[ i ]) << endl;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM