переполнение при неявном преобразовании констант [-Werror = overflow] в инициализаторе члена класса только для одного конструктора - PullRequest
0 голосов
/ 25 февраля 2020

Было несколько похожих вопросов, но этот мог (?) Быть из-за ошибки в компиляторе g cc. Единственным константой является параметр vvalue. Я изменил на char * и получил то же предупреждение компилятора.

Это сторонний код с классом (не показывает пространство имен и т. Д. c. Отображается только соответствующая часть

class Value {
public:
    ....
    Value(double value);
    Value(const char *vvalue);
    ....
private:
        struct CommentInfo {
          CommentInfo();
           ~CommentInfo();
          void setComment( const char *text );
           char *comment_;
      };

        union ValueHolder {
          Int int_;
           UInt uint_;
           double real_;
           bool bool_;
           char *string_;
 #ifdef JSON_VALUE_USE_INTERNAL_MAP
           ValueInternalArray *array_;
          ValueInternalMap *map_;
 #else
         ObjectValues *map_;
 #endif
        } value_;
        ValueType type_ : 8;
        int allocated_ : 1;     // Notes: if declared as bool, bitfield is useless.
 #ifdef JSON_VALUE_USE_INTERNAL_MAP
       unsigned int itemIsUsed_ : 1;      // used by the ValueInternalMap container.
        int memberNameIsStatic_ : 1;       // used by the ValueInternalMap container.
 #endif
        CommentInfo *comments_;
     };

};

/// class definition
 316 Value::Value( double value )
 317    : type_( realValue )
 318    , comments_(nullptr)
 319 # ifdef JSON_VALUE_USE_INTERNAL_MAP
 320    , itemIsUsed_( 0 )
 321 #endif
 322 {
 323    value_.real_ = value;
 324 }
 325 
 326 Value::Value(const char *vvalue)
 327    : type_(stringValue), allocated_(true),
 328       comments_(nullptr)
 329 #ifdef JSON_VALUE_USE_INTERNAL_MAP
 330       , itemIsUsed_( 0 )
 331 #endif 
 332 {     
 333    value_.string_ = duplicateStringValue(vvalue);
 334 }     

Когда мы запускаем с -Werror -Wall, мы получаем следующее сообщение об ошибке только с конструктором, принимающим входные данные, но не с другими конструкторами для элемента comments_:

json_value.cpp:328:24: error: overflow in implicit constant conversion [-Werror=overflow]
       comments_(nullptr)
                        ^

Достаточно странно, что предупреждение не появляется на конструкторе с версией (двойное значение). Я долго смотрел на код время и не вижу, где я могу изменить, чтобы устранить это предупреждение.

Это может иметь какое-то отношение к битовому полю:

 309 Value::Value( double value )
 310    : type_( realValue ),
 311    //allocated_(true), // adding this caused overflow issue
 312    //allocated_(1), // adding this caused overflow issue
 313    //allocated_(0), // this eliminates overflow issue
 314    allocated_(false), // this eliminates overflow issue
 315    comments_(nullptr)

Что я обнаружил, предупреждение имеет что-то сделайте с битовым полем в предыдущем члене класса: alocated_, который является 1-битным для логического значения. Не уверен, что код плохая практика или что.

1 Ответ

1 голос
/ 25 февраля 2020

Битовое поле allocated_ может содержать два значения. В вашей реализации они 0 и -1. См. Этот вопрос, почему. Вы инициализируете его с true, который преобразуется в 1, который переполняется. Включение -Wconversion хорошо объясняет это:

предупреждение: преобразование из 'int' в 'знаковый символ: 1' меняет значение с '1' на '-1' [-Wconversion]

Обновление: предупреждение о переполнении также содержит эту информацию. Оба имеют эту деталь с g cc 8.1 и далее. Эта сторонняя библиотека имеет вид jsoncpp, и эта ошибка, по-видимому, была исправлена ​​с помощью коммита 2bc6137a 24 января 2015 г. ( ref ) и включена в версию 1.4.0, выпущенную 11 февраля 2015 г. ( ссылка ).

...