C99 assert

Jeff Johnston jjohnstn@redhat.com
Wed Jun 27 12:50:00 GMT 2007


Eric Blake wrote:
> Jeff Johnston <jjohnstn <at> redhat.com> writes:
> 
>> Hi Eric,
>>
>>    I'd like to see backward-compatiblity to be the old-style message 
>> format.  I don't see the point of saying: function <blank>.  So, old 
>> compiled calls to __assert would behave as they always have.  Similarly, 
>> for systems without function capability, I would like to use the old 
>> message format.  My take would be to have both __assert and 
>> __assert_func and have assert map to the appropriate call.  I also think 
>> that the function should be quoted or you should use a colon (e.g. 
>> function: getparms) for clarification.
>>
> 
> How about the following, then?
> 

Looks good, thanks.  Assuming you have done some preliminary testing on 
it, feel free to check it in.

-- Jeff J.

> 2007-06-26  Eric Blake  <ebb9@byu.net>
> 
> 	Support __func__ in assert, as required by C99.
> 	* libc/stdlib/assert.c (__assert_func): New function.
> 	(__assert): Use __assert_func.
> 	* libc/include/assert.h (assert) [!NDEBUG]: Use __assert_func when
> 	possible.
> 
> Index: libc/include/assert.h
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/include/assert.h,v
> retrieving revision 1.1.1.1
> diff -u -p -r1.1.1.1 assert.h
> --- libc/include/assert.h	17 Feb 2000 19:39:46 -0000	1.1.1.1
> +++ libc/include/assert.h	26 Jun 2007 20:01:28 -0000
> @@ -11,18 +11,26 @@ extern "C" {
>  #undef assert
>  
>  #ifdef NDEBUG           /* required by ANSI standard */
> -#define assert(p)  	((void)0)
> +# define assert(p)	((void)0)
>  #else
> +# define assert(e) ((e) ? (void)0 : __assert_func (__FILE__, __LINE__, \
> +                                                   __ASSERT_FUNC, #e))
> +#endif /* NDEBUG */
>  
> -#ifdef __STDC__
> -#define assert(e)       ((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))
> -#else   /* PCC */
> -#define assert(e)       ((e) ? (void)0 : __assert(__FILE__, __LINE__, "e"))
> +#ifdef __cplusplus && defined __GNUC__
> +  /* Use g++'s demangled names.  */
> +# define __ASSERT_FUNC __PRETTY_FUNCTION__
> +#elif __cplusplus || __STDC_VERSION__ < 199901L
> +  /* C++03 and C89 do not have __func__.  */
> +# define __ASSERT_FUNC ((char*) 0)
> +#else /* C99 compatible */
> +# define __ASSERT_FUNC __func__
>  #endif
>  
> -#endif /* NDEBUG */
> -
> -void _EXFUN(__assert,(const char *, int, const char *));
> +void _EXFUN(__assert,(const char *, int, const char *)
> +            _ATTRIBUTE ((__noreturn__)));
> +void _EXFUN(__assert_func,(const char *, int, const char *, const char *)
> +            _ATTRIBUTE ((__noreturn__)));
>  
>  #ifdef __cplusplus
>  }
> Index: libc/stdlib/assert.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/assert.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 assert.c
> --- libc/stdlib/assert.c	28 Oct 2005 21:21:07 -0000	1.2
> +++ libc/stdlib/assert.c	26 Jun 2007 20:01:28 -0000
> @@ -9,11 +9,6 @@ ANSI_SYNOPSIS
>  	#include <assert.h>
>  	void assert(int <[expression]>);
>  
> -TRAD_SYNOPSIS
> -	#include <assert.h>
> -	assert(<[expression]>)
> -	int <[expression]>;
> -
>  DESCRIPTION
>  	Use this macro to embed debuggging diagnostic statements in
>  	your programs.  The argument <[expression]> should be an
> @@ -24,7 +19,11 @@ DESCRIPTION
>  	calls <<abort>>, after first printing a message showing what
>  	failed and where:
>  
> -. Assertion failed: <[expression]>, file <[filename]>, line <[lineno]>
> +. Assertion failed: <[expression]>, file <[filename]>, line <[lineno]>, 
> function: <[func]>
> +
> +	If the name of the current function is not known (for example,
> +	when using a C89 compiler that does not understand __func__),
> +	the function is omitted.
>  
>  	The macro is defined to permit you to turn off all uses of
>  	<<assert>> at compile time by defining <<NDEBUG>> as a
> @@ -48,15 +47,28 @@ Supporting OS subroutines required (only
>  #include <stdlib.h>
>  #include <stdio.h>
>  
> +/* func can be NULL, in which case no function information is given.  */
>  void
> -_DEFUN (__assert, (file, line, failedexpr),
> +_DEFUN (__assert_func, (file, line, func, failedexpr),
>  	const char *file _AND
>  	int line _AND
> +	const char *func _AND
>  	const char *failedexpr)
>  {
> -  (void)fiprintf(stderr,
> -	"assertion \"%s\" failed: file \"%s\", line %d\n",
> -	failedexpr, file, line);
> +  fiprintf(stderr,
> +	   "assertion \"%s\" failed: file \"%s\", line %d%s%s\n",
> +	   failedexpr, file, line,
> +           func ? ", function: " : "", func ? func : "");
>    abort();
>    /* NOTREACHED */
>  }
> +
> +void
> +_DEFUN (__assert, (file, line, failedexpr),
> +	const char *file _AND
> +	int line _AND
> +	const char *failedexpr)
> +{
> +   __assert_func (file, line, NULL, failedexpr);
> +  /* NOTREACHED */
> +}
> 
> 



More information about the Newlib mailing list