c-assert宏在C89中的实现,如何退出程序



我正在尝试在C89标准中实现我自己的assert宏。

我希望它和最初的一样:

dir/file.c:20: MyFunction: Assertion `null != pointer` failed.

有两个问题:

  1. 没有打印函数名称的选项,因为预标识符__FUNC__仅在c99标准之后才可用
  2. 我不知道如何退出这个程序。我尝试了exit(1)__Exit(1),但它们都不起作用,我认为这是因为macros在每个处理阶段都转换为代码,这意味着预处理器甚至还不知道这些exit函数是什么。因为它们只在编译器阶段相关,对吧

这是我的代码:

/********************************* Inclusions *********************************/
#include <stdio.h>  /* printf, NULL */
/***************************** Macros Definitions *****************************/
#define ASSERT(expr) 
if (!(expr)){ 
fprintf(stderr, "%s:%d: Assertion `%s` failed.n" 
,__FILE__, __LINE__, #expr); }
/******************************************************************************/
int main()
{
void *null_ptr = NULL;

ASSERT(NULL != null_ptr);

printf("ALL WORKS");

return (0);
}
/******************************************************************************/

我的输出是:

`file.c:25: Assertion `NULL != null_ptr` failed.`

有没有办法获得函数名或用宏退出程序?因为现在,我还没有得到函数的名称,更重要的是,即使断言打印出错误消息,程序也不会停止。

这很奇怪,因为为什么不可能获得函数名或退出带有宏的程序,但原始assert可以同时执行这两项操作?

p.S每个标识符的__FILE__只为我打印文件名,如file.c,而不是像原始assert那样打印dir/file.c。为什么?

我希望我能写这样的东西:

#define ASSERT(expr) 
if (!(expr)){ 
fprintf(stderr, "%s:%d: %s: Assertion `%s` failed.n" 
,__FILE__, __LINE__, __FUNC__, #expr); exit(1) }

谢谢。

  1. 事实上,C89没有获得函数名称的方法。因此,如果你只能依靠C89,你就不得不放弃它。注意,甚至在C99之前,许多实现可能已经为此提供了它们自己的扩展,并且可能已经在它们自己的assert()定义中使用了这些扩展;例如GCC具有CCD_ 13。

  2. 如果断言失败,标准assert()宏将调用abort()。因此,如果你想复制它的行为,你也可以这样做。

Nate Eldredge回答了您的大部分查询。作为对你的P.S.的回应,我怀疑编译器可以在内部做一些我们不能做的事情。与函数名相同,但没有__func__(尽管GCC有一个可以使用的__FUNCTION__宏(。

不过,您仍然可以使assert更接近编译器assertassert试图尽可能最好地模拟一个函数。因此,首先,它必须作为一个表达式来工作,而您的表达式由于if而不能工作。此外,它应该返回void。CCD_ 24上的CCD_;原型":

void assert(scalar expression);

这两者都有可能。这是我刚刚制作的assert,它(我认为(能够满足这两个要求:

#define ASSERT(expr)                                                        
((expr) ?                                                               
(void) 0 :                                                          
(void) (fprintf(stderr, "%s:%d: %s: Assertion `%s` failedn",       
__FILE__, __LINE__, __FUNCTION__, #expr), abort()))

这利用了__FUNCTION__GCC扩展,如果你想的话,你可以删除它。

相关内容

  • 没有找到相关文章

最新更新