С++: как вызвать ошибку компилятора, когда значение возвращаемой функции не используется?
Скажем, у меня есть функция нормализации, определяемая как:
Vec3f Vec3f::getNormalized() const {
return (*this)/this->length();
}
Можно ли как-то создать ошибку времени компиляции, если эта функция используется без какого-либо сохранения возвращаемого значения?;
v.getNormalized(); // which most definitely is a typo
.. вместо..
v = v.getNormalized();
Ответы
Ответ 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
- это то, что вам нужно.