我有ASSERT(x)
宏,如果断言(在发布配置中)我想调用return
。
为此,我需要知道使用此ASSERT
的函数的返回类型。如何获得它(我处理C++03
,LLVM GCC 4.2
编译器)?
我的ASSERT宏:
#define ASSERT(x) \
if(!(x)) {
LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
return /*return_type()*/; \
}
PS:我试过return 0;
- 编译器显示void函数的错误(我没有尝试复杂的返回类型),如果return;
- 非void函数的错误。
(适用更新...)
我会在这里回答错误, nyarlathotep 和 jdv-Jan de Vaan 。我使用标准assert
进行调试配置。但经过beta测试后,我仍然会收到最终客户的崩溃报告,在大多数情况下我需要更改崩溃的功能:
ASSERT (_some_condition_);
if (!_some_condition_) // add this return
return _default_value_;
据我所知,我的程序可能会在稍后崩溃(否则它肯定会在当前函数中崩溃)。此外,我不能退出应用程序,因为开发适用于iPhone(应用程序可能不会以编程方式退出)。所以最简单的方法是在断言失败时“自动返回”。
答案 0 :(得分:4)
您无法确定宏中周围函数的返回类型;宏由预处理器扩展,它没有关于这些宏出现的环境的这种信息;它基本上只是“搜索和替换”宏。您必须为每种返回类型编写单独的宏。
但为什么不退出程序(即调用exit
函数)?刚从函数返回似乎不是一个非常强大的错误处理。失败的断言毕竟只有在某些事情出现严重错误时才会发生(意味着程序处于不设计处理的状态),因此最好退出program as soon as possible。
答案 1 :(得分:2)
没有正确的方法来确定C中函数内的返回类型。
此外,如果您以某种方式实现ASSERT
的变体,将导致错误的程序行为。 ASSERT
的主要思想:如果失败,则程序处于未定义状态,只有正确的方法是立即停止它。即致电exit()
。
答案 2 :(得分:1)
你不能这样做,C / C ++预处理器非常基础,不能进行任何代码分析。您最多可以将返回类型传递给宏。
但是我的观点是:你以错误的方式使用断言。它们只应用于代码的健全性检查(对于错误而言,只能由于程序员而发生);如果所有断言都通过,你不需要关心它们,你不需要记录它们。
不仅如此,而且(一般来说)你应该使用最少惊喜的元素。你期望ASSERT
记录一些内容然后强行让函数返回吗?我知道我不会。我要么完全关闭应用程序(标准assert
做什么),要么让我决定接下来会发生什么(也许我有一些免费的指针)。
答案 3 :(得分:0)
宏不具有return
值,因为它们本身不是函数。他们将源代码替换为使用它们的位置,因此您在使用宏的函数中return
。
无法从宏中获取return value
。
答案 4 :(得分:0)
我认为您可以使用模板函数执行此操作,您可以在宏中调用默认值(x)。
template<class T> default<T>(T x) { return T(); }
将适用于使用默认构造函数的每个人。我认为你需要为void编写一个特殊的宏。
我希望我的模板语法正确,我的c ++正在生锈。
答案 5 :(得分:0)
您可以根据需要定义另一个宏。
#define ASSERT(x) \
if(!(x)) { \
LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
ASSERT_DEFAULT_RETURN(); \
}
然后在函数内部:
int foo(){
#ifdef ASSERT_DEFAULT_RETURN
#undef ASSERT_DEFAULT_RETURN
#endif
#define ASSERT_DEFAULT_RETURN() return 0
// ...
ASSERT(some_expression);
// ...
// cleanup
#undef ASSERT_DEFAULT_RETURN
}