C ++: Как вызвать ошибку компилятора, когда возвращаемое значение функции не используется? - PullRequest
22 голосов
/ 27 апреля 2011

Допустим, у меня есть нормализованная функция, определенная как:

Vec3f Vec3f::getNormalized() const {
   return (*this)/this->length();
}

Возможно ли как-то создать ошибку времени компиляции, если эта функция используется без чего-либо, хранящего возвращаемое значение?;

v.getNormalized(); // which most definitely is a typo

.. вместо ..

v = v.getNormalized(); 

Ответы [ 4 ]

19 голосов
/ 27 апреля 2011

В GCC используйте -Wunused-result, чтобы вызвать предупреждение, когда возвращаемое значение функции игнорируется. И если вы хотите получить ошибку вместо предупреждения, используйте -Werror, чтобы преобразовать все предупреждения в ошибки. Для получения дополнительной информации см. Параметры предупреждения GCC .

Похоже, что нет аналогичного предупреждения для компилятора Visual C ++. (Если я ошибаюсь, отредактируйте этот ответ, указав информацию о Visual C ++.)

6 голосов
/ 27 апреля 2011

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

3 голосов
/ 27 апреля 2011

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

Однако, если это нормально, генерировать ошибку во время выполненияВы, возможно, могли бы использовать некоторые приемы, такие как прокси-класс:

template <typename T>
struct Return
{
    Return(const T & value) 
      : value_(value), used_(false) 
    {}

    Return(const Return & other) 
      : value_(other.value_), used_(false) 
    { 
        other.used_ = true; 
    }


    Return & operator=(const Return & other)
    {
        other.used_ = true;
        value_ = other.value;
        return *this;
    }

    operator T() const 
    { 
        used_ = true; 
        return value_;
    }

    ~Return() // generates an error if the value hasn't been used
    { 
        assert(used_); 
    }

  private:

    T value_;
    mutable bool used_;
};

Return<int> foo()
{
    return 42;
}

int main()
{
    int i = foo();                   // ok
    std::cout << foo() << std::endl; // ok

    foo();                           // assertion failed
}

Вам просто нужно изменить тип возвращаемого значения вашей функции, чтобы она возвращала Return<Vec3f>, и вы должны получить ошибку, еслирезультат функции не используется.Однако я не уверен, что рекомендую это, поскольку это делает код менее понятным и, вероятно, также может быть использовано неправильно.Пока ваша функция хорошо документирована, вы должны быть уверены в своих пользователях:)!

2 голосов
/ 27 апреля 2011

С помощью clang вы можете выборочно преобразовать данное предупреждение в ошибку (а не во все).

Это достигается с помощью -Werror=foo, где foo - это имя предупреждения. Здесь я думаю, что -Werror=unused-expr - это то, что вам нужно.

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