HomeBlogMagic

Lösen der gcc fallthrough warnung [-Wimplicit-fallthrough=]

Der gcc wird mit jeder Version restriktiver was die fall-throug -arning betrifft.

In der Version 7.0 hatte ich in beim kompilieren des CcOS Frameworks bei sqlite3 folgende warning erhalten:

/home/coolcow/git/CcOS/ThirdParty/sqlite3/sqlite3.c:25901:19: warning: this statement may fall through [-Wimplicit-fallthrough=]
         flag_long = sizeof(char*)==sizeof(i64) ? 2 :
         ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      sizeof(char*)==sizeof(long int) ? 1 : 0;

Die Stelle im Code:

...
switch( xtype ){
  case etPOINTER:
    flag_long = sizeof(char*)==sizeof(i64) ? 2 :
                 sizeof(char*)==sizeof(long int) ? 1 : 0;
  case etORDINAL:
  case etRADIX:      
    cThousand = 0;
...

Um die warning zu lösen muss jeder gewünschte fall through mit einem Attribut gekennzeichnet werden, welches inzwischen in den verschiedensten gcc Versionen anders geschrieben wird.

Um das Problem zu umgehen habe ich ein Fall Through Makro erstellt welches die Versionen beachtet:

//! @brief Notify if fall through in switch case is wanted!
#ifdef __clang__
  // clang does not warn here at the moment
  #define CCFALLTHROUGH
#elif __GNUC__
  #if __cplusplus
    #if __GNUG__ > 6
      #define CCFALLTHROUGH [[gnu::fallthrough]];
    #else
      #define CCFALLTHROUGH
    #endif
  #else
    // Older gcc versions requires an text to warn for fall through
    #define CCFALLTHROUGH  /* fall through */
  #endif
#else
  // No other compiler is know who warnes here
  #define CCFALLTHROUGH
#endif

Im Code sieht das dann so aus:

...
switch( xtype ){
  case etPOINTER:
    flag_long = sizeof(char*)==sizeof(i64) ? 2 :
                 sizeof(char*)==sizeof(long int) ? 1 : 0;
    CCFALLTHROUGH
  case etORDINAL:
    CCFALLTHROUGH
  case etRADIX:      
    cThousand = 0;
    CCFALLTHROUGH
...

Das Makro ist sicherlich noch nicht perfekt, aber im Moment funktioniert es auch im c++ teil ganz gut.