lundi 28 septembre 2015

When int isn't an int (intX_t)

I have some headache inducing problems here.

Basically I'm trying to make a library compatible with different Arduino systems (not an Arduino question).

I have a situation where types no longer match, as in an int is no longer equivalent to its identical fixed width type. In the limited environment provided (no stdlib and such) I have written my own type trait classes for the features I need.

Everything works fine using GCC 4.8.1 (avr) & Extensa-1x106-GCC (ESP8266), but not in GCC 4.8.3 (SAM,SAMD cores).

Basically I have knuckled down my code to show the problem in this very basic code (int is confirmed to have 4 bytes on the failing 32-bit platform compilers):

template < typename T, typename U > struct is_same{ enum { value = false }; };
template < typename T > struct is_same< T, T >    { enum { value = true }; };

void setup() {
  static_assert( is_same<int,int32_t>::value, "Not integer");
}

void loop(){}

You can view a 'normal' C++ implementation here (above is a basic implementation for use within the Arduino IDE): http://cpp.sh/377e

By the way, the static assert does not fire in the cpp.sh compiler either.

Is 4.8.1 incorrect, meaning int and int32_t should be considered different types. Or is 4.8.3 incorrect and they should be equivalent if equally sized defined by the implementation.

I was using the code below to detect any type of integer, which was where I found my error originally.

template< typename T >
    struct is_integer{
        enum{
            V8    = is_same< T, uint8_t >::value  || is_same< T, int8_t >::value,
            V16   = is_same< T, uint16_t >::value || is_same< T, int16_t >::value,
            V32   = is_same< T, uint32_t >::value || is_same< T, int32_t >::value,
            V64   = is_same< T, uint64_t >::value || is_same< T, int64_t >::value,
            value = V8 || V16 || V32 || V64
        };
};

I of course can change it to check for char, int, long, etc.. but it will still require checking for all fixed width variations and most likely the int_fastX_t and int_leastX_t types, which seems like a super redundant method to ensure maximum usability.

Any ideas?

Cheers, I appreciate any input!

Aucun commentaire:

Enregistrer un commentaire