商务合作:179001057@qq.com

ISO-ANSI CC++ 预处理器测试文本

技术2022-05-11  0


某平台价值19860元的编程课程资料免费领取【点我领取】


ISO-ANSI C/C++ 预处理器测试文本

http://blog.csdn.net/huyansoft/archive/2009/04/01/4039976.aspx

 

A test file for my ISO C/C++ PreprocessorCopyright(c) 2008, HuYanAll rights reserved.

Trigraph------------------------------------------------------------------------------------------------------------------------

in normal textint a ??( ??) = ??< 1, 2, 3 ??>;    //equivalent to next lineint a [ ] = { 1, 2, 3 };

in preprocessing directives??=define MACRO_TRIGRAPH(a,b)  a ??=??= b    //equivalent to next line#define MACRO_TRIGRAPH(a,b)  a ## b

in comments/* ??=  ??)  ??!  ??(  ??'  ??>  ??/n  ??<  ??- */    //equivalent to next line/* #  ]  |  [  ^  }  /n  {  ~ */

in backslashch??/ar* s="string ??/literal";

equivalent toch/ar* s="string /literal";

and equivalent tochar* s="string literal";

Backslash------------------------------------------------------------------------------------------------------------------------

in normal textch/ar* s="string /literal";

equivalent tochar* s="string literal";

in preprocessing directives#/defi/ne MACRO_/BACKSLASH/(a,b)  a #/# b

equivalent to#define MACRO_BACKSLASH(a,b)  a ## b

in comments//a single-/line comment

///a single-line comment

//*a multi-line comment*//

in the end of filenext backslash is unexpected if it is the last character of this file/

next backslash is unexpected if next newline is the end of this file/

Single-line comment-----------------------------------------------------------------------------------------------------------------------

in characters constant and string literal'a//b'    //a characters constant, not syntax error"a//b"    //4 characters string literal, not syntax error

between tokens (replacement to a space)m=n//**/o     //equivalent to m=n , not equivalent to m=n/o

in header name (error)#include <file.h//>    //undefined behavior, not equivalent to #include <file.h>#include "file.h//"    //undefined behavior, not equivalent to #include <file.h>

attempt defined it as macro (error)#define SINGLE_LINE_COMMENT // SINGLE_LINE_COMMENT abc    //error, 'abc' not comment

#define GLUE(x,y) x##yGLUE(/,/) abc     //error, 'abc' not comment

Multi-line comment------------------------------------------------------------------------------------------------------------------------

in characters constant and string literal'a//b'    //a characters constant, not syntax error"a/**/b"    //6 characters string literal, not syntax error

between tokens (replacement to a space)/**/#/**/define/**/MACRO_COMMENT/**/replacement/**/list/**/    //equivalent to next line # define MACRO_COMMENT replacement list

within punctuator or identifier (error)i+/**/+    //equivalent to i+ +, not equivalent to i++#incl/**/ude <file.h>    //error, equivalent to #incl ude <file.h>

in header name (error)#include <file.h/**/>    //undefined behavior, not equivalent to #include <file.h>#include "file.h/**/"    //undefined behavior, not equivalent to #include <file.h>

nesting/*****************************/    //ok/* // */    //ok,a multi-line comment/* /**/ */    //error, multi-line comments do not nest ('*/' found outside of comment)

//    /**/    //error, '*/' found outside of comment

//attempt defined it as macro (error)#define BEGIN_COMMENT /*#define END_COMMENT */BEGIN_COMMENT abc END_COMMENT    //error, 'abc' not comment

Identifier----------------------------------------------------------------------------------------------------------------------------------

_ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz    //an identifier/u1234_/uABCD_/U00001234_/U0000abcd    //an identifier (contains universal character names)

Preprocessing operator or punctuator--------------------------------------------------------------------------------------------------------

parsing>>=++++    //three punctuators, '>>=' and two '++'x+++++y    //parsed as x ++ ++ + y (although this expression is invalid), not x ++ + ++ y

reserved operator#define delete DELETE   //error, 'delete' is an operator in C++, not an identifier

Preprocessing number------------------------------------------------------------------------------------------------------------------------

familiar123L   //valid preprocessing number, a long integer.123   //valid preprocessing number, a floating number0123   //valid preprocessing number, a octal number0x123abc   //valid preprocessing number, a hexadecimal number3.14e10   //valid preprocessing number3.14e+10   //valid preprocessing number3.14E-10   //valid preprocessing number

definition123.456._.abc.ABC.e+.e-.E+.E-    //valid preprocessing number.123.456._.abc.ABC.e+.e-.E+.E-    //valid preprocessing number./u1234_/uABCD_/U00001234_/U0000abcd    //a preprocessing number (contains universal character names)

+123    //not a preprocessing number-123    //not a preprocessing number123+    //not a preprocessing number123-    //not a preprocessing number

importance#define X123  4560X123    //'X123' is not an identifier and will not be expanded, because '0X123' is a preprocessing number

Header name-------------------------------------------------------------------------------------------------------------------------------

parsing#include <file.h>=        //'>=' is not a punctuator because <file.h> is a header namea < b && c > d        //< b && c > is not a header name#if a < b && c > d        //< b && c > is not a header name#endif

matching#include <file.h    //error, missing matched separator#include "file.h    //error, missing matched quotes#include L"file.h"    //error, unexpected 'L'

unexpected characters in header names#include <' / " // /* >    //undefined behavior#include " ' /  // /* "    //undefined behavior

processing before string connecting#define BASE_NAME "file"#define EXTEND_NAME ".h"#include BASE_NAME EXTEND_NAME    //equivalent to #include "file" ".h" , but not equivalent to #include "file.txt"

Character constant------------------------------------------------------------------------------------------------------------------------

empty character (error)''    //errorL''    //error

matching'    //error, missing matched single-quotesL'    //error, missing matched single-quotes'abc/'    //error, missing matched single-quotes, /' is only a escape sequenceL'abc/'    //error, missing matched single-quotes, /' is only a escape sequence

escape sequences'/a /b /f /n /r /t /v /' /" /? //'    //valid escape sequences'/c /d /e / /+'    //invalid escape sequences' ? " '    //ok, may represented by ' /? /" '

value range of escape sequences'/400'    //error, too large value of octal escape sequence'/377'    //okL'/777'    //ok

'/x100'    //error, too large value of hexadecimal escape sequence'/xff'   //okL'/x10000'    //error, too large value of escape hexadecimal sequenceL'/xffff'    //ok

String literal----------------------------------------------------------------------------------------------------------------------------

empty string""    //okL""    //ok

matching"    //error, missing matched quotesL"    //error, missing matched quotes"abc/"    //error, missing matched quotes, /" is only a escape sequenceL"abc/"   //error, missing matched quotes, /" is only a escape sequence

escape sequences"/a /b /f /n /r /t /v /" /" /? //"    //valid escape sequences"/c /d /e / /+"    //invalid escape sequences" ? ' "    //ok, may represented by " /? /' "

value range of escape sequences"/400"    //error, too large value of octal escape sequence"/377"    //okL"/777"    //ok

"/x100"    //error, too large value of hexadecimal escape sequence"/xff"   //okL"/x10000"    //error, too large value of escape hexadecimal sequenceL"/xffff"    //ok

Universal character name-----------------------------------------------------------------------------------------------------------------------

within identifier/u1234_/uABCD_/U00001234_/U0000abcd    //valid

within character constant'/u1234_/uABCD_/U00001234_/U0000abcd'    //valid

within string literal"/u1234_/uABCD_/U00001234_/U0000abcd"    //valid

within preprocessing number./u1234_/uABCD_/U00001234_/U0000abcd    //valid

value range/u0065_/U00000065    //error, a universal character name cannot designates a basic source character (uncompleted)'/u0065 /U00000065'    //error, a universal character name cannot designates a basic source character (uncompleted)"/u0065 /U00000065"    //error, a universal character name cannot designates a basic source character (uncompleted)./u0065_/U00000065    //error, a universal character name cannot designates a basic source character (uncompleted)

/u0019_/u007f_/u009f_/U00000019_/U0000007f_/U0000009f    //error, a universal character name cannot less than 0x20, or in the range 0x7F-0x9F'/u0019 /u007f /u009f /U00000019 /U0000007f /U0000009f'    //error, a universal character name cannot less than 0x20, or in the range 0x7F-0x9F"/u0019 /u007f /u009f /U00000019 /U0000007f /U0000009f"    //error, a universal character name cannot less than 0x20, or in the range 0x7F-0x9F./u0019_/u007f_/u009f_/U00000019_/U0000007f_/U0000009f    //error, a universal character name cannot less than 0x20, or in the range 0x7F-0x9F

Preprocessing directive and normal text--------------------------------------------------------------------------------------------------------

null directive#    //no effect

normal text#define EMPTYEMPTY #include <file.h>    //a text line, will expend to #include <file.h> but not a preprocessing directive

#define INCLUDE1 #include <file.h>INCLUDE1    //a text line, will expend to #include <file.h> but not a preprocessing directive

#define INCLUDE2 #includeINCLUDE2 <file.h>    //a text line, will expend to #include <file.h> but not a preprocessing directive

directive name#define INCLUDE3 include <file.h>#INCLUDE3    //error, nonexistent directive name

#define INCLUDE4 include#INCLUDE4 <file.h>    //error, nonexistent directive name

#define pragma error#pragma "abc"    //the directive name is 'pragma' but not 'error', because the replacement was not occured

Source file inclusion---------------------------------------------------------------------------------------------------------------------------

#define MAKE_HEADER(s) #s#include MAKE_HEADER(file.h)     //ok, macro expanded, the header name is "file.h"

//#include "stdio.h"    //working but warning

//#line __LINE__ "new.h"    //next line is error even if current line is reserved#include "test.txt"    //error, cannot include itselt, though current file name was modified to "new.h" by last line

#include "b.txt"    //begin a recursive inclusion, b.txt and c.txt will include each other

Conditional inclusion---------------------------------------------------------------------------------------------------------------------------

syntax checking in skipped groups#if 0                            //checking carefully and responsibly even if in skipped groups    "abc                         //fogot a quotes    '/400'                       //too large value of octal escape sequence    #include <d:/file.h>         //unexpected '/' character    #define PI3.14               //forgot spaces after PI    #define MAX(a,a)  a>b?a:b    //careless spelling of second parameter    #define defined otherwise    //do not know identifier 'defined' is reserved    #line "file.h" 100           //two arguments reversed#elsc                            //careless spelling, follow lines before #endif will be ignored unecpectly    #define PI 3.14              //ignored unecpectly#endif

unreplaced macros#define UNREPLACED something

#ifdef UNREPLACED    //UNREPLACED will not be expanded#endif

#ifndef UNREPLACED    //UNREPLACED will not be expanded#endif

#if defined(UNREPLACED)    //UNREPLACED will not be expanded#elif defined(UNREPLACED)    //UNREPLACED will not be expanded#endif

matching#endif    //error, missing matched 'if' branch#else    //error, missing matched 'if' branch#elif 1    //error, missing matched 'if' branch

#if 0#elif 0#else//#elif 0    //error if this line reserved, 'elif' branch shall not occur after 'else' branch#endif    //dismatch if this line is removed

branch testing#define A#ifndef A #ifdef B  a if #elif 0  a elif a #elif 1  a elif b #else  a else #endif#elif 0 #ifdef b  b if #elif 0  b elif a #elif 1  b elif b #else  b else #endif#elif 1 #ifdef c  c if #elif 0  c elif a #elif 1  c elif b #else  c else #endif#else #ifdef d  d if #elif 1  d elif a #elif 1  d elif b #else  d else #endif#endif

Macro definition-----------------------------------------------------------------------------------------------------------------------------

white separator#define PI3.14    //invalid directive format, forgeting space after macro name#define PI()3.14    //invalid directive format, forgeting space after ')'#define MACRO_MAX (a,b) ((a)>(b)?(a):(b))    //will be defined as object-like macro, not function-like macro

redefinition#define ERR_PARA(a,a)  something        //error, parameter 'a' redefined

#define OBJECT_LIKE something#define OBJECT_LIKE() something    //error, cannot redefine object-like macro as function-like macro

#define FUNCTION_LIKE() something#define FUNCTION_LIKE something    //error, cannot redefine function-like macro as object-like macro

#define OBJ_LIKE (1)#define OBJ_LIKE (0)    //error, redefine with different token sequence in replacement list

#define FUNC_LIKE(a) something#define FUNC_LIKE(b) something    //error, redefine with different parameter list

#define MACRO_CONNECT(a,b,c) a##b##c#define MACRO_CONNECT( a , b , c )  a ## b ## c    //ok, the same definition to MACRO_CONNECT (uncompleted)

Macro invocation and replacement-----------------------------------------------------------------------------------------------------------------------------

#define MULTI_ARGS(a,b) b,aMULTI_ARGS    //valid text, but not a macro invocation

arguments numberMULTI_ARGS()    //warning, not enough argumentsMULTI_ARGS(1,)    //valid, the second argument is emptyMULTI_ARGS(,2)    //valid, the first argument is emptyMULTI_ARGS(,)    //valid, both arguments are emptyMULTI_ARGS(1,2,3,4)    //valid, though arguments too much

whites (spaces, tabs and newlines) within argumentsMULTI_ARGS (    //valid, though whites involved  1  ,    2  )

quotes matching//MULTI_ARGS(a,b    //error, missing matched ')'//MULTI_ARGS( isdigit(32), isdigit(65)    //error, missing matched ')'MULTI_ARGS( isdigit(32), isdigit(65) )    //valid, four middle parentheses skippedMULTI_ARGS( MULTI_ARGS(1,2), MULTI_ARGS(3,4) )    //valid, nesting invocation (will expand to 4,3,2,1)MULTI_ARGS(    1,    #define PI 3.14    //error, preprocessing directives cannot occur within a macro invocation    )

replacement time#define MACROX 2#define MACROY MACROX    //MACROX does not replaced to 2 now#undef  MACROX#define MACROX 3int i=MACROY;    //replacement occurs, MACROY will expanded to 3 but not 2

The # operator (string making)----------------------------------------------------------------------------------------------------------------

definition#define ERR_JIN1(a) #    //error, # should be followed by a parameter in the replacement list of a function-like macro (uncompleted)#define ERR_JIN2(a) a#b    //error, # should be followed by a parameter in the replacement list of a function-like macro (uncompleted)

whites (spaces, tabs and newlines) within arguments#define MKS(s) #sMKS(abc)    //expands to "abc"MKS(  abc  )    //expands to "abc", whites before the first token and after the last token within the argument is deletedMKS(abc)    //expands to "abc", (uncompleted)MKS(  a    b    c  )    //expands to "a b c", each white within the argument becomes a single space

arguments substitution#define S1(s) #s#define S2(s) S1(s)#define MYNAME huyanS1( MYNAME )    //expands to "MYNAME"S2( MYNAME )    //expands to "huyan"

#define FORMAT(x) #x "=%d/n",x#define MYNUM 100printf( FORMAT(MYNUM) )    //expands to printf( "MYNUM" "=%d/n",100 ), not printf( "100" "=%d/n",100 )

making valid string literal#define S3(s) #sprintf("%s", S3(a/nb "a/nb" // '//' /n '/n'));    //expands to next lineprintf("%s", "a/nb /"a//nb/" // '' /n '//n'");    //not next sick line//printf("%s", "a/nb "a/nb" // '//' /n '/n'");    //error, dismatched quotes

The ## operator (token connection)------------------------------------------------------------------------------------------------------------

definition#define ERR_JINJIN1(a) ## a    //error, ## cannot occur at the beginning of the replacement list#define ERR_JINJIN2(a) a ##    //error, ## cannot occur at the end of the replacement list

#define hash_hash1 ##    //error, cannot define ## to a macro directly#define hash_hash2 # ## #    //okhash_hash2    //expands to ##

arguments substitution#define CONNECT(x) I ## x#define CONNECT2(x) CONNECT(x)#define S(a) a#define IS(a) aint I2=5;CONNECT( S(1) )    //expands to IS(1), and further expands to 1CONNECT2( S(2) )    //expands to CONNECT2( 2 ), further expands to CONNECT( 2 ), and last expands to I2

example from ISO C Standard#define hash_hash # ## ##define mkstr(a) # a#define in_between(a) mkstr(a)#define join(c, d) in_between(c hash_hash d)char p[] = join(x, y);    //equivalent to char p[] = "x ## y";

Complex macro replacement (rescanning and further replacement)---------------------------------------------------------------------------------

#define MACROS(a) a#define MACROT(b) b*bMACROS ( MACROT ) ( 3 )    //expands to 3*3

int M1=3;#define M1 M2#define M2 M1*M1    //recursive definitionprintf("%d/n",M1);    //expands to M1*M1 and output 9

#define Puts(s)  printf("%s is ",#s); Puts(s)char translator[]={-70,-6,-47,-27,0};Puts(translator);    //expands to  printf("%s is","translator"); Puts(translator);

example from ISO C Standard#define X       3#define F(a)    F(X  *  (a))#undef  X#define X       2#define G       F#define Z       Z[0]#define H       G(~#define M(a)    a(W)#define W       0,1#define T(a)    a#define P()     int#define Q(x)    x#define R(x,y)  x ## y#define STR(x)  # x

F(y+1) + F(F(Z)) % T(T(G)(0) + T) (1);                //expands to F(2 * (y+1)) + F(2 * (F(2 * (Z[0])))) % F(2 * (0)) + T(1);G(X+(3,4)-W) | H 5) & M(F)^M(M);                      //expands to F(2 * (2+(3,4)-0,1)) | F(2 * (~ 5)) & F(2 * (0,1))^M(0,1);P() i[Q()] = { Q(1), R(2,3), R(4,), R(,5), R(,) };    //expands to int i[] = { 1, 23, 4, 5,  };char c[2][6] = { STR(hello), STR() };                 //expands to char c[2][6] = { "hello", "" };

#define Str(s) # s#define Xstr(s) Str(s)#define Debug(s, t) printf("x" # s "= %d, x" # t "= %s", x ## s, x ## t)#define INCFILE(n) vers ## n#define Glue(a, b) a ## b#define Xglue(a, b) Glue(a, b)#define HIGHLOW "hello"#define LOW LOW ", world"

Debug(1, 2);                                                      //expands to printf("x" "1" "= %d, x" "2" "= %s", x1, x2);fputs(Str(strncmp("abc/0d", "abc", '/4') == 0) Str(: @/n), s);    //expands to fputs("strncmp(/"abc//0d/", /"abc/", '//4') == 0" ": @/n",s);#include Xstr(INCFILE(2).h)                                       //expands to #include "vers2.h"Glue(HIGH, LOW);                                                  //expands to "hello";Xglue(HIGH, LOW)                                                  //expands to "hello" ", world"

Macro with variable arguments-----------------------------------------------------------------------------------------------------------------------

definition#define ERR_VAM1  __VA_ARGS__    //error, unexpected __VA_ARGS__ in the replacement list of normal macro#define ERR_VAM2(a,b,c) __VA_ARGS__     //error, unexpected __VA_ARGS__ in the replacement list of normal macro#define ERR_VAM3(a,b,c,...) a,b,c       //warning, missing __VA_ARGS__ in the replacement list of variable arguments macro

#define ERR_VAM4(__VA_ARGS__) something     //error, the parameter cannot be __VA_ARGS__#define ERR_VAM5(__VA_ARGS__,...) __VA_ARGS__     //error, the parameter cannot be __VA_ARGS__

#define __VA_ARGS__  otherwise    //error, the identifier '__VA_ARGS__' is reserved#undef __VA_ARGS__    //error, the identifier '__VA_ARGS__' is reserved

#define VAM1(...)  __VA_ARGS__    //ok#define VAM2(a,b,c,...) __VA_ARGS__    //ok

arguments substitution#define VAM3(...)  #__VA_ARGS__VAM3()    //expands to ""VAM3(1)    //expands to "1"VAM3(a,b,c)    //expands to "a,b,c"

#define VAM4(a,b,...) a b #__VA_ARGS__VAM4(1)    //warning, not enough argumentsVAM4(1,2)    //expands to 1 2 ""VAM4(1,2,3,4,5)    //expands to 1 2 "3,4,5"VAM4( ((a), (b)), ((c), (d)), ((e),(f)), ((g),(h)) )    //expands to ((a), (b)) ((c), (d)) "((e),(f)), ((g),(h))"

example from ISO C Standard#define Debug2(...) fprintf(stderr, __VA_ARGS__)#define Showlist(...) puts(#__VA_ARGS__)#define Report(test, ...) ((test)?puts(#test):printf(__VA_ARGS__))

Debug2("Flag");                                   //expands to fprintf(stderr, "Flag" );Debug2("x = %d/n", x);                            //expands to fprintf(stderr, "x = %d/n", x );Showlist(The first, second, and third items.);    //expands to puts( "The first, second, and third items." );Report(x>y, "x is %d but y is %d", x, y);         //expands to ((x>y)?puts("x>y"):printf("x is %d but y is %d", x, y));

Predefined macro names and reserved identifiers------------------------------------------------------------------------------------------------

following predefined macros will be expanded__DATE____FILE____LINE____STDC____STDC_HOSTED____STDC_VERSION____TIME__

redefine and undefine (error)#define __DATE__  otherwise       //error, cannot redefine predefined macros#define defined  otherwise        //error, the identifier 'defined' is reserved

#undef __DATE__       //error, cannot undefine predefined macros#undef defined        //error, the identifier 'defined' is reserved

Line control-----------------------------------------------------------------------------------------------------------------------------------

//#line 100    //set next line number to 100//#line 200 "file1.h"    //set next line number to 200 and current file name to "file1.h"

expanded macro arguments#define LINE_NUMBER1 300//#line LINE_NUMBER1    //set next line number to 300 (the macro LINE_NUMBER1 expanded)

#define LINE_NUMBER2 400//#line LINE_NUMBER2 "file2.h"    //set next line number to 400 and current file name to "file2.h"

#define FILE_NAME "file3.h"//#line 500 FILE_NAME    //set next line number to 500 and current file name to "file3.h"

#define LINE_FILE 600 "test.h"//#line LINE_FILE    //set next line number to 600 and current file name to "test.h"

arguments format#line 0    //error, the line number cannot less than 1#line 2147483648    //error, the line number cannot more than 2147483647#line +100    //error, the line number need not prefixed by '+' or '-'#line "file.h" 100    //error, the first argument shall be a number (after macro replacement)#line 100  L"file.h"    //error, the file name need not prefixed by 'L' (cannot be wide string literal)//#line 100  "file.h/"    //error, missing matched quotes, the /" is only a escape sequence

counting of line number//#line 100    //set next line number to 100, but next broken '__LINE__' will expands to 101__LINE/__ ;

Error directive------------------------------------------------------------------------------------------------------------------------------

//#error    //stop preprocessing//#error message1    //stop preprocessing and output 'message1'

expanded macro arguments#define MESSAGE2 message2//#error MESSAGE2    //macro expanded, stop preprocessing and output 'message2'

#define MAX_VALUE 100//#error the "MAX_VALUE" cannot more than MAX_VALUE    //stop preprocessing and output 'the "MAX_VALUE" cannot more than 100'

Pragma directive-----------------------------------------------------------------------------------------------------------------------------

#pragma some_instructions    //valid, but all #pragma directives will be ignored and removed

_Pragma operator (uncompleted)_Pragma ("string literal")    //it will regard as normal text

[The End]


最新回复(0)