Существует ли опция GCC предупредить о записи 'этого-поля' вместо 'этого-> поле'?

Этот после кода (содержащий порочную ошибку) компилирует с GCC без любого предупреждения. Но, конечно, это не работает как ожидалось разработчиком (меня).

#include <iostream>

struct A
{
    bool b;
    void set(bool b_) { this->b = b_; }
    bool get() const { return this-b; } // The bug is here: '-' instead of '->'
};

int main()
{
    A a;
    a.set(true);
    std::cout << a.get() << std::endl; // Print 1
    a.set(false);
    std::cout << a.get() << std::endl; // Print 1 too...
    return 0;
}

Какое предупреждение я могу добавить, чтобы компилятор (GCC 4.8) избежал этого вида опечатки?

Связанный вопрос: Есть ли любая опция вызвать (или предупредить) доступ к членским переменным/функциям с this->?

62
задан 27 September 2017 в 04:09

4 ответа

Эта конкретная проблема обнаруживается cppcheck:

$ cppcheck --enable=all this-minus-bool.cxx 
Checking this-minus-bool.cxx...
[this-minus-bool.cxx:7]: (warning) Suspicious pointer subtraction. Did you intend to write '->'?
(information) Cppcheck cannot find all the include files (use --check-config for details)

Это было без, включают данный путь. Если я добавляю -I /usr/include/c++/4.8/, проблема все еще обнаруживается:

Checking this-minus-bool.cxx...
[this-minus-bool.cxx]: (information) Too many #ifdef configurations - cppcheck only checks 12 of 45 configurations. Use --force to check all configurations.
[this-minus-bool.cxx:7]: (warning) Suspicious pointer subtraction. Did you intend to write '->'?
[/usr/include/c++/4.8/bits/ostream.tcc:335]: (style) Struct '__ptr_guard' has a constructor with 1 argument that is not explicit.
[/usr/include/c++/4.8/bits/locale_classes.tcc:248]: (error) Deallocating a deallocated pointer: __c

и затем cppcheck медленно работает через вышеупомянутое #ifdef конфигурации.

(Как примечание стороны, ошибка в local_classes.tcc является положительной ложью, но это очень трудно сказать для автоматизированного инструмента, поскольку это должно было бы знать, что catch блок на этом сайте не должен быть введен, когда макрос __EXCEPTIONS сброшен.)

Правовая оговорка: у Меня нет никакого другого опыта с cppcheck.

71
ответ дан 31 October 2019 в 13:59

Нет, this - b работает адресная арифметика с указателями на указателе this, несмотря на b являющийся bool тип (b неявно преобразовывается в int).

(Интересно, Вы можете всегда , устанавливает this + b на указатель, где b bool тип, так как можно установить указатель на одно прошлое конец скаляра! Таким образом, даже Ваш фаворит неопределенное поведение сыщик разрешил бы что один.)

проверка границ Массива всегда была заданием программиста на C++.

Примечание также, что в Ваших случаях использование this является лишним: так сокращение этого чрезмерного использования является одним способом заставить проблему уйти.

32
ответ дан 31 October 2019 в 13:59

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

Однако в этом определенном варианте использования мы можем добиться большего успеха - путем обертывания bool в класс обертки, который имеет явные преобразования и никакие определенные арифметические операции.

Это приводит к ошибке компилятора, когда логически неправильно используется, которая обычно рассматривается как предпочтительная для предупреждения, если логическая правильность является целью.

интересно отметить, что C++ 17 удерживает от использования bool::operator++, поскольку эта арифметика рассматривается как зло.

пример:

struct Bool
{
    explicit Bool(bool b) : value_(b) {}
    explicit operator bool() const { return value_; }
private:
    bool value_;

    // define only the operators you actually want
    friend std::ostream& operator<<(std::ostream& os, const Bool& b) {
        return os << b;
    }
};

struct X
{
    bool foo() {
        // compilation failure - no arithemetic operators defined.
        // return bool(this-b);

        // explicit conversion is fine
        return bool(b);
    }

    Bool b { true }; // explicit initialisation fine
};
-1
ответ дан 31 October 2019 в 13:59

Я хотел бы предложить другой инструмент (кроме cppcheck предложенный @arne-vogel), давая лучшую визуальную помощь вместо предупреждения, относительно которого попросили:

Использование формат лязга для автоматического форматирования кода. Результат мог бы быть похожим на это (в зависимости от настроек), делая ошибку более видимой пробелами добавленный приблизительно operator-:

struct A {
  bool b;
  void set(bool b_) { this->b = b_; }
  bool get() const { return this - b; }
};
13
ответ дан 31 October 2019 в 13:59

Другие вопросы по тегам:

Похожие вопросы: