New compiler won't work with typeid()

05 Aug 2013

Hi, Some previously working code has stopped compiling since Friday's updates. The code uses typeid(). I specify #include <typeinfo>. Please fix.

Thanks Tim

05 Aug 2013

I am also troubled by this problem.

05 Aug 2013

Hi Tim, Ryo, we deprecated RTTI on mbed.

It is an accepted embedded C++ programming practice to avoid both RTTI and exceptions.

RTTI adds type information overhead to every object independently if you are using it, or not.

You can recreate the RTTI behaviour, just where you need it, adding a custom "type_info" field with your desired information about the type.

Avoiding RTTI is considered good practice also for big server applications like the ones developed in Google: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Run-Time_Type_Information__RTTI_#Run-Time_Type_Information__RTTI_

You can post here the snippet of code where you were using typeid and we can help you replacing it with some custom code.

Cheers, Emilio

05 Aug 2013

Emilio-san,

Thank you for reply. I used typeid to detect the file system type from a DirHandle object.

include the mbed library with this snippet

    DIR* d=opendir(buf);
    if(d==NULL){
        i_connection.sendError(403);
        if(!i_connection.isMethodType(Http::MT_GET)){
            return;
        }
        i_connection.sendBodyF("<!DOCTYPE html><html><body><h1>403 Forbidden</h1><hr/>'%s'</body></html>",buf);
        return;
    }        
    if(!i_connection.sendHeader(200,"text/html",NULL)){
        //nothing to do
    }else{
        if(!i_connection.isMethodType(Http::MT_GET)){
            //nothing to do.
        }else{
            bool is_fatfs=(typeid(*d) == typeid(FATDirHandle));
            struct dirent *p;
            p = readdir(d);
            i_connection.sendBodyF(
                "<!DOCTYPE html><html><body><h1>Index of %s</h1><hr/>\n"
                "<ul>\n"
                ,buf);
            for(;;)
            {
                if(is_fatfs){
                    if((((struct direntFAT*)(p))->fattrib & AM_DIR)!=0){
                        //dir
                        i_connection.sendBodyF("<li><a href=\"./%s/\">[DIR]%s</a></li>\n",p->d_name,p->d_name);
                    }else{
                        //file
                        i_connection.sendBodyF("<li><a href=\"./%s\">%s</a></li>\n",p->d_name,p->d_name);
                    }
                }else{
                    i_connection.sendBodyF("<li><a href=\"./%s\">%s</a></li>\n",
                    p->d_name,p->d_name);
                }
                p = readdir(d);
                if(p==NULL){
                    break;
                }
            }
            i_connection.sendBodyF("</ul></body></html>",buf);
        }
    }

At line16, The code detects base filesystem type by DirHandle object.

This code snippet is part of libMiMic in MbedFileServer. (this program gets error at this line.)

https://mbed.org/users/nyatla/code/MbedFileServer/

Is there any technique gets the kind of file system from a DirHandle class?

Regards

Ryo

06 Aug 2013

This was actually a bug - the new compiler should not have had different behaviour if you did not update the SDK. We have a policy of never breaking user code, meaning nobody should ever be forced to change previously working code on mbed.

This should now be fixed - Unless you update the mbed SDK beyond revision 63, the previous behaviour will remain in force. Please let me know if you still have problems.

Thanks,

Dan

06 Aug 2013

Hi Emilio,

Thanks for the explanation. I use typeid in a templated keypad component for use with a touchscreen. I need to check whether the data type for the return from the keypad is a float or double so I can enable or disable the decimal point button.

template <typename T>
class Keypad
{
      public:
            Draw(void);
      ......
}

template <typename T>
Keypad<T>::Draw(void)
{
      ......
      if ((typeid(T)==typeid(float))||(typeid(T)==typeid(double)))
            // Enable decimal point button
      else
            // Disable decimal point button
      ......
}

Thanks for your help.

Tim

06 Aug 2013

Hi Dan,

I'm still having this problem. I'm using mbed.bld version 42 on one project, and mbed-src and mbed-NXP versions 7 on another and both have this problem.

Thanks Tim

06 Aug 2013

Emilio Monti wrote:

RTTI adds type information overhead to every object independently if you are using it, or not.

Strictly speaking, only to polymorphic classes (those with virtual functions), not all of them :) Still, I welcome this decision, it should result in noticeable code size reduction, especially for smaller chips like the LPC11U24.

06 Aug 2013

Tim Barry wrote:

I use typeid in a templated keypad component for use with a touchscreen. I need to check whether the data type for the return from the keypad is a float or double so I can enable or disable the decimal point button.

You can use the type traits approach. It does not require RTTI and results in smaller code because the condition is resolved at compile time, not runtime:

template< typename T > 
struct is_float { 
  static const bool value = false; // most types are not floats
};

// specializations for float and double
template<> 
struct is_float< float >{ 
  static const bool value = true;
};

template<> 
struct is_float< double >{ 
  static const bool value = true;
};

template <typename T>
Keypad<T>::Draw(void)
{
      ......
      if ( is_float<T>::value )
            // Enable decimal point button
      else
            // Disable decimal point button
      ......
}
06 Aug 2013

Ryo Iizuka wrote:

At line16, The code detects base filesystem type by DirHandle object.

It's a little awkward, but I think you can differentiate files from directories by using FilePath::isFile().

06 Aug 2013

Dan-san,

Thank you for reply. I tried to compile again with mbed-sdk 61:5e5da4a5990b. But it has same error.

Igor - san,

Thank you for advice. I'll check the source code implementation.

There may be a problem that require large memory for a long file path on FAT filesystem.

I hope that to get file system information from FileHandle-extended classes, the dirnet structure have a type information.

06 Aug 2013

Hi Igor,

Thanks for the suggestion. It works perfectly. I agree it is good to get rid of the overheads. I just checked the difference in size between my previously compiled version of this project and the newly compiled one and it is 16kB (from 463kB down to 447kB)!!

Thanks Tim