[C language learning fun] _ GCC source code analysis _ 2_assert.h

Source: Internet
Author: User

I remember in the previous article, I analyzed the <assert. h> in a heap of windows. Today, let's take a look at the definition of this file in GCC.

[1] role of assert macro

The role of assert macro to implement assertions is generally referenced in the source file in the following format:

 
# Include <assert. h># UNDEFNdebugAssert (expression)

About assert macro:

1. When expression is 0, assertion is performed. If expression is non-zero, assertion is not performed.

2. When assert macro performs assert, output the source file name __file _ in the standard error output and the row of the statement when the assert occurs: _ line __

3.ProgramDuring the debugging process, the assert macro is used to test the key program to output some useful information. When debugging is not required, you can define the ndebug macro to cancel it.

The role of macro assert.

[2] assert. h

 /*  Allow this file to be compiled ded multiple times with different settings of ndebug. */  //  Assert is an assertion mechanism provided by C library.  //  Assertions are used to output stream output information in a standard error and terminate an exception in the program.  /*  Assertion mechanism:  */  //  First, cancel the definition of the assert macro,  //  The purpose is to prevent macro duplication from being defined.  # UNDEF Assert # UNDEF _ Assert // Determine whether the ndebug macro is negative.Source codeWhether macro assert is required  /*  If the ndebug macro is defined, it means that you do not need to reference the assert macro ndebug: Do not debug in the program. Otherwise, the assert Macro will be executed and we can find that when the assert macro defines ndebug, the definition is special. macro parameters are not referenced.  */  # Ifdef ndebug  //  Ndebug macro is defined, and assert macro is defined as no prompt output       # Define Assert (ignore) (void) 0) # Else      Void _ Eprintf (); /*  Defined in gnulib */  # Ifdef _ stdc __  //  The _ stdc _ macro is defined.          # Define Assert (expression )\ ((  Void ) (Expression )? 0  : _ Assert (# expression, _ file __, _ line __)))  # Define _ Assert (expression, file, lineno )\ (_ Eprintf (  "  Failed assertion '% s' at line % d of' % s'. \ n "  , \ Expression, lineno, file ),  0  )  # Else /* No _ stdc __; I. e.-Traditional .*/ # Define Assert (expression )\ ((  Void ) (Expression )? 0  : _ Assert (expression, _ file __, _ line __)))  # Define _ Assert (expression, file, lineno )\ (_ Eprintf ( "  Failed assertion '% s' at line % d of' % s'. \ n  "  ,\  "  Expression  " , Lineno, file ), 0  )  # Endif /* No _ stdc __; I. e.-Traditional .*/ # Endif 

View code

[3] preprocessing

//First, cancel the definition of the assert macro,//The purpose of this operation is to prevent the impact of repeated definition macros.# UNDEFAssert# UNDEF_ Assert

The purpose of this operation is to prevent assert redefinition and confusion. In this way, the previous definition can be canceled at the referenced position.

[4] standard assert macro definition structure

Generally, the assert macro definition has the following structure:

The purpose of this structure is to make a correct response to the user's ndebug macro.

[5] macroCode

 //  Determine whether macro assert is required in the source code by checking whether ndebug is a negative macro.  /*  If the ndebug macro is defined, it means that you do not need to reference the assert macro ndebug: Do not debug in the program. Otherwise, the assert Macro will be executed and we can find that when the assert macro defines ndebug, the definition is special. macro parameters are not referenced. */  # Ifdef ndebug  //  Ndebug macro is defined, and assert macro is defined as no prompt output       # Define Assert (ignore) (void) 0) # Else      Void _ Eprintf (); /*  Defined in gnulib  */  # Ifdef _ stdc __  //  The _ stdc _ macro is defined.          # Define Assert (expression )\((  Void ) (Expression )? 0  : _ Assert (# expression, _ file __, _ line __)))  # Define _ Assert (expression, file, lineno )\ (_ Eprintf (  "  Failed assertion '% s' at line % d of' % s'. \ n  "  , \ Expression, lineno, file ),  0  )  # Else /* No _ stdc __; I. e.-Traditional .*/ # Define Assert (expression )\ ((  Void ) (Expression )? 0  : _ Assert (expression, _ file __, _ line __)))  # Define _ Assert (expression, file, lineno )\ (_ Eprintf (  "  Failed assertion '% s' at line % d of' % s'. \ n  "  ,\  " Expression  " , Lineno, file ), 0  )  # Endif /* No _ stdc __; I. e.-Traditional .*/ # Endif 

Here we can see that this macro actually defines two red keys: assert and _ assert.

1. Assert

There are two situations:

When _ stdc _ macro is defined:

 
# DefineAssert (expression )\((Void) (Expression )?0: _ Assert (# expression, _ file __, _ line __)))

When _ stdc _ macro is not defined:

# DefineAssert (expression )\((Void) (Expression )?0: _ Assert (expression, _ file __, _ line __)))

The difference between the two lies only in the role of the "#" connector. If the form # expression is not used, the macro parameter cannot use a string with quotation marks.

# Expression. The actual assert macro parameter can be a string with quotation marks.

Two predefined macros:

_ File __: return the source file name of the C member.

_ Line _: return the number of lines in the C file of the code line.

2. _ assert

This macro has only one form:

# Define_ Assert (expression, file, lineno )\(_ Eprintf ("Failed assertion '% s' at line % d of' % s'. \ n",\"Expression", Lineno, file ),0)

This macro actually references the function _ eprintf () to implement the output. This function is not a standard library function. If you want to implement the standard assert macro, you cannot reference the standard library

Function implementation, because if the program does not contain these library functions, it will cause an exception.

_ Eprintf () function:

 # Ifdef l_eprintf # include <Stdio. h> /* This is used by the 'assert 'macro.  */  Void  _ Eprintf (  String  , Expression, line, filename)  Char * String  ;  Char * Expression;  Int  Line;  Char * Filename; {fprintf (stderr, String  , Expression, line, filename); fflush (stderr); abort ();}  # Endif 

That is to say, this header file can also be like this:

 # Ifdef ndebug  //  Ndebug macro is defined, and assert macro is defined as no prompt output       # Define Assert (ignore) (void) 0) # Else      Void _ Eprintf (); /*  Defined in gnulib  */      # Define _ Assert (expression, file, lineno )\(_ Eprintf (  "  Failed assertion '% s' at line % d of' % s'. \ n  "  , \ Expression, lineno, file ),  0  ) # Ifdef _ stdc __  //  The _ stdc _ macro is defined.          # Define Assert (expression )\ ((  Void ) (Expression )? 0 : _ Assert (# expression, _ file __, _ line __)))  # Else /* No _ stdc __; I. e.-Traditional .*/ # Define Assert (expression )\ ((  Void ) (Expression )? 0  : _ Assert (expression, _ file __, _ line __)))  # Endif /* No _ stdc __; I. e.-Traditional .*/ # Endif 

[6] comparison of Microsoft vs 2008 code

 /* * ** Assert. h-define the assert macro ** copyright (c) Microsoft Corporation. all rights reserved. ** purpose: * defines the assert (exp) Macro. * [ANSI/System V] ** [public] *****  */  # Include <Crtdefs. h> # UNDEF Assert # Ifdef ndebug  # Define Assert (_ expression) (void) 0) # Else  # Ifdef _ cplusplus  Extern   "  C  " {  # Endif  _ Cribd  Void _ Cdecl _ wassert (_ in_z _ Const Wchar_t * _ message, _ in_z _ Const Wchar_t * _ File, _ in _ unsigned _ line); # ifdef _ cplusplus}  # Endif  # Define Assert (_ expression) (void )((!! (_ Expression) | (_ wassert (_ crt_wide (# _ expression), _ crt_wide (_ file _), _ line _), 0 )) # Endif /* Ndebug */

 

I don't know. Are there any books dedicated to the source code of the GCC compiler? I know there is a GCC internal, which is an English version. It seems useless. Does anyone know such a book in Chinese;

the man did not give me any advice. He told me a book like this, or a forum like this. I haven't found a consensus for a long time.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.