Repeat the classic-Objective C ++ item2: replace const, Enum, and inline as much as possible # define

Source: Internet
Author: User

Blog (http://blog.csdn.net/livelylittlefish
) Post the notes prepared by the author (@ Xiaoyu) on the relevant research and study content. You are welcome to correct them!

 

1. macro definition

 

# Define aspect_ratio 1.653

The macro definition aspect_ratio may never be seen by the compiler, and may be replaced by the pre-processor before the compiler starts to process the source code. We know that the macro definition will be replaced with a string in the preprocessing phase, and any part of aspect_ratio will be replaced with 1.653. Therefore, aspect_ratio does not enter the symbol table.

 

Symbol table Review

 

(1) What is a symbol table? What are the important functions of a symbol table?

A symbolic table is a table used to record various information during compilation.

Role of the symbol table:

  • Register the input and output information of the compilation process
  • Used for semantic check and intermediate code generation during Semantic Analysis
  • As the basis for Address Allocation in the generation phase of the target code

 

(2) What are the common parts of a symbol table? What are their descriptions?

The table items in the symbol table contain two columns: The name column and the information column;

The name column is also called the main column, and the identifier for storing the name is called a keyword;

The information column contains many sub-columns and flag spaces, which are used to record different attributes of the corresponding name.

 

(3) How do I organize a symbol table? What factors does the Organization depend on?

The organization of a symbol table is divided into two types: direct organization and indirect organization.

Items in the direct organization mode are stored in a fixed length order;

In indirect organization, the main column of the symbol table stores an indicator and an integer (start position and length of the identifier) of the identifier, and the string of the identifier is stored in a string array.

 

The organization of the symbol table depends on the following factors:

  • Whether the storage unit and length of each column in the table item are fixed
  • Length limit of the identifier in a language
  • Which items have common values?
  • Operation and usage of symbol tables

 

(4) How can I view the executable program symbol table on Win32 and Linux platforms?

  • Win32 platform

Dumpbin command

For example,> dumpbin/Symbols filename (where> is a command line prompt)

  • Linux platform

Objdump command

For example, # objdump-s filename (where # is a command line prompt)

 

Therefore, when compilation errors occur in 1.653, it is difficult to figure out the problem. In addition, during the debugging stage, it is also difficult to locate (we cannot find the defined macro value during debugging through visual stiduo or GDB on Linux, because the symbol table does not have this symbol ), therefore, the macro definition cannot be seen as WYSIWYG. You must check the code to understand the macro definition.

 

So how can we solve it? As follows.

 

2. Use const to define Constants

 

For example, the macro defined in define can be changed:

Const double aspectratio = 1.653; // an upper-case name is usually used for macros.

 

From the above, we can see that the constant has a type, which is double. As a language constant, it will certainly be seen by the compiler, and of course it will enter the symbol table. You can also check the value of this constant during debugging.

 

3. exclusive class Constants

 

If you limit the scope of a constant to a class, you must make it a member of the class ). To ensure that this constant has at most one entity, you must make it a static member.

 

For example, the following program can describe the definition method of the class exclusive constant.

[C-sharp]
View plaincopy
  1. /**
  2. * <Valid tive C ++>, page 14
  3. * Const data of class
  4. * Platform: Visual Studio 2005, Win32
  5. * Filename: item2.1.cpp
  6. */
  7. # Include <iostream>
  8. Using namespace STD;
  9. Class mytest
  10. {
  11. // (1) Error c2864: 'mytest: maxnumber1': only static const integral data members can be initialized within a class
  12. // Int maxnumber1 = 5;
  13. // (2) Error c2864: 'mytest: maxnumber2': only static const integral data members can be initialized within a class
  14. // Const int maxnumber2 = 5;
  15. // (3) Error c2864: 'mytest: maxnumber3': only static const integral data members can be initialized within a class
  16. // Static int maxnumber3 = 5;
  17. // (4) OK
  18. Static const int maxnumber4 = 5;
  19. Static const char cconst4 = 'B ';
  20. // (5) Error c2864: 'mytest: dconst4': only static const integral data members can be initialized within a class
  21. // Static const double dconst4 = 200.00;
  22. Public:
  23. // (6) Error c2758: 'mytest: maxnumber2': Must be initialized in constructor base/member initializer list
  24. Mytest ()
  25. {
  26. Cout <"mytest constructor! "<Endl;
  27. Cout <"maxnumber4 =" <maxnumber4 <Endl;
  28. Cout <"cconst4 =" <cconst4 <Endl;
  29. }
  30. };
  31. Int main ()
  32. {
  33. Mytest OBJ;
  34. Return 0;
  35. }

 

 

(1), (2), (3) in the code comment indicates the step number.

From (1), (2), (3), we can see that only static const Integral Data member (static integer constant data member) can be initialized in the class. It can also be proved from (4) and (5. The char type is equivalent to an integer.

 

The running result is as follows.

Mytest constructor!

Maxnumber = 5

Cconst1 =

Cconst2 = B

Dconst1. = 100

 

Another example is.

[C-sharp]
View plaincopy
  1. /**
  2. * <Valid tive C ++>, page 14
  3. * Const data of class
  4. * Platform: Visual Studio 2005, Win32
  5. * Filename: item2.2.cpp
  6. */
  7. # Include <iostream>
  8. Using namespace STD;
  9. Class mytest
  10. {
  11. Int maxnumber1;
  12. Const int maxnumber2;
  13. Static int maxnumber3;
  14. Static const int maxnumber4 = 5;
  15. Static const char cconst4 = 'B ';
  16. Static const int maxnumber5;
  17. Public:
  18. // (1) Error c2758: 'mytest: maxnumber2': Must be initialized in constructor base/member initializer list
  19. // (4) Error c2438: 'maxnumber3': Cannot initialize static class data via Constructor
  20. // (7) Error c2438: 'maxnumber5': Cannot initialize static class data via Constructor
  21. Mytest (): maxnumber1 (5), maxnumber2 (5) //, maxnumber5 (5) //, maxnumber3 (5)
  22. {
  23. // (2) Error c2166: L-value specifies const object
  24. // Maxnumber2 = 5;
  25. // (3) Error lnk2001: unresolved external symbol "Private: static int mytest: maxnumber3 "(? Maxnumber3 @ mytest @ 0HA)
  26. // Maxnumber3 = 5;
  27. // (6) Error c3892: 'maxnumber5': you cannot assign to a variable that is const
  28. // Maxnumber5 = 5;
  29. Cout <"mytest constructor! "<Endl;
  30. Cout <"maxnumber1 =" <maxnumber1 <Endl;
  31. Cout <"maxnumber2 =" <maxnumber2 <Endl;
  32. Cout <"maxnumber3 =" <maxnumber3 <Endl;
  33. Cout <"maxnumber4 =" <maxnumber4 <Endl;
  34. Cout <"maxnumber5 =" <maxnumber5 <Endl;
  35. Cout <"cconst4 =" <cconst4 <Endl;
  36. }
  37. };
  38. // (5) OK
  39. Int mytest: maxnumber3 = 5;
  40. // (8) OK
  41. Const int mytest: maxnumber5 = 5;
  42. // (9) Error c2761: 'int mytest: maxnumber1': member function redeclaration not allowed
  43. // Int mytest: maxnumber1 = 5;
  44. Int main ()
  45. {
  46. Mytest OBJ;
  47. Return 0;
  48. }

 

 

The running result is as follows.

Mytest constructor!

Maxnumber1 = 5

Maxnumber2 = 5

Maxnumber3 = 5

Maxnumber4 = 5

Maxnumber5 = 5

Cconst4 = B

 

(1), (2), (3) in the code comment indicates the step number.

From (1), (2) We can see that non-static constant data members must be initialized in the constructor's initialization list. If they are initialized in the constructor, the error c2166 may occur, that is, the constant object is read-only (read only) and cannot be assigned a value.

 

From (3), (4), (5), we can see that the static extraordinary data members can only be initialized outside the class (implementation file of the class.

We can see from (6), (7), and (8) that static constant data members can also be initialized outside the class (implementation file of the class.

Conclusion:

  • Static constant data members can be initialized within the class (that is, they can be declared at the same time), or they can be initialized outside the class, that is, in the class implementation file, and cannot be initialized in the constructor, it cannot be initialized in the initialization list of the constructor;
  • Static extraordinary data members can only be initialized in the class implementation file outside the class. They cannot be initialized in the constructor or in the constructor initialization list;
  • Non-static constant data members cannot be initialized in the class or in the constructor, but must be initialized only in the constructor initialization list;
  • Non-static non-constant data members cannot be initialized in the class. They can be initialized in the constructor or in the constructor initialization list;

 

Summary:

Type Initialization Method

Class (Declaration)

Out-of-class (class implementation file)

Constructor

List of constructor Initialization

Non-static extraordinary data member

N

N

Y

Y

Non-static constant data member

N

N

N

Y (must)

Static extraordinary data member

N

Y (must)

N

N

Static constant data member

Y

Y

N

N

 

4. Exclusive constants of class of Enum type

 

All data members of the above 4 types have their own initialization methods. The only column is that a class constant is required during the class compilation, except for static constant data members, you can also use data of the enum type, that is, use the so-called "The Enum hack" compensation method. The theoretical basis is "an enumerated type) the value of can be used as an integer ". For example,

 

Class mytest

{

PRIVATE:

Enum {maxnumber = 5}; // "The Enum hack" makes maxnumber a mark name of 5

Int score [maxnumber];

 

};

 

The behavior of Enum hack is more like # define than Const. For example, you can get a const address, not an Enum address, or a # Define address;

 

5. Use inline function instead of Macro function

 

(Template) benefits of the inline function:

  • Obtain the efficiency of macros (macros do not have additional overhead for function calls)
  • Type Safety)

 

 

Remember

For constants, it is best to replace # defines with a const object or enum;

Replace # defines with the inline function for macro (macros) Like a function.

 

Note: This program can also be run on Linux.

Blog (http://blog.csdn.net/livelylittlefish
) Post the notes prepared by the author (@ Xiaoyu) on the relevant research and study content. You are welcome to correct them!

 

1. macro definition

 

# Define aspect_ratio 1.653

The macro definition aspect_ratio may never be seen by the compiler, and may be replaced by the pre-processor before the compiler starts to process the source code. We know that the macro definition will be replaced with a string in the preprocessing phase, and any part of aspect_ratio will be replaced with 1.653. Therefore, aspect_ratio does not enter the symbol table.

 

Symbol table Review

 

(1) What is a symbol table? What are the important functions of a symbol table?

A symbolic table is a table used to record various information during compilation.

Role of the symbol table:

  • Register the input and output information of the compilation process
  • Used for semantic check and intermediate code generation during Semantic Analysis
  • As the basis for Address Allocation in the generation phase of the target code

 

(2) What are the common parts of a symbol table? What are their descriptions?

The table items in the symbol table contain two columns: The name column and the information column;

The name column is also called the main column, and the identifier for storing the name is called a keyword;

The information column contains many sub-columns and flag spaces, which are used to record different attributes of the corresponding name.

 

(3) How do I organize a symbol table? What factors does the Organization depend on?

The organization of a symbol table is divided into two types: direct organization and indirect organization.

Items in the direct organization mode are stored in a fixed length order;

In indirect organization, the main column of the symbol table stores an indicator and an integer (start position and length of the identifier) of the identifier, and the string of the identifier is stored in a string array.

 

The organization of the symbol table depends on the following factors:

  • Whether the storage unit and length of each column in the table item are fixed
  • Length limit of the identifier in a language
  • Which items have common values?
  • Operation and usage of symbol tables

 

(4) How can I view the executable program symbol table on Win32 and Linux platforms?

  • Win32 platform

Dumpbin command

For example,> dumpbin/Symbols filename (where> is a command line prompt)

  • Linux platform

Objdump command

For example, # objdump-s filename (where # is a command line prompt)

 

Therefore, when compilation errors occur in 1.653, it is difficult to figure out the problem. In addition, during the debugging stage, it is also difficult to locate (we cannot find the defined macro value during debugging through visual stiduo or GDB on Linux, because the symbol table does not have this symbol ), therefore, the macro definition cannot be seen as WYSIWYG. You must check the code to understand the macro definition.

 

So how can we solve it? As follows.

 

2. Use const to define Constants

 

For example, the macro defined in define can be changed:

Const double aspectratio = 1.653; // an upper-case name is usually used for macros.

 

From the above, we can see that the constant has a type, which is double. As a language constant, it will certainly be seen by the compiler, and of course it will enter the symbol table. You can also check the value of this constant during debugging.

 

3. exclusive class Constants

 

If you limit the scope of a constant to a class, you must make it a member of the class ). To ensure that this constant has at most one entity, you must make it a static member.

 

For example, the following program can describe the definition method of the class exclusive constant.

[C-sharp]
View plaincopy
  1. /**
  2. * <Valid tive C ++>, page 14
  3. * Const data of class
  4. * Platform: Visual Studio 2005, Win32
  5. * Filename: item2.1.cpp
  6. */
  7. # Include <iostream>
  8. Using namespace STD;
  9. Class mytest
  10. {
  11. // (1) Error c2864: 'mytest: maxnumber1': only static const integral data members can be initialized within a class
  12. // Int maxnumber1 = 5;
  13. // (2) Error c2864: 'mytest: maxnumber2': only static const integral data members can be initialized within a class
  14. // Const int maxnumber2 = 5;
  15. // (3) Error c2864: 'mytest: maxnumber3': only static const integral data members can be initialized within a class
  16. // Static int maxnumber3 = 5;
  17. // (4) OK
  18. Static const int maxnumber4 = 5;
  19. Static const char cconst4 = 'B ';
  20. // (5) Error c2864: 'mytest: dconst4': only static const integral data members can be initialized within a class
  21. // Static const double dconst4 = 200.00;
  22. Public:
  23. // (6) Error c2758: 'mytest: maxnumber2': Must be initialized in constructor base/member initializer list
  24. Mytest ()
  25. {
  26. Cout <"mytest constructor! "<Endl;
  27. Cout <"maxnumber4 =" <maxnumber4 <Endl;
  28. Cout <"cconst4 =" <cconst4 <Endl;
  29. }
  30. };
  31. Int main ()
  32. {
  33. Mytest OBJ;
  34. Return 0;
  35. }

 

 

(1), (2), (3) in the code comment indicates the step number.

From (1), (2), (3), we can see that only static const Integral Data member (static integer constant data member) can be initialized in the class. It can also be proved from (4) and (5. The char type is equivalent to an integer.

 

The running result is as follows.

Mytest constructor!

Maxnumber = 5

Cconst1 =

Cconst2 = B

Dconst1. = 100

 

Another example is.

[C-sharp]
View plaincopy
  1. /**
  2. * <Valid tive C ++>, page 14
  3. * Const data of class
  4. * Platform: Visual Studio 2005, Win32
  5. * Filename: item2.2.cpp
  6. */
  7. # Include <iostream>
  8. Using namespace STD;
  9. Class mytest
  10. {
  11. Int maxnumber1;
  12. Const int maxnumber2;
  13. Static int maxnumber3;
  14. Static const int maxnumber4 = 5;
  15. Static const char cconst4 = 'B ';
  16. Static const int maxnumber5;
  17. Public:
  18. // (1) Error c2758: 'mytest: maxnumber2': Must be initialized in constructor base/member initializer list
  19. // (4) Error c2438: 'maxnumber3': Cannot initialize static class data via Constructor
  20. // (7) Error c2438: 'maxnumber5': Cannot initialize static class data via Constructor
  21. Mytest (): maxnumber1 (5), maxnumber2 (5) //, maxnumber5 (5) //, maxnumber3 (5)
  22. {
  23. // (2) Error c2166: L-value specifies const object
  24. // Maxnumber2 = 5;
  25. // (3) Error lnk2001: unresolved external symbol "Private: static int mytest: maxnumber3 "(? Maxnumber3 @ mytest @ 0HA)
  26. // Maxnumber3 = 5;
  27. // (6) Error c3892: 'maxnumber5': you cannot assign to a variable that is const
  28. // Maxnumber5 = 5;
  29. Cout <"mytest constructor! "<Endl;
  30. Cout <"maxnumber1 =" <maxnumber1 <Endl;
  31. Cout <"maxnumber2 =" <maxnumber2 <Endl;
  32. Cout <"maxnumber3 =" <maxnumber3 <Endl;
  33. Cout <"maxnumber4 =" <maxnumber4 <Endl;
  34. Cout <"maxnumber5 =" <maxnumber5 <Endl;
  35. Cout <"cconst4 =" <cconst4 <Endl;
  36. }
  37. };
  38. // (5) OK
  39. Int mytest: maxnumber3 = 5;
  40. // (8) OK
  41. Const int mytest: maxnumber5 = 5;
  42. // (9) Error c2761: 'int mytest: maxnumber1': member function redeclaration not allowed
  43. // Int mytest: maxnumber1 = 5;
  44. Int main ()
  45. {
  46. Mytest OBJ;
  47. Return 0;
  48. }

 

 

The running result is as follows.

Mytest constructor!

Maxnumber1 = 5

Maxnumber2 = 5

Maxnumber3 = 5

Maxnumber4 = 5

Maxnumber5 = 5

Cconst4 = B

 

(1), (2), (3) in the code comment indicates the step number.

From (1), (2) We can see that non-static constant data members must be initialized in the constructor's initialization list. If they are initialized in the constructor, the error c2166 may occur, that is, the constant object is read-only (read only) and cannot be assigned a value.

 

From (3), (4), (5), we can see that the static extraordinary data members can only be initialized outside the class (implementation file of the class.

We can see from (6), (7), and (8) that static constant data members can also be initialized outside the class (implementation file of the class.

Conclusion:

  • Static constant data members can be initialized within the class (that is, they can be declared at the same time), or they can be initialized outside the class, that is, in the class implementation file, and cannot be initialized in the constructor, it cannot be initialized in the initialization list of the constructor;
  • Static extraordinary data members can only be initialized in the class implementation file outside the class. They cannot be initialized in the constructor or in the constructor initialization list;
  • Non-static constant data members cannot be initialized in the class or in the constructor, but must be initialized only in the constructor initialization list;
  • Non-static non-constant data members cannot be initialized in the class. They can be initialized in the constructor or in the constructor initialization list;

 

Summary:

Type Initialization Method

Class (Declaration)

Out-of-class (class implementation file)

Constructor

List of constructor Initialization

Non-static extraordinary data member

N

N

Y

Y

Non-static constant data member

N

N

N

Y (must)

Static extraordinary data member

N

Y (must)

N

N

Static constant data member

Y

Y

N

N

 

4. Exclusive constants of class of Enum type

 

All data members of the above 4 types have their own initialization methods. The only column is that a class constant is required during the class compilation, except for static constant data members, you can also use data of the enum type, that is, use the so-called "The Enum hack" compensation method. The theoretical basis is "an enumerated type) the value of can be used as an integer ". For example,

 

Class mytest

{

PRIVATE:

Enum {maxnumber = 5}; // "The Enum hack" makes maxnumber a mark name of 5

Int score [maxnumber];

 

};

 

The behavior of Enum hack is more like # define than Const. For example, you can get a const address, not an Enum address, or a # Define address;

 

5. Use inline function instead of Macro function

 

(Template) benefits of the inline function:

  • Obtain the efficiency of macros (macros do not have additional overhead for function calls)
  • Type Safety)

 

 

Remember

For constants, it is best to replace # defines with a const object or enum;

Replace # defines with the inline function for macro (macros) Like a function.

 

Note: This program can also be run on Linux.

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.