2011-12-29 126 views
2

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

我断言宏:

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

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

(更新中...)

我会回答werewindle奈亚拉托提普JDV-简·德·梵这里。我使用标准assert进行调试配置。但是beta测试后,我仍然可以从最终客户的崩溃报告,并且在大多数情况下,我需要改变我崩溃的功能:

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

我明白了,我的程序可以大概后崩溃(否则它肯定会崩溃当前功能)。此外,我无法退出应用程序,因为开发是针对iPhone的(应用程序可能不会以编程方式退出)。所以最简单的方法是在断言失败时“自动返回”。

+0

当他们说,应用程序不能只退出程序,但并不意味着你应该保持,无论你的程序有什么错误运行。他们的意思是说**你的应用程序在提交之前应该没有错误**! – 2011-12-29 12:44:01

+0

iPhone - 不是Objective-C而不是C++? – codeling 2011-12-29 12:48:45

+1

你有没有想过使用异常?看起来你可能有一个非常高级别的try-catch块,然后记录你可以合并到你的异常对象中的消息(以及__FILE__和__LINE__给出的位置)。你似乎没有对回报价值感兴趣,对吗? – Andre 2011-12-29 19:11:29

回答

4

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

但为什么不退出程序(即调用exit功能)?从函数返回并不像是一个非常强大的错误处理。失败的断言应该只发生在出现严重错误的情况下(意味着程序处于无法处理的状态),所以最好退出program as soon as possible

+0

如果编译器厂商想要,当然他可以添加这样的宏。它与__LINE__,__FUNC__等没有什么不同。 – lkanab 2015-05-12 08:28:40

+0

返回一些东西的一个原因是查看所有可能的流程的静态分析工具。如果他们符合回报 - 他们知道流程已经结束。如果他们遇到退出 - 他们不会。 – lkanab 2015-05-12 08:30:51

0

宏没有return值,因为它们本身没有功能。它们将源代码替换为使用它们的地方,因此您可以在使用宏的函数中使用return

没有办法从宏中获取return value

2

有确定返回类型的函数里面C.

另外,如果你以某种方式实现的变种ASSERT会导致错误的程序的行为不正确的方法。 ASSERT的主要思想:如果失败,那么程序处于未定义状态,只有正确的方法是现在停止它。即致电exit()

1

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

但这里是我的看法:你使用错误的方式断言。它们只能用于代码的完整性检查(对于错误而不仅仅是因为程序员而发生);如果所有的断言都通过了,你不需要关心它们,你不需要记录它们。

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

0

我认为你可以用模板函数做到这一点,你可以在宏中调用default(x)。

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

这将工作的默认构造函数everyting。我认为你需要编写一个特殊的宏来作为void。

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

+0

传递给default()的参数是什么? – brigadir 2011-12-29 11:34:50

+0

返回值。它将返回类型T的默认值,这是无参数ctor的值。 – 2011-12-29 13:19:56

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 
} 
+0

这不够“微妙”,但可能是一个解决方案。使用最少的编码就会看起来像'ASSERT(condition,return_command)',并使用它:'ASSERT(x,return 0);' – brigadir 2011-12-29 13:08:39