C++ 获取宏中函数的返回类型(C+;+;)
我有C++ 获取宏中函数的返回类型(C+;+;),c++,function,types,assert,C++,Function,Types,Assert,我有ASSERT(x)宏,如果它断言(在版本配置中),我想调用return。 要做到这一点,我需要知道我在哪里使用这个ASSERT函数的返回类型。如何获得它(我处理C++03,llvmgcc4.2编译器) 我的断言宏: #define ASSERT(x) \ if(!(x)) { LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \ return /*return_type()*/; \ } PS:我尝试
ASSERT(x)
宏,如果它断言(在版本配置中),我想调用return
。
要做到这一点,我需要知道我在哪里使用这个ASSERT
函数的返回类型。如何获得它(我处理C++03
,llvmgcc4.2
编译器)
我的断言宏:
#define ASSERT(x) \
if(!(x)) {
LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
return /*return_type()*/; \
}
PS:我尝试返回0代码>-编译器显示void函数的错误(对于复杂的返回类型我没有尝试过),如果返回代码>-非void函数的错误
(更新…
我会在这里回答werewindle、nyarlathotep和jdv Jan de Vaan的问题。我使用标准assert
进行调试配置。但在测试版测试之后,我仍然会收到最终客户的崩溃报告,在大多数情况下,我需要更改崩溃功能:
ASSERT (_some_condition_);
if (!_some_condition_) // add this return
return _default_value_;
我明白,我的程序以后可能会崩溃(否则它肯定会在当前函数中崩溃)。我也不能退出应用程序,因为开发是针对iPhone的(应用程序可能不会以编程方式退出)。因此,最简单的方法是在断言失败时“自动返回”。您无法确定宏中周围函数的返回类型;宏是由预处理器扩展的,预处理器没有关于这些宏出现的环境的此类信息;它基本上只是“搜索和替换”宏。您必须为每个返回类型编写单独的宏
但是为什么不退出程序(即调用exit
函数)?仅仅从函数返回似乎不是一个非常健壮的错误处理。失败的断言毕竟只有在出现严重错误时才会发生(这意味着程序处于非设计用于处理的状态),因此最好退出。宏不返回值,因为它们本身不是函数。它们替换使用它们的源代码,因此在使用宏的函数中返回
无法从宏中获取返回值。在C中没有确定函数内部返回类型的正确方法
此外,如果您以某种方式实现了ASSERT
的变体,则会导致错误的程序行为。断言的主要思想是:若它失败了,那个么程序处于未定义状态,唯一正确的方法就是现在停止它。即通过调用exit()
您不能这样做,C/C++预处理器非常基本,不能进行任何代码分析。最多只能将返回类型传递给宏
template<class T> default<T>(T x) { return T(); }
但我的观点是:你使用断言的方式是错误的。它们只应用于代码的健全性检查(用于仅因程序员而发生的错误);如果所有断言都通过了,您不需要关心它们,也不需要记录它们
不仅如此,而且(总的来说)你应该使用最小惊喜的元素。您是否希望ASSERT
记录一些内容,然后强制使函数返回?我知道我不会的。我要么希望它完全关闭应用程序(标准的断言所做的),要么让我决定接下来会发生什么(也许我有一些可用的指针)。我想你可以用一个模板函数来实现这一点,你可以从宏中调用默认值(x)
template<class T> default<T>(T x) { return T(); }
模板默认值(tx){return T();}
这将适用于所有使用默认构造函数的情况。我认为你需要为void编写一个特殊的宏
我希望模板语法正确,我的C++已经生锈了。< /p> 你可以为你的需求定义另一个宏。
#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
}
要传递到default()
的参数是什么?返回值。它将返回类型T的默认值,这是无参数ctor的结果。当他们说应用程序不能以编程方式退出时,并不意味着不管程序有什么bug,你都应该继续运行。他们的意思是说你的应用在提交之前应该是没有bug的!iPhone不是Objul-C而不是C++吗?你想过使用异常吗?看起来您可能有一个非常高级的try-catch块,它会记录您可以合并到异常对象中的消息(以及\uuuuu-FILE\uuuu
和\uu-LINE\uu
给出的位置)。您似乎对返回值一点也不感兴趣,是吗?这还不够“精细”,但可能是一个解决方案。使用最少的编码,它看起来像ASSERT(condition,return_命令)
,要使用它:ASSERT(x,return 0)如果编译器供应商愿意,他当然可以添加这样的宏。它与LINE、FUNC等没有什么不同。返回内容的一个原因是静态分析工具,它可以查看所有可能的流。如果他们遇到了回报,他们知道这股潮流已经结束。如果他们遇到出口,他们不会。