繁体   English   中英

获取宏中函数的返回类型(C++)

[英]Get return type of function in macro (C++)

我有ASSERT(x)宏,如果它断言(在发布配置中),我想调用return 为此,我需要知道使用此ASSERT的函数的返回类型。 如何得到它(我处理C++03LLVM GCC 4.2编译器)?

我的断言宏:

#define ASSERT(x) \
    if(!(x)) {
        LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
        return /*return_type()*/; \
    }

PS:我试过return 0; - 如果return;编译器显示 void 函数错误(我没有尝试复杂的返回类型) return; - 非空函数的错误。

(更新...)

我会在这里回答werewindlenyarlathotepjdv-Jan de Vaan 我使用标准assert进行调试配置。 但是在 beta 测试之后,我仍然会收到最终客户的崩溃报告,并且在大多数情况下,我需要更改我的崩溃函数:

ASSERT (_some_condition_);
if (!_some_condition_)      // add this return
    return _default_value_;

我知道,我的程序可能会在以后崩溃(否则它肯定会在当前函数中崩溃)。 我也不能退出应用程序,因为开发是针对 iPhone 的(应用程序可能不会在那里以编程方式退出)。 所以最简单的方法是在断言失败时“自动返回”。

您无法确定宏中周围函数的返回类型; 宏由预处理器扩展,它没有关于这些宏出现的环境的这种信息; 它基本上只是“搜索和替换”宏。 您必须为每种返回类型编写单独的宏。

但为什么不退出程序(即调用exit函数)? 刚从函数返回似乎不是一个非常强大的错误处理。 失败的断言应该只在某些事情出现严重错误时发生(意味着程序处于不能设计处理的状态),因此最好尽快退出程序

没有正确的方法来确定C中函数内的返回类型。

此外,如果您以某种方式实现ASSERT的变体,它将导致错误的程序行为。 ASSERT主要思想:如果失败,那么程序处于未定义状态,只有正确的方法是立即停止它。 即通过调用exit()

你不能这样做,C / C ++预处理器非常基础,不能进行任何代码分析。 您最多可以将返回类型传递给宏。

但是我的意见是:你使用错误的方式使用断言。 它们只应用于代码的健全性检查(对于错误而言,只能由于程序员而发生); 如果所有断言都通过,你不需要关心它们,你不需要记录它们。

不仅如此,而且(一般而言)你应该使用最少惊喜的元素。 你期望ASSERT记录一些东西然后强行让函数返回吗? 我知道我不会。 我要么完全关闭应用程序(标准assert做什么),要么让我决定接下来会发生什么(也许我有一些免费的指针)。

就这样做

#define ASSERT(x, ret, type)    \
     if(!(x)){
          LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
          return (type) ret;
     }

我相信您正在尝试解决错误的问题。 你不希望你的程序在断言的情况下崩溃,你最好改进你的测试。

在这些断言中有“回报”会给你一种虚假的安全感。 相反,它隐藏了您的问题并导致程序中出现意外行为,因此您遇到的错误要复杂得多。 我的一位同事实际上写了一篇很好的博客文章

如果你真的想要它,你可以尝试写return {}; 所以它默认构造值,或者有一个断言宏,您还可以在其中提供失败案例。 不过我真的不推荐!

宏不return值,因为它们本身不是函数。 它们替换使用它们的源代码,因此您将return使用宏的函数。

无法从宏获取return value

我认为您可以使用模板函数执行此操作,您可以在宏中调用default(x)。

template<class T> default<T>(T x) { return T(); }

这将适用于默认构造函数的每一个。 我认为你需要为void编写一个特殊的宏。

我希望我的模板语法正确,我的c ++正在生锈。

您可以根据需要定义另一个宏。

#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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM