The use of macros in C + + common sense

Source: Internet
Author: User

The process of preprocessing (#include, #if, #define), compiling, assembling, and linking is the process of the C + + from editing to generating the target file, and macro substitution is occurring in preprocessing, and the macro substitution does not do any grammar checking. The context may be different when replaced by macro, so it is required to wrap the variables that exist in the macro substitution process in parentheses to avoid ambiguity and try not to use the auto-increment operator in the macro.

First, use # in the Macro and # #

Description: "#" strings the arguments in the macro, "# #" connects 2 tokens to 1

//the size of the output class#defineOut_class_size (_class) do{\cout<< #_Class <<"size is:"<<sizeof(_class) <<Endl;} while(0);//gets the type of the base class#defineGetclassbase (type) C # #type # #Bassclasschousebass{};classChouse: Publicchousebass{};//the above defines 2 classes, Chouse inherits from Chousebass, where a base class object is defined using the Getclassbase macroGetclassbase (house) housebassobj;

Third, the use of the macro in the string

In demon, which calls SQLite using C + +, the macro substitution is written to a string, but runs at a time inconsistent with expectations.
Look at the code first:

#define _var_arg_20#define _var_arg_40 (+)#define _var_arg_spec   (20-30)  Char"Target Pin[_var_arg_20]:value[_var_arg_40]:spec[_var_arg_spec]";

Compile no problem, when running, the individual macros in STR are not replaced. The first reaction is that the macro is replaced at the time of precompilation, and there should be no problem. Later, when you think about it, char * is actually a string stored in a static store, its essence is an rvalue, it is not allowed to be modified, and its creation is done before pre-compilation, and the macros in the string are treated as normal strings are not replaced.

If you want to implement a string substitution, you can use the # number to concatenate a string with a macro.
You can also replace a macro with a placeholder, and then use a macro to replace the placeholder to achieve the purpose using the format character method.

Second, the use of macro in the internationalization of language
//the first version of language internationalization//Chinese, Englishenum_en_language{elanguage_chinese =0, Elanguage_english};_en_language g_enlanguage=Elanguage_english;#defineDefstring (NO,EN,CN) string String_language_no (GetLanguage ()? EN:CN);//equivalent to: String string_language_1101 ("Welcome to Luran ' s Home \ r \ n");Defstring (1101,"Welcome to Luran ' s Home \ r \ n","Welcome to Luzan's house \ r \ n")#defineGETSTRING (NO) string_language_no//the second version of the language internationalization: Compared to the first version is to define a global variable, the second version is defined as a string array,//and when you do not know the last language setting, you can use Elanguage_last to set the inheritance of the last language settingenum_en_language{elanguage_chinese =0, Elanguage_english,elanguage_last};_en_language g_enlanguage=Elanguage_english;#defineSetLanguage (language) do {if(Elanguage_last! =language) G_enlanguage=language;} while(0)#defineGetLanguage () g_enlanguage#defineDefstring (NO,EN,CN) static string string_id_# #no [Elanguage_last] = {EN,CN};#defineGETSTRING (NO) string_id_# #no [GetLanguage ()]defstring (1101,"Welcome to Luran ' s Home \ r \ n","Welcome to Luzan's house \ r \ n")intMain () {setlanguage (Elanguage_chinese); cout<< GETSTRING (1101). C_STR () <<Endl;    SetLanguage (Elanguage_english); cout<< GETSTRING (1101). C_STR () <<Endl;    GetChar (); return 0;}
Iv. the offset of the obtained class-member variable
#define OFFSET (structure, member) ((int) & ((structure*) 0)->member);

A typical example is the address of a class of member variables, such as the implementation of a linked list in the Linux kernel, to obtain the addresses of such objects.

V. Use ofdo{....}while (0)

Use do{....}while (0) to wrap the required code into a separate syntax unit that avoids multiple statements in case of an error

#define dosomething (x) x++;x*=2; if  (bOK) dosomething (x);  //  dosomething extension, because there are multiple statements between if and else, and no {} package, resulting in cheap error else  dootherthing ();

The use of Do{}while (0) can be very good to eliminate the above problems

#define dosome (x) do{\    x+ +;    X*=2; \  } while(0)

Six, the type of strong turn

The following code converts the specified address to an object of type CLASS_EX or a pointer to that object

#define ADDR_TO_CLASS_EX (P_ADDR) (* (class_ex*) (P_ADDR))
#define ADDR_TO_CLASS_EX (P_ADDR) (((class_ex*) (P_ADDR))

Vii. Prevention of spillage

#define Inc_val (val) (val = (val) +1 > (val))? (val) +1: (val))

Eight, return array number

#define Array_no (arr) ((sizeof (ARR)/sizeof (arr[0]))

Nine, macro debugging

/* (two underscores), corresponding to%d */    /* corresponds to%s */* for%s */*  corresponds to%s* /

The use of macros in C + + common sense

Related Article

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.