Already defined in *. OBJ

Source: Internet
Author: User
Tags prototype definition


Lnk2005 errors may occur in the following situations:
1

1. Define global variables repeatedly. There may be two situations:
A. For some programmers who are new to programming, they sometimes think that they can use definitions to declare where they need to use global variables. In fact, this is wrong. global variables are for the entire project. The correct definition should be defined in a CPP file as follows: int g_test; in the CPP file in use, use: extern int g_test. If you still use int g_test, the lnk2005 error will be generated. The error message is similar to AAA. OBJ error lnk2005 int book C? Book @ 3ha already
Defined in BBB. obj. Remember that you cannot assign values to variables. Otherwise, the lnk2005 error will still occur.
What we need here is a "Declaration", not a "Definition "! According to the C ++ standard, a variable is declared and must satisfy both conditions. Otherwise, it is defined as follows:
(1) The declaration must use the extern keyword; (2) the variable cannot be assigned an initial value.
Therefore, the following is a statement:
Extern int;
The following is the definition
Int A; int A = 0; extern int A = 0;
B. For programmers who are not so rigorous in programming, they always define a global variable in files that require variables, and do not consider the variable name, this often leads to repeated variable names and lnk2005 errors.

2. Duplicate header files. The header files that need to be included include definitions of variables, functions, and classes, and must be included multiple times in other places, if there are no related Macros in the header file and other measures to prevent duplicate links, the lnk2005 error will occur. The solution is to perform similar processing in the header file to be included: # ifndef my_h_file // if this macro is not defined
# Define my_h_file // define this macro
....... // Header file body content
.......
# Endif
The above is done using macros. You can also use pre-compilation to add the following to the header file:
# Pragma once
// Header file subject
3. Use a third-party library. This situation is mainly caused by library conflicts between the function library and the MFC in the C runtime. The specific method is to put the database that prompts an error in front of another database. In addition, selecting different C function libraries may cause this error. Microsoft and C have two types of runtime function libraries: libc. Lib, which does not support multithreading. The other is multi-threaded: msvcrt. Lib. This error may occur if these two function libraries are used together in a project. In general, it requires the library of MFC to be linked before the function library of C runtime, we recommend that you use msvcrt that supports multiple threads. lib. Therefore, before using a third-party library, you must first know which library it is linked to. Otherwise, the lnk2005 error may occur. If you have to use a third-party library, you can try to modify it as described below, but it cannot be guaranteed to solve the problem. The first two methods are provided by Microsoft:
A. Select VC menu project-> Settings-> link-> catagory and select input. Then, enter the library you want to ignore in the edit column of ignore libraries, for example, nafxcwd. LIB; libcmtd. lib. Then fill in the correct library order in the edit column of Object/library modules. here you need to be able to determine what is the correct order!
B. Select the VC menu project-> Settings-> link page, and enter/verbose: Lib in the edit column of project options, in this way, you can see the link sequence in the output window during the compilation of the link program.
C. Select the VC menu project-> Settings-> C/C ++ page, select code generation for catagory, and then select other libraries such as multithread DLL in user runtime libraray to try them one by one.
For more information about the compiler processing process, see:
Http://www.donews.net/xzwenlan/archive/2004/12/23/211668.aspx

This is one of the situations where I have encountered the lnk2005 error. There are certainly other situations that may also cause this error, so I do not want you to read this article, when the lnk2005 error occurs again, you may want to exclude the incorrect number. The process of programming is a process of thinking, so you can start your mind more and get more!

Appendix:

Compiler Processing
I. pre-processor-compiler-Assembler-linker
The pre-processor processes related pre-processing commands, generally starting. For example, # include "XX. H" # define.
The compiler translates *. cpp into a *. s file (assembly language ).
The assembler processes *. s to generate the corresponding *. o file (OBJ target file)
Finally, the linker links all *. O files into an executable file (?. EXE)

1. Parts:
First, you must know that parts (which can be understood as a class in a narrow sense) are generally divided into header files (I like to call interfaces, such as *. h) and implementation files (such as *. cpp ).
Generally, header files are stored as interfaces for declaration.
The implementation file is mainly the specific code for implementation.

2. Compile a single file:
Remember that ide only compiles implementation files (such as *. cpp) in bulid to generate obj. In VC, you can ?. CPP press Ctrl + F7 to compile it separately
Generate a corresponding ?. OBJ file. Compiling ?. When CPP, IDE will be in ?. CPP processes header files included with # include in sequence
(If the header file contains another # include file, it will also follow up and process each header file in order, so recursive ..)

3. Internal and external links:
Internal and external links are relatively basic, but they are also the easiest and most common mistakes for new users. Therefore, we need to discuss them in detail here.
Is the internal link generated only locally ?. OBJ, and the external link symbol is visible between all *. obj.
For example, if inline is used, the variables directly declared in the file header and global functions without inline are all external links.
In the file header, the internal declared function of the class (without the function body) is an external link, while the function body is generally an internal link (because ide will try to use it as an inline function)
What is the role of an internal link and an external link? The following example uses vc6:
// File main. cpp content:
Void main (){}
// File t1.cpp content:
# Include "A. H"
Void test1 () {Foo ();}
// File t2.cpp content:
# Include "A. H"
Void Test2 () {Foo ();}
// File A. H content:
Void Foo (){}
Well, use VC to generate an empty console Program (file-New-projects-Win32 console application) and turn off the pre-compilation Option Switch.
(Project-setting-cagegoryrecompiled headers-not using precompiled headers)
Now you open t1.cpp and press Ctrl + F7 to compile and generate t1.obj through
Open t2.cpp and press Ctrl + F7 to compile and generate t2.obj
When you connect, you will find that:
Linking...
T2.obj: Error lnk2005: "Void _ cdecl Foo (void )"(? Foo @ yaxxz) already defined in t1.obj
This is because:
1. Compile t1.cpp. When processing Foo in # include "A. H", the prototype definition of the foo function is external link. Therefore, record that the foo symbol is external in t1.obj.
2. Compile t2.cpp. When processing Foo in # include "A. H", the prototype definition of the foo function is external link. Therefore, the foo symbol is recorded as external in t2.obj.
3. When linking t1.obj and t2.obj, VC finds that there are two places (in t1.obj and t2.obj) that define the same external symbol (note: Yes, the external symbol can
Multiple declarations but not multiple definitions, because the external symbols are globally visible. Assume that the t3.cpp Declaration uses this symbol and you do not know whether to call t1.obj.
In t2.obj), so an error is reported.
There are several solutions:
A. Rewrite the definition in A. H as a declaration, and use another file a. cpp to store the function body. (Tip: change the above program to try)
(The function body can be placed in any other CPP such as t1.cpp, but it is good to use the corresponding CPP file for storage ).
In this case, except for the function body code in A. OBJ,
Other OBJ files generated by CPP including a. h only have the corresponding symbols but no function bodies. For example, t1.obj and t2.obj only have symbols. When the final link is reached, IDE will
The Foo () function of A. obj is linked to the EXE file, and the foo symbol in t1.obj and t2.obj is converted to the address corresponding to the EXE file of the function.
In addition, when a variable is placed in a. h, it becomes the definition of a global variable. How can it be changed to a declaration?
For example, we add: Class cfoo {}; cfoo * OBJ; To A. H;
When you press F7 to build, the following occurs:
Linking...
T2.obj: Error lnk2005: "class cfoo * OBJ "(? OBJ @ 3pavcfoo @ A) already defined in t1.obj
A good way is to define the variable (cfoo * OBJ) in A. cpp, copy the definition to A. H file, and add extern (extern cfoo * OBJ
So you can pass. Of course, extern can also be declared before any location where this variable is called, but it is strongly recommended not to do so, because extern works everywhere
Resulting in inconsistent interfaces. A good habit is that the interface is usually placed in the corresponding header file.

B. Modify the definition in a.h to an internal link, that is, add the inline keyword. At this time, each t1.obj and t2.obj stores a foo function body, but they are not external
So it is not referenced by other OBJ files, so there is no conflict. (Tip: change the above program to try)
In addition, I made an experiment to verify that "VC records the external symbols in the OBJ file" (a bit of a detour ). You can see the following:
(1) file content:
// File main. cpp content:
Void main (){}
// File t1.cpp content:
# Include "A. H"
Void test1 () {Foo ();}
// File t2.cpp content:
# Include "A. H"
Void Test2 () {Foo ();}
// File A. H content:
Inline void Foo (){}
(2) Select t1.cpp and press Ctrl + F7 for separate compilation, and change the compiled t1.obj to t1.obj _ inline.
(3) Select t2.cpp and press Ctrl + F7 for separate compilation, and change the compiled t2.obj to t2.obj _ inline.
(4) Delete all files generated by compilation except t1.obj _ inline and t2.obj _ inline.
(5) modify a. h to void Foo () {} to make it a non-Inline Function for testing.
(6) rebuild all files. Prompt:
Linking...
T2.obj: Error lnk2005: "Void _ cdecl Foo (void )"(? Foo @ yaxxz) already defined in t1.obj
Debug/cle.exe: Fatal error lnk1169: one or more multiply defined symbols found
(7) Well, look at the DEBUG directory under the project directory and you will see the newly generated OBJ file.
Next let's take a look at the manual link,
Open project-setting-link in the menu and copy all the content under project options, as follows:
Kernel32.lib user32.lib kernel winspool. Lib kernel shell32.lib ole32.lib oleaut32.lib UUID. Lib kernel 32.lib user32.lib kernel winspool. Lib kernel ole32.lib oleaut32.lib
Odbc32.lib odbccp32.lib/nologo/subsystem: console/Incremental: yes/PDB: "Debug/cle. PDB"/debug/machine: i386/out: "Debug/cle.exe"/pdbtype: sept
Modify it:
Link.exe kernel32.lib user32.lib kernel winspool. Lib kernel shell32.lib ole32.lib oleaut32.lib UUID. Lib kernel 32.lib user32.lib kernel winspool. Lib kernel shell32.lib ole32.lib
UUID. lib odbc32.lib odbccp32.lib/nologo/subsystem: console/Incremental: yes/PDB: "Debug/cle. PDB "/debug/machine: i386/out:" Debug/cle.exe "/pdbtype: Sept debug/t1.obj debug/t2.obj debug/main. OBJ
Pause
Link.exe is added to the frontend, followed by debug/t1.obj debug/t2.obj debug/Main. OBJ and
The last pause Batch Processing Command is saved to the project directory (the DEBUG directory is displayed under this directory) and named Link. bat.
Run it and you will see:
T2.obj: Error lnk2005: "Void _ cdecl Foo (void )"(? Foo @ yaxxz) already defined I
N t1.obj
Debug/cle.exe: Fatal error lnk1169: one or more multiply defined symbols found
Very good. The effect of linking the original OBJ file is the same as that of using rebuild all in VC. Now, if
We overwrite the backed-up t1.obj _ inline to t1.obj, And the t2.obj _ inline to overwrite t2.obj.
No error occurs, because the original t1.obj _ inline and t2.obj _ inline contain internal link symbols. Good Luck line link. bat, sure enough
As expected, the link is successful. Check that there is an extra EXE file in the DEBUG directory. This indicates that the internal and external symbols are marked in OBJ!
(Note: The above does not use the f7build link of VC. Because the file time has changed, the build will generate a new obj,
Therefore, we use manual link to ensure that objdoes not change. Note bjinformation. You can use dumpbin.exe to view the information.]

4. # include rules:
Many people do not know where to put the # include file?

1). Enhance the integrity of components:
To ensure component integrity, the first # include file in the CPP implementation file of the component (such as test. cpp) should be its own header file (such as test. h ).
(Unless you use a pre-compiled header file, the pre-compiled header must be placed in the first one ). This ensures that the header file (test. h) Other interfaces that must be depended on (such as. h) To be put in the corresponding file header (test. h), rather than in CPP (test. CPP. h) to its own header file (test. h) before (because it forces other header files including this part (test. h) file (B. CPP) You must also write the include (B. to # include "test. H "must also be # include
"A. H ")". In addition, we usually try to reduce the dependency between file headers. See the following:

2). Reduce the dependency between components:
On the basis of 1, try to include the # include file in CPP.
This requires that we do not directly reference the implementation of other variables in the header file, but move this reference to the implementation file.
For example:
// File Foo. h:
Class cfoo {
Void Foo (){}
};
// File test. h:
# Include "foo. H"
Class ctest {
Cfoo * m_pfoo;
Public:
Ctest (): m_pfoo (null ){}
Void test () {If (m_pfoo) {m_pfoo-> Foo ();}}
...........
};
// File test. cpp:
# Include "test. H"
.....

In the test. h file above, we can actually move # include "foo. H" to the test. cpp file. Because cfoo * m_pfoo is only used in part ctest,
In the future, if you want to use the ctest part and other parts including test. H, you do not need to see the foo. h interface. Therefore, we use the Forward Declaration to modify the original file as follows:
// File Foo. h:
Class cfoo {
Public:
Void Foo (){}
};
// File test. h:
Class cfoo;
Class ctest {
Cfoo * m_pfoo;
Public:
Ctest ();
Void test ();
//........
};
// File test. cpp:
# Include "test. H" // The first interface header file containing the part itself
# Include "foo. H" // Foo. h is used for this part.
Ctest: ctest (): m_pfoo (0 ){
M_pfoo = new cfoo;
}
Void ctest: Test (){
If (m_pfoo ){
M_pfoo-> Foo ();
}
}
//.....
// Add main. cpp to test:
# Include "test. H" // we don't need to see # include "foo. H" here
Ctest test;
Void main (){
Test. Test ();
}

3). Dual includes guard:
When other header files are included in the file header (for example, # include "XX. H"), we recommend that you add the following header files:
// Test. h file content:
# Ifndef _ xx1_h _
# Include "xx1.h"
# Endif
# Ifndef _ xx2_h _
# Include "xx2.h"
# Endif
......

Although we have already added the header in the XX. h file, because the compiler opens the # include file
It takes time. If you add a guard on the outside, you can save more Compilation Time for a large project.

Reproduced in: http://www.cnblogs.com/shiney/archive/2011/10/20/2219084.html

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.