ASSERT_THROW: error: void value not ignored as it ought to be
ASSERT_THROW: error: void value not ignored as it ought to be
我是 gtest 的初学者。我尝试使用 ASSERT_THROW 会编译失败。谁能帮忙解决这个问题:
class my_exp {};
int main(int argc, char *argv[])
{
EXPECT_THROW(throw my_exp(), my_exp); // this will pass
// This will through below compilation error
ASSERT_THROW(throw my_exp(), my_exp);
return 0;
}
编译输出:
ERROR :
In file included from /usr/include/gtest/gtest.h:57:0,
from gtest.cpp:1:
gtest.cpp: In function ‘int main(int, char**)’:
gtest.cpp:12:3: error: void value not ignored as it ought to be
ASSERT_THROW(throw my_exp(), my_exp);
^
短版
你写测试的方式不对,写测试you should把断言放在测试(宏TEST
)或测试夹具(宏TEST_F
)中。
长版
1。到底发生了什么?
要找出真正的问题并不容易,因为 Google 测试框架使用隐藏真实代码的宏。要查看宏替换后的代码需要进行预处理,类似这样:
g++ -E main.cpp -o main.p
使用ASSERT_THROW
预处理的结果如下(格式化后):
class my_exp {};
int main(int argc, char *argv[])
{
switch (0)
case 0:
default:
if (::testing::internal::ConstCharPtr gtest_msg = "") {
bool gtest_caught_expected = false;
try {
if (::testing::internal::AlwaysTrue () ) {
throw my_exp ();
};
} catch (my_exp const &) {
gtest_caught_expected = true;
} catch (...) {
gtest_msg.value = "Expected: throw my_exp() throws an exception of type my_exp.\n Actual: it throws a different type.";
goto gtest_label_testthrow_7;
} if (!gtest_caught_expected) {
gtest_msg.value = "Expected: throw my_exp() throws an exception of type my_exp.\n Actual: it throws nothing.";
goto gtest_label_testthrow_7;
}
}
else
gtest_label_testthrow_7:
return ::testing::internal::AssertHelper (::testing::TestPartResult::kFatalFailure, "main.cpp", 7, gtest_msg.value) = ::testing::Message ();
return 0;
}
对于 EXPECT_THROW
结果将是相同的,除了一些差异:
else
gtest_label_testthrow_7:
::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "main.cpp", 7, gtest_msg.value) = ::testing::Message ();
2。 OK,不同行为的原因找到了,让我们继续。
在文件 src/gtest.cc 中可以找到 AssertHelper
class 声明包括赋值运算符 which return void
:
void AssertHelper::operator=(const Message& message) const
所以现在编译器抱怨的原因已经澄清了。
3。但是为什么会导致这个问题还不清楚。尝试了解为什么 ASSERT_THROW
和 EXPECT_THROW
生成了不同的代码。答案是文件 include/gtest/internal/gtest-internal.h
中的宏
#define GTEST_FATAL_FAILURE_(message) \
return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
#define GTEST_NONFATAL_FAILURE_(message) \
GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
其中包含 return
致命案例。
4。但现在的问题是为什么这个断言通常效果很好?
要回答这个问题,请尝试调查在测试中放置断言时以正确方式编写的代码片段:
#include <gtest/gtest.h>
class my_exp {};
TEST (MyExp, ThrowMyExp)
{
ASSERT_THROW (throw my_exp (), my_exp);
}
为了排除答案的污染,我只注意到在这种情况下,ASSERT_THROW
的 return
语句也存在,但它放在方法中:
void MyExp_ThrowMyExp_Test::TestBody ()
哪个returnvoid
!但是在您的示例中,断言位于 main
函数中,其中 return int
。看来这是问题的根源!
尝试用简单的片段证明这一点:
void f1 () {};
void f2 () {return f1();};
//int f2 () {return f1();}; // error here!
int main (int argc, char * argv [])
{
f2;
return 0;
}
5。所以最终的答案是:ASSERT_THROW
宏包含 return 表达式的语句,其计算结果为 void
并且当这样的表达式被放入 return 非 void 值的函数时,gcc 会抱怨关于错误。
P.S。但无论如何我不知道为什么在一种情况下使用 return 而在另一种情况下不使用
更新:我在 GitHub 上问过这个问题并得到以下答案:
ASSERT_XXX is used as a poor man's exception to allow it to work in
environments where exceptions are disabled. It does a return; instead.
It is meant to be used from within the TEST() methods, which return
void.
更新:我刚刚意识到 the official documentation:
中描述的这个问题
By placing it in a non-void function you'll get a confusing compile error > like "error: void value not ignored as it ought to be".
我是 gtest 的初学者。我尝试使用 ASSERT_THROW 会编译失败。谁能帮忙解决这个问题:
class my_exp {};
int main(int argc, char *argv[])
{
EXPECT_THROW(throw my_exp(), my_exp); // this will pass
// This will through below compilation error
ASSERT_THROW(throw my_exp(), my_exp);
return 0;
}
编译输出:
ERROR :
In file included from /usr/include/gtest/gtest.h:57:0,
from gtest.cpp:1:
gtest.cpp: In function ‘int main(int, char**)’:
gtest.cpp:12:3: error: void value not ignored as it ought to be
ASSERT_THROW(throw my_exp(), my_exp);
^
短版
你写测试的方式不对,写测试you should把断言放在测试(宏TEST
)或测试夹具(宏TEST_F
)中。
长版
1。到底发生了什么?
要找出真正的问题并不容易,因为 Google 测试框架使用隐藏真实代码的宏。要查看宏替换后的代码需要进行预处理,类似这样:
g++ -E main.cpp -o main.p
使用ASSERT_THROW
预处理的结果如下(格式化后):
class my_exp {};
int main(int argc, char *argv[])
{
switch (0)
case 0:
default:
if (::testing::internal::ConstCharPtr gtest_msg = "") {
bool gtest_caught_expected = false;
try {
if (::testing::internal::AlwaysTrue () ) {
throw my_exp ();
};
} catch (my_exp const &) {
gtest_caught_expected = true;
} catch (...) {
gtest_msg.value = "Expected: throw my_exp() throws an exception of type my_exp.\n Actual: it throws a different type.";
goto gtest_label_testthrow_7;
} if (!gtest_caught_expected) {
gtest_msg.value = "Expected: throw my_exp() throws an exception of type my_exp.\n Actual: it throws nothing.";
goto gtest_label_testthrow_7;
}
}
else
gtest_label_testthrow_7:
return ::testing::internal::AssertHelper (::testing::TestPartResult::kFatalFailure, "main.cpp", 7, gtest_msg.value) = ::testing::Message ();
return 0;
}
对于 EXPECT_THROW
结果将是相同的,除了一些差异:
else
gtest_label_testthrow_7:
::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "main.cpp", 7, gtest_msg.value) = ::testing::Message ();
2。 OK,不同行为的原因找到了,让我们继续。
在文件 src/gtest.cc 中可以找到 AssertHelper
class 声明包括赋值运算符 which return void
:
void AssertHelper::operator=(const Message& message) const
所以现在编译器抱怨的原因已经澄清了。
3。但是为什么会导致这个问题还不清楚。尝试了解为什么 ASSERT_THROW
和 EXPECT_THROW
生成了不同的代码。答案是文件 include/gtest/internal/gtest-internal.h
#define GTEST_FATAL_FAILURE_(message) \
return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
#define GTEST_NONFATAL_FAILURE_(message) \
GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
其中包含 return
致命案例。
4。但现在的问题是为什么这个断言通常效果很好?
要回答这个问题,请尝试调查在测试中放置断言时以正确方式编写的代码片段:
#include <gtest/gtest.h>
class my_exp {};
TEST (MyExp, ThrowMyExp)
{
ASSERT_THROW (throw my_exp (), my_exp);
}
为了排除答案的污染,我只注意到在这种情况下,ASSERT_THROW
的 return
语句也存在,但它放在方法中:
void MyExp_ThrowMyExp_Test::TestBody ()
哪个returnvoid
!但是在您的示例中,断言位于 main
函数中,其中 return int
。看来这是问题的根源!
尝试用简单的片段证明这一点:
void f1 () {};
void f2 () {return f1();};
//int f2 () {return f1();}; // error here!
int main (int argc, char * argv [])
{
f2;
return 0;
}
5。所以最终的答案是:ASSERT_THROW
宏包含 return 表达式的语句,其计算结果为 void
并且当这样的表达式被放入 return 非 void 值的函数时,gcc 会抱怨关于错误。
P.S。但无论如何我不知道为什么在一种情况下使用 return 而在另一种情况下不使用
更新:我在 GitHub 上问过这个问题并得到以下答案:
ASSERT_XXX is used as a poor man's exception to allow it to work in environments where exceptions are disabled. It does a return; instead. It is meant to be used from within the TEST() methods, which return void.
更新:我刚刚意识到 the official documentation:
中描述的这个问题By placing it in a non-void function you'll get a confusing compile error > like "error: void value not ignored as it ought to be".