获取宏(c++)中函数的返回类型
Get return type of function in macro (C++)
我有ASSERT(x)
宏,如果它断言(在发布配置中),我想调用return
。要做到这一点,我需要知道返回类型的函数,我使用这个ASSERT
。如何得到它(我处理C++03
, LLVM GCC 4.2
编译器)?
My ASSERT宏:
#define ASSERT(x)
if(!(x)) {
LOG ("ASSERT in %s: %d", __FILE__, __LINE__);
return /*return_type()*/;
}
PS:我尝试了return 0;
-编译器显示错误的void函数(我没有尝试复杂的返回类型),如果return;
-错误的非void函数。
(更新…)
我将回答 werwindle , nyarlathotep和jd - jan de Vaan。我使用标准assert
进行调试配置。但在beta测试后,我仍然会收到最终用户的崩溃报告,在大多数情况下,我需要更改崩溃函数:
ASSERT (_some_condition_);
if (!_some_condition_) // add this return
return _default_value_;
我明白,我的程序可能会崩溃(否则它肯定会在当前功能中崩溃)。我也不能退出应用程序,因为开发是针对iPhone的(应用程序可能不会退出编程)。因此,最简单的方法是在断言失败时"自动返回"。
在宏中不能确定周围函数的返回类型;宏是由预处理器展开的,预处理器并没有这些宏发生的环境信息;它基本上只是"搜索和替换"宏。您必须为每种返回类型编写单独的宏。
但为什么不退出程序(即调用exit
函数)?仅仅从函数返回似乎不是一个非常健壮的错误处理。毕竟,失败的断言应该只在出现严重错误时才会发生(这意味着程序处于一种它没有设计来处理的状态),因此最好尽快退出程序。
在c语言中没有合适的方法来确定函数内部的返回类型。
同样,如果您以某种方式实现ASSERT
的变体,它将导致错误的程序行为。ASSERT
的主要思想:如果失败,则程序处于未定义状态,唯一正确的方法是现在停止它。即通过调用exit()
。
我认为你可以用模板函数来做到这一点,你可以在宏中调用default(x)。
template<class T> default<T>(T x) { return T(); }
将适用于所有具有默认构造函数的内容。我认为你需要为void写一个特殊的宏。
我希望我的模板语法是正确的,我的c++越来越生疏了。
你不能这样做,C/c++预处理器是非常基本的,它不能做任何代码分析。您最多只能将返回类型传递给宏。
但是我的观点是:你使用断言的方式是错误的。它们应该只用于代码的完整性检查(对于程序员可能导致的错误);如果所有的断言都通过了,你不需要关心它们,你不需要记录它们。
不仅如此,而且(一般来说)你应该使用最不意外的元素。您是否期望ASSERT
记录一些东西,然后强制使函数返回?我知道我不会。我要么期望它完全关闭应用程序(标准assert
所做的),要么让我决定接下来会发生什么(也许我有一些指针可以释放)。
宏没有return
值,因为它们本身不是函数。它们替换了使用它们的源代码,因此您可以在使用宏的函数中使用return
。
没有办法从宏中获得return value
。
您可以根据需要定义另一个宏。
#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
}
就这么做
#define ASSERT(x, ret, type)
if(!(x)){
LOG ("ASSERT in %s: %d", __FILE__, __LINE__);
return (type) ret;
}
我相信你在试图解决错误的问题。如果你不想让你的程序在断言的情况下崩溃,你最好改进你的测试。
在这些断言中使用'return'会给您一种错误的安全感。相反,它隐藏了你的问题,并在你的程序中引起意想不到的行为,所以你得到的bug要复杂得多。我的一个同事为此写了一篇很好的博客。
如果你真的想要它,你可以试着写return {};
,让它默认构造这个值,或者有一个assert宏,你也提供了失败的情况。但是我真的不推荐它!
- 检查函数返回类型是否与STL容器类型值相同
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 在 c++ 中将函数返回类型指定为模板参数
- 通过引用传递参数;函数返回类型是否必须为 VOID?
- 如何避免模板函数返回类型重复?
- 从类型bankAccount的返回值到函数返回类型int没有可行的转换
- 为什么在某些情况下从函数返回类型中删除 cv 限定符?
- 模板类内模板类的函数返回类型
- 为什么函数返回类型中不允许参数推导?
- 函数返回类型之前的"define"
- C++推断要隐式调用的模板函数返回类型
- 具有不同模板参数的函数返回类型
- 当函数返回类型为父类时,如何返回子类的对象?
- C++:在原型中声明"auto"函数返回类型仍然会导致在扣除错误之前使用"auto&quo
- C++14 'auto'能够获取函数返回类型,我们还需要 std::result_of<> 吗?
- 函数返回类型中的模板类型推断
- 嵌套模板类返回类型在 C++ 中的头文件中函数返回类型的语法
- C++重写 void 函数返回类型会导致生成失败
- 从函数内部推断函数返回类型
- C++嵌套类函数返回类型和命名空间