C++ C++;:当函数返回值未使用时,如何触发编译器错误?
假设我有一个规格化函数,定义为:C++ C++;:当函数返回值未使用时,如何触发编译器错误?,c++,compiler-errors,return-value,C++,Compiler Errors,Return Value,假设我有一个规格化函数,定义为: Vec3f Vec3f::getNormalized() const { return (*this)/this->length(); } 如果在没有存储返回值的情况下使用此函数,是否可能产生编译时错误 v.getNormalized(); // which most definitely is a typo …而不是 v = v.getNormalized(); 无法知道返回值是否被接受。保证传入的唯一方法是通过引用传入返回值。在GCC中,
Vec3f Vec3f::getNormalized() const {
return (*this)/this->length();
}
如果在没有存储返回值的情况下使用此函数,是否可能产生编译时错误
v.getNormalized(); // which most definitely is a typo
…而不是
v = v.getNormalized();
无法知道返回值是否被接受。保证传入的唯一方法是通过引用传入返回值。在GCC中,当忽略函数的返回值时,使用
-Wunused result
触发警告。如果您想要错误而不是警告,请使用-Werror
将所有警告转换为错误。有关更多信息,请参见
<> Visual C++编译器似乎没有等价的警告。(如果我错了,请用VisualC++信息编辑这个回复)
用CLAN,你可以有选择地将给定的警告转换成错误(而不是全部)。
这是通过
-Werror=foo
实现的,其中foo
是警告的名称。在这里,我认为您需要的是-Werror=unused expr
。我认为这在编译时是不可能的,除非使用编译器标志作为
但是,如果可以在运行时生成错误,则可以使用一些技巧,例如使用代理类:
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
}
模板
结构返回
{
返回值(常数T和值)
:value(值),used(假)
{}
返回(常量返回和其他)
:value_u(其他.value_u),used_u(false)
{
other.used=真;
}
返回和运算符=(常量返回和其他)
{
other.used=真;
值=其他值;
归还*这个;
}
运算符T()常量
{
使用=真;
返回值;
}
~Return()//如果未使用该值,则生成错误
{
断言(已使用);
}
私人:
T值;
可变布尔;
};
返回foo()
{
返回42;
}
int main()
{
int i=foo();//好的
std::cout如果方法声明为const
并且没有任何东西存储返回值,我认为问题会被优化掉,这样您就不必担心了。但无论如何,这是个好问题。从优化的角度来看,无论函数是否声明为const,我都不认为这是一个问题。可以吗,如果您可以heck it runtime?我不知道这是否只是一个例子,但如果不是,你能避免“v=v.blah()”或“v=blah(v)”吗?如果可能的话,在计算的每个阶段使用不同的变量,这样即使没有编译器检查,当你遗漏一个赋值时,你也能更清楚地看到吗?“Vec3f v_init=foo();v_norm=v.getNormalized();Vec3f v_ans=v_norm*v_other;等等;“或者,不是您真正想要的,而是使用一个二进制函数或运算符,所以“v.assignNormalisedTo(v)”。换句话说,void Vec3f::getNormalized(Vec3f&result)
但是,如果调用v.getNormalized(v),请小心发生什么
Peter Hull;在这种情况下,我会将函数设置为静态。我正在考虑类似的问题。我不会在实际代码中使用它,但这是一个很好的学术解决方案。