Deep analysis of the differences between declarations and definitions in C + + _c language

Source: Internet
Author: User
Tags assert class definition static class

First, discuss the difference between the declaration and the definition.
The declaration is to introduce a name into the program. The definition provides a unique description of an entity in the program. declarations and definitions are sometimes present at the same time.

   such as int A;

   extern int b=1;

The declaration is only declared if there is no initialization in extern. Other situations are both definitions and declarations.

But in the following cases, the declaration is merely a declaration:

    1: Only provide function prototypes. such as void Func (int,int);

    2:extern int A;

    3:class A;

    4:typedef declaration

    5: Declaration of static data members defined in a class

Such as:

Class A 
{public 
  : 
  static int a;//declaration. 
};

The definition is simply defined in the following cases:

   1: Define and initialize a static data member outside of the class definition. such as a::a=0;

   2: Define a non-inline member function outside of the class.
A declaration is simply to introduce a symbol into a scope. The definition provides a unique description of an entity in the program. It is possible to repeatedly declare a symbol in a given domain, but it cannot be defined repeatedly, or it will cause a compilation error. However, member functions and static data members in a class are exceptions, although they are declarations within a class, but they cannot have more than one.

Such as:

Understand the difference between the declaration and the definition, but also need to understand the internal links, external links. Only when you understand them will you know the questions that are raised at the beginning.

At compile time, the compiler detects only program syntax and functions, and whether variables are declared. If the function is not declared, the compiler gives a warning, but the target file can be generated. When you link a program, the linker looks for the implementation of the function in all of the target files. If you can't find it, you'll report a link error code (Linker error). In VC, this error is generally: Link 2001 error, meaning is said, the linker failed to find the implementation of the function.

Links link The symbols generated by different compilation units. There are two ways of linking: internal links and external links.

If a symbolic name is local to its compilation unit, and it is not possible to conflict with the same name in other compilation units at the time of the link, that symbol is an internal link. Internal links mean that access to this symbol is limited to the current compilation unit and is not visible to other compilation units.

When the static keyword acts on a global variable, it represents a static global variable. However, the scope is only within the current file scope. Other files cannot be used even if an extern declaration is used. The const is similar.

A connection with a static, const keyword, and enum type is internal.

Symbols with internal links cannot be used outside of the current file, so that they affect other parts of the program and can be placed in the. h file. At this point, all source files that contain this. h file have their own definitions and do not affect each other.

The definition of a class has an internal link that cannot be repeated in the same compilation unit because it is defined. If you need to use it in another compilation unit, the class must be defined in the header file and included by other files. Use Class A only in other files, because the definition of the class is an internal link and does not export the symbol in the destination file. They will not be parsed by other cells as undefined symbols. It is important to understand this.

Inline functions also have internal links.

In a multiple-file program, if a symbol can interact with other compilation units when the link is linked, then the name has an external link. An external link means that the definition is not limited to a single compilation unit. It can generate external symbols in the. o file. can be accessed by other compilation units to resolve symbols that they do not define. Therefore, they must be unique throughout the program, or they will result in duplicate definitions.

Non-inline member functions, non-inline functions, and non-static free functions all have external links.

All of the inline functions have internal links, because the compiler replaces all calls to the function with the function body whenever possible, and does not write any symbols to the. o file.

A good way to judge whether a symbol is an internal or external link is to see if the symbol is written to. o file.

The previous definition of the impact of the link mode, and then the statement on the impact of the link.

Because the declaration is only useful for the current compilation unit, the declaration does not write anything to the. o file.

such as extern int A;

int func ();

These declarations do not in themselves affect the contents of the. o file. Each one simply names an external symbol so that the current compilation unit can access the corresponding global definition when needed.

A function call causes an undefined symbol to be written to the. o file. If a is not used in the file, it is not written to the. o file. The Func function has a call to this function. The symbol is also written to the destination file. this. o file is then concatenated with the. o file that defines the symbol, and the previously undefined symbol is parsed.

The above declaration may cause the symbol to be written to the destination file. However, the following declaration does not cause the symbol to be written to the destination file.

Such as:

typedef int INT;
Class A; 
struct S; 
Union Point;

 
Their links are also internal.

Both the class declaration and the class definition are internal links. is only used for the current compilation unit.

The definition of a static class data member has an external link. Such as

Class A 
{ 
static int a;//declaration. has internal links. 
};

Static data member A is just a declaration, but its definition is a::a=0, but it has an external link.

C + + handles classes and enumeration types differently. For example, you can declare a class when you do not define a class. However, you cannot declare an enumerated type without definition.

Based on the above analysis, we can know that it is almost a programming error to put a definition of an external link in a header file. Because if the header file is contained in more than one source file, there will be multiple definitions, and the link will be an error.

The definition of placing an internal link in a header file is legal, but is deprecated. Because header files are included in multiple source files, they not only pollute the global namespace, but also have their own entity presence in each compilation unit. Consumes a lot of memory space and can also affect machine performance.

Global variables for the const and static adornments are valid only within the current file scope. They have internal link properties.

The following is a list of definitions that should or should not be written to the header file:

Test.h 
#ifndef test_h 
#define TEST_H 
  int A;   A has an external link and cannot be defined in the header file. 
  extern int b=10;//ibid. The 
  const int C=2;//C has internal links that can be set in header files but should be avoided. 
  static int d=3;//Ibid. 
  static void Func () {}/Ibid. 
  void Func2 () {}//same as a. 
  void func3 ()//OK. Just a statement. does not cause the symbol name to be written to the destination file. 
class A 
{public 
  : 
   static int e;//can have internal links. 
   int f;//can be, ditto. 
   void Func4 ();//Declaration, internal link. Ditto. 
}; 
  a::e=10;//You cannot include a definition with an external link in a header file. The symbol name is not written to the destination file. 
  void A:func4 ()//not Allowed, class member function. External connections. 
{ 
 //,...... 
} 
#endif

I believe you now understand why it is legal to declare a member function only in a type, but not to implement it. You can also answer why the definition of a class can be placed in the. h file. The implementation of the class can be placed in a CPP file with the same name. The teacher's previous introduction is that the compiler will automatically look for a CPP file with the same name. In fact, because the CPP file is stored in the member function implementation, and the member function has the external link attribute, will produce the symbol in the target file. This symbol is defined in this file. Other target files that call this member function also produce an indeterminate symbol. This symbol is parsed after the two target files are connected. Note the static data members should be placed in the CPP file. Instead of the. h file.

The definition of an internal link can be defined in a CPP file and will not affect the global symbol space. However, in the CPP file scope you want to avoid defining (not forbidding) data and functions that are not declared static because they have external links.

Such as

 int A; 
void func () 
{  
    ... 

The above definition has external links that may potentially conflict with other symbolic names of the global namespace. If you do need to use global variables or functions. You can add a static keyword to them. Limits its scope to the current file, with internal links that do not affect the global namespace. Because inline functions and static free functions, enumerations, and const-type data have internal links, they can be defined in a CPP file without affecting the global namespace.

typedef and macro definitions do not introduce symbols to. o files, they can also appear in CPP files and do not affect the global namespace.

A typedef creates an alias for a type that already exists. Instead of creating a new type. It does not provide type safety. Such as

typedef int IntA; 
typedef int InB;
 

The use of INTB in places where inta is needed is not an error. They can be replaced by each other. Because of this we say that it does not provide type safety. However, when you define a function type, the typedef is often used to make the definition clearer.

The standard C library provides an Assert macro to ensure that the given expression value is Non-zero. Otherwise, the error message is output and the program execution is terminated. The assert does not work unless the ndebug is defined in the program. Once the ndebug is defined, the Assert statement is ignored. Notice the difference from the assert in VC. The assert is provided by VC. It works when _DEBUG is defined.

In the VC debug mode, _DEBUG will be defined. In release mode, the Ndebug will be defined.

Well, I'm sure everyone will understand the question at the beginning. If there is not understand, please be sure to leave a message oh. If there is a mistake, please do not hesitate to correct me!!

The above content reference from "Large Scale C + + software Design".

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.