Подтвердить что ты не робот

С++: как вызвать ошибку компилятора, когда значение возвращаемой функции не используется?

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

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

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

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

.. вместо..

v = v.getNormalized(); 
4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

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>, и вы должны получить ошибку, если результат функции не используется. Тем не менее, я не уверен, что рекомендую это, поскольку он делает код менее понятным и, вероятно, может быть неправильно использован. Пока ваша функция хорошо документирована, вы должны быть уверены в своих пользователях:)!

Ответ 4

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

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