Written by Embarcadero USA on Thursday, 2 July 1998 Posted in PROGRAMMING
Technical Information Database TI688C.txt Understanding "Undefined Symbol" Error Messages. Category :General Platform :All Product :Borland C++ ALL Description: One of the most common error messages seen by developers using a C or C++ compiler is "undefined symbol." This document provides a general description of what causes undefined symbol error messages, as well as instructions on solving specific undefined symbol errors. UNDEFINED SYMBOL AT COMPILE TIME An undefined symbol at compile time indicates that the named identifier was used in the named source file, but had no definition in the source file. This is usually caused by a misspelled identifier name, or missing declaration of the identifier used. EXAMPLE 1: int main(void) { test = 1; return 0; } The code shown for example one will cause an undefined symbol error message to be displayed because the variable "test" has not been declared in either a header file which has been included or in the actual code itself. EXAMPLE 2: int main(void) { int test; Test = 1; return 0; } The code shown for example one will cause an undefined symbol error message to be displayed because when the variable "test" was used it was misspelled. The misspelling was a capital 't' instead of a lower case 't'. EXAMPLE 3: int main(void) { int test; test = 1; return 0; } The code shown in example three has no errors and is an example of what must be done to resolve an undefined symbol error message. In the example here we simply made sure we have a definition for the integer test and that we spelled it the same at the time we used it. It's that simple! UNDEFINED SYMBOL AT LINK TIME When linking multi-file projects, the linker must resolve all references to functions and global variables shared between modules. When these references cannot be resolved, the linker generates an "undefined symbol" error message. This means that after searching all of the object files and libraries which are included in the link, the linker was unable to find a declaration for the identifier you were using. This can be caused by: forgetting to include a needed object module or library in your link (project file, response file, or command line). misspelling the name of the undefined symbol either where it was used or where it was declared. in the case of global variables, all may have been declared "extern". mixing C++ with C or Assembly modules, you may have forgotten to use extern "C" to disable name mangling. See the specific entry on this subject elsewhere in this document or consult the helpme!.doc file included with the product. one of your modules may have Generate Underbars turned OFF. If all else fails, TDUMP.EXE both object modules and note any difference between symbols. This will usually trigger an insight sufficient to resolve the problem. For more information on using TDUMP to resolve undefined symbol errors see the "Getting a Closer Look" section in this document. COMMON UNDEFINED SYMBOL ERRORS The following list provides solutions to some of the more common causes of undefined symbol errors: UNDEFINED SYMBOL WHEN LINKING A BORLAND EXAMPLE: Almost all of the Borland's examples come with project files. You must use the project file when building the example to ensure that all necessary modules linked and all necessary settings are defined. UNDEFINED SYMBOL WHEN TLINKING FROM DOS COMMAND LINE The TLINK command line must have the libraries in the following order ( GRAPHICS.LIB + + EMU.LIB + MATH (S,T,C,M,L - for model) + C (S,T,C,M,L - for model) UNDEFINED SYMBOL LINKING C/C++ AND ASSEMBLY MODULES There are several sources of undefined symbol errors when trying to link assembly with C or C++ modules: The Turbo Assembler generates all upper-case symbols unless you specify /ml or /mx on the assembly command line. Since C modules are, by default, case sensitive, failing to do this will result in undefined symbols for all symbols that are not completely upper case in the C module(s). The symbols in the assembly file being referenced from a C module must be declared using a PUBLIC directive. TLINK will not consider symbols that are not declared PUBLIC in an attempt to resolve and undefined symbol condition. All symbols in the assembly module that are referenced in the C module must be prototyped/declared as extern in the C module otherwise the compiler will generate undefined symbol errors for such symbols. All symbols in the assembly module that will be referenced from a C module must have a underscore prefix. This naming convention must be used in the assembly module. You can do this explicitly (_symbol) or you can use: .model , C to specify this implicitly for all symbols. IMPORTANT NOTE: If you put underscores in front of your assembly routines and also specify the .model , C directive, however, the public symbol will be generated with two underscores; consequently an undefined symbol error will be generated. If all else fails, TDUMP both object modules and note any difference between symbols. This will usually trigger an insight sufficient to resolve the problem. For more information on using TDUMP to resolve undefined symbol errors see the "Getting a Closer Look" section in this document. UNDEFINED SYMBOL LINKING C++ WITH C OR ASSEMBLY MODULES C++ is a strongly typed language. In order to support type-safe linkage (as well as function overloading), Borland C++ must attach information to the symbols generated for function names and variables. When this is done, the symbol will no longer match the standard C style function name. In order to link correctly with C or assembly modules, the compiler must be notified that the symbol is to be in the standard C style (non-encoded) rather than employing C++ name-mangling (encoded). This is done by prototyping the function as type extern "C". Here is a quick example: extern "C" int normal_c_func( float, int, char ); For an additional example, you may want to look at the header files which came with the product. One such header file is stdio.h. UNDEFINED SYMBOL: '_main' IN MODULE C0.ASM Every C program must contain a function called main(). This is the first function executed in your program. The function name must be all in lower case. If your program does not have one, create one. If you are using multiple source files, the file that contains the function main() must be one of the files listed in the project. Note that an underscore character '_' is prepended to all external Turbo C++ symbols. In addition to an absent, misspelled or mis-cased symbol main, there are two additional common causes: The "generate underbars" option is disabled. The Pascal calling Convention rather than the C calling convention is selected. UNDEFINED SYMBOL LINKING A DLL It is relatively simple to link a DLL to your source: create a .LIB for the DLL using Borland's implib utility include the LIB in your project if using the IDE or in your link if using the command-line compiler or linker. turn case sensitive link ON turn case sensitive exports ON The issues of linking C++ with C, assembly, or any other language still apply. See the sections on linking C++, C, and assembly in this document. If the link still fails, the techniques in the section "Getting A Closer Look" should help you resolve the problem. UNDEFINED SYMBOL: A PSEUDO REGISTER (ie. _AX) Pseudo registers are only allowed in the Turbo C++ and ANSI modes of the compiler. You can change this setting in the Options | Compiler | Source menu. UNDEFINED SYMBOL: 'FIWRQQ' Your program uses floating point routines directly (or indirectly) and you have NONE selected for floating point. OR, you are using TLINK and have forgotten to include EMU.LIB or FP87.LIB on the command line. UNDEFINED SYMBOL: AN IOSTREAM CLASS MEMBER If you are using the Integrated Development Environment simply turn off Options | Compiler | Code Generation | Unsigned Characters. If you are using the command line compiler simply remove the '-K' option. UNDEFINED SYMBOL: 'abort()' The sole purpose of abort is to print the error message "Abnormal Program Termination" and exit the program with an error code of 3. This function is located in the startup code C0.ASM. Linker errors indicating that abort() is an undefined symbol are only possible if the standard startup code is not being linked into a project. Although this is not common is routine C/C++ development exercises, it is to be expected when linking in code written other languages such Microsoft Fortran, and Clipper and in cases where embedded systems are being developed. To resolve the undefined symbol, extract the abort() function from the startup code and make a separate object out of it to be linked into the project. UNDEFINED SYMBOL: '_exitclean()' There is a function called _exitclean which is new to Turbo C++. Users moving from Turbo C 2.0 to Turbo C++ may encounter _exitclean() as an undefined symbol at link time. _exitclean() is defined in the Turbo C++ startup code. Users creating embedded system (rommable code), who do not use the standard Turbo C++ startup code, are likely to encounter _exitclean() as an undefined symbol. These users can strip the function from the C0.ASM file and create a separate .OBJ file which can be linked. Another option would be to purchase the TC++ RTL source and make the necessary adjustments. UNDEFINED SYMBOL: LLSH or SCOPY or FMUL or FDIV The helper functions have changed their names from Turbo C 2.0 to Turbo C++. This can lead to many undefined symbol issues. When LLSH or SCOPY or FMUL or FDIV (note no underscores here) appear as undefined symbols at link time, it is likely that an object module or library has code generated a call to some helper function from the Turbo C 2.0 libraries. The solution is to simply recompile all objects from source. You can do this by choosing Compile | BuildAll from the menu in the Integrated Development Environment. UNDEFINED SYMBOL: STATIC POINTER TO A CLASS MEMBER FUNCTION Any static member of a class must be initialized otherwise that static member generates an undefined symbol error. The following is an example of how to initialize a static pointer to class member function of a class is initialized: // When testing static member initialization, you must // declare an instance of the class in a main function; // otherwise, the linker has no reference which it must // try to resolve, and the undefined symbol error will // not be seen - thus you won't know that your // initialization was in error. #include // used to allow global initialization of static member // pointer typedef void (*fptr)(); // declare class containing static members class First { public: static fptr statptr; }; // initialize static members of class First fptr First::statptr = NULL; int main(void) { First fVar; if (fVar.statptr == NULL) cout << "fVar.statptr is NULL: " << fVar.statptr << endl; return 0; } // end of main() UNDEFINED SYMBOL: '_WSPRINTF' Turn off the "Case-sensitive exports" and "Case- sensitive link" options. If you are using the command linker, don't use the /c switch. If you are invoking the linker from the BCC(x) command line, use the -lc- switch. If you are using the IDE, go to the linker options dialog box and turn off the case sensitivity switch. UNDEFINED SYMBOL: 'fidrqq' You will get undefined symbol fidrqq when using the Integrated Development Environment if you have the Options | Compiler | Code Generation | More | Floating Point Option set to NONE and you are using floating point arithmetic in your program. In order to best solve this problem you must set the IDE option for Floating Point to either the emulation choice or to the 80x87 choice. Note that if you choose an 80x87 setting the application generated by the compiler will require an 80x87 chip to be present at run-time. Use this setting only when truly appropriate. UNDEFINED SYMBOL IN WINDOWS.H Make sure you are using the windows.h file that came with Borland C++, NOT the windows.h that came with the Microsoft Windows SDK. If you include the Microsoft windows.h file you will get many undefined symbols including WINMAIN in caps and translatemessage in lower case. Use our windows.h file instead of Microsoft's when you are using our compiler. UNDEFINED SYMBOL USING TCLASDLL.LIB To use the DLL version of the container class library you must do ALL of the following: use the large memory model use Smart Callbacks turn case sensitive link ON turn case sensitive exports ON use the DLL version of the RTL define _CLASSDLL UNDEFINED SYMBOL USING SELECTORS PROVIDED BY WINDOWS If you are using _C000h or other selectors provided by Windows and they are coming up as undefined symbols, perhaps you are compiling in C++ mode and forgot to extern "C" them. Programming in C: extern WORD _C000h Programming in C++: extern "C" WORD _C000h UNDEFINED SYMBOL: 'ChangeSelector' The Windows API function ChangeSelector() has the wrong name in KERNEL.EXE for Windows 3.0, and therefore in IMPORT.LIB. The name given to this function (this is NOT a joke) is PrestoChangoSelector(). Use PrestoChangoSelector() in your program in place of ChangeSelector() and all will be well. UNDEFINED SYMBOLS USING THE OBJECTWINDOWS LIBRARY (OWL) If you get the undefined symbols TApplication(unsigned char far *, unsigned int, unsigned int, unsigned char far *, int ) and TWindow::TWindow(TWindowsObject near *, unsigned char far *, TModule near *) and are using the DLL versions of OWL and the Class Library, you must define _CLASSDLL in Options | Compiler | Code Generation | defines combo box. It could be because you have forced unsigned characters. The functions in the .lib take signed characters and thus if you compile to use unsigned characters, the symbols will not match. Using the Integrated Development Environment be sure to turn off Options | Compiler | Code Generation | Unsigned Characters. If you are using the command line compiler be sure to remove the -K option to solve this problem. UNDEFINED SYMBOL: 'Object::new(unsigned int)' You forgot to link with the TCLASDLL.LIB file where it is defined! Basically the problem is that you are mixing both STATIC and DYNAMIC LINK libraries into the application. You must use only one or the other. If you are working in the IDE, change the LINKER options section for libraries. If you are using the dynamic link library, remember to set _CLASSDLL and Build All. If you are using the command line compiler and linker, just be sure to specify the correct set of library files. For specific information on the "correct set of library files" please see the documentation included with the product as library names tend to change from version to version. GETTING A CLOSER LOOK Borland provides tools that you can use to determine exactly what the linker is seeing when it is trying to match symbols: TDUMP and IMPDEF. This section provides some simple techniques for using these utilities to resolve undefined symbol errors. USING TDUMP TO RESOLVE UNDEFINED SYMBOLS TDUMP can be used to list the symbols in a .OBJ or a static .LIB that the linker is having trouble matching. First, TDUMP the module that is trying to reference the symbol. For example, if main.cpp is trying to access a function, myfunc() in myfuncs.cpp and is getting "Undefined symbol myfunc() in module main.cpp", tdump -m -oiEXTDEF main.obj > main.ext Then, TDUMP the module in which the symbol is defined. tdump -m -oiPUBDEF myfuncs.obj > myfunc.pub Using a text editor find the symbol associated with the error in each file. If they are not the same, then you have verified that the linker is correct in generating the error. You must check your code and verify that the compiler is seeing the same declaration for the symbol when each module is being compiled. You can use TDUMP to look at a static .LIB the same way you look at a .OBJ. tdump -m -oiPUBDEF mystatic.lib > mystatic.pub To use TDUMP with an implib, tdump -m -oiTHEADR mydll.lib > mydll.pub You can also use IMPDEF to view the symbols exported by a DLL. USING IMPDEF TO RESOLVE UNDEFINED SYMBOLS IN A DLL If you are trying to link a Borland generated DLL with another language or product and are getting undefined symbol errors, you should verify that the names or the ordinals that are being exported by the DLL are the same as your application expects. This can be done by generating a .DEF file with the utility IMPDEF. For example, to create a .DEF file for MY.DLL, impdef my.def my.dll The .DEF file will have the exported symbol name and its ordinal number. Remember that C++ mangles names. Your application must expect the mangled symbol name to call the function in the DLL properly. This can be a problem if the application automatically uppercases the symbol name before trying to call the function. If this is so, you must change the declaration of the function and re-build your DLL. DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that you received with the Borland product to which this information pertains. Reference: 7/2/98 10:39:18 AM
Article originally contributed by Borland Staff
Tags:
C++Builder
Check out more tips and tricks in this development video:
No iframes
Содержание
- Error undefined symbol referenced in
- Undefined Symbols
- Generating an Executable Output File
- Generating a Shared Object Output File
- Weak Symbols
- Error undefined symbol referenced in
- Undefined Symbols
- Generating an Executable
- Generating a Shared Object
- Weak Symbols
- C++ Undefined Reference Linker Error and How To Deal With It
- What Does Undefined Reference Mean in C++?
- – Program Output:
- How To Fix Undefined Reference in C++
- Undefined Reference in Programs Without Main Function
- Tracking Down Undefined Reference Errors in Derived Classes
- Key Takeaways
Error undefined symbol referenced in
Undefined Symbols
After all of the input files have been read and all symbol resolution is complete, the link-editor searches the internal symbol table for any symbol references that have not been bound to symbol definitions. These symbol references are referred to as undefined symbols. Undefined symbols can affect the link-edit process according to the type of symbol, together with the type of output file being generated.
Generating an Executable Output File
When generating an executable output file, the link-editor’s default behavior is to terminate with an appropriate error message should any symbols remain undefined. A symbol remains undefined when a symbol reference in a relocatable object is never matched to a symbol definition.
Similarly, if a shared object is used to create a dynamic executable and leaves an unresolved symbol definition, an undefined symbol error results.
To allow undefined symbols, as in the previous example, use the link-editor’s -z nodefs option to suppress the default error condition.
Take care when using the -z nodefs option. If an unavailable symbol reference is required during the execution of a process, a fatal runtime relocation error occurs. This error might be detected during the initial execution and testing of an application. However, more complex execution paths can result in this error condition taking much longer to detect, which can be time consuming and costly.
Symbols can also remain undefined when a symbol reference in a relocatable object is bound to a symbol definition in an implicitly defined shared object. For example, continuing with the files main.c and foo.c used in the previous example.
prog is built with an explicit reference to libbar.so . libbar.so has a dependency on libfoo.so . Therefore, an implicit reference to libfoo.so from prog is established.
Because main.c made a specific reference to the interface provided by libfoo.so , prog really has a dependency on libfoo.so . However, only explicit shared object dependencies are recorded in the output file being generated. Thus, prog fails to run if a new version of libbar.so is developed that no longer has a dependency on libfoo.so .
For this reason, bindings of this type are deemed fatal. The implicit reference must be made explicit by referencing the library directly during the link-edit of prog . The required reference is hinted at in the fatal error message that is shown in the preceding example.
Generating a Shared Object Output File
When the link-editor is generating a shared object output file, undefined symbols are allowed to remain at the end of the link-edit. This default behavior allows the shared object to import symbols from a dynamic executable that defines the shared object as a dependency.
The link-editor’s -z defs option can be used to force a fatal error if any undefined symbols remain. This option is recommended when creating any shared objects. Shared objects that reference symbols from an application can use the -z defs option, together with defining the symbols by using an extern mapfile directive. See SYMBOL_SCOPE / SYMBOL_VERSION Directives.
A self-contained shared object, in which all references to external symbols are satisfied by named dependencies, provides maximum flexibility. The shared object can be employed by many users without those users having to determine and establish dependencies to satisfy the shared object’s requirements.
Weak Symbols
Weak symbol references that remain unresolved, do not result in a fatal error condition, no matter what output file type is being generated.
If a static executable is being generated, the symbol is converted to an absolute symbol with an assigned value of zero.
If a dynamic executable or shared object is being produced, the symbol is left as an undefined weak reference with an assigned value of zero. During process execution, the runtime linker searches for this symbol. If the runtime linker does not find a match, the reference is bound to an address of zero instead of generating a fatal relocation error.
Historically, these undefined weak referenced symbols have been employed as a mechanism to test for the existence of functionality. For example, the following C code fragment might have been used in the shared object libfoo.so.1 .
When building an application that references libfoo.so.1 , the link-edit completes successfully regardless of whether a definition for the symbol foo is found. If during execution of the application the function address tests nonzero, the function is called. However, if the symbol definition is not found, the function address tests zero and therefore is not called.
Compilation systems view this address comparison technique as having undefined semantics, which can result in the test statement being removed under optimization. In addition, the runtime symbol binding mechanism places other restrictions on the use of this technique. These restrictions prevent a consistent model from being made available for all dynamic objects.
Undefined weak references in this manner are discouraged. Instead, you should use dlsym(3C) with the RTLD_DEFAULT, or RTLD_PROBE handles as a means of testing for a symbol’s existence. See Testing for Functionality.
Источник
Error undefined symbol referenced in
Undefined Symbols
After all input files have been read and all symbol resolution is complete, the link-editor searches the internal symbol table for any symbol references that have not been bound to symbol definitions. These symbol references are referred to as undefined symbols. The effect of these undefined symbols on the link-edit process can vary according to the type of output file being generated, and possibly the type of symbol.
Generating an Executable
When the link-editor is generating an executable output file, the link-editor’s default behavior is to terminate the link-edit with an appropriate error message should any symbols remain undefined. A symbol remains undefined when a symbol reference in a relocatable object is never matched to a symbol definition:
In a similar manner, a symbol reference within a shared object that is never matched to a symbol definition when the shared object is being used to build a dynamic executable, will also result in an undefined symbol:
If you want to allow undefined symbols, as in cases like the previous example, then the default fatal error condition can be suppressed by using the link-editor’s -z nodefs option.
Take care when using the -z nodefs option. If an unavailable symbol reference is required during the execution of a process, a fatal runtime relocation error will occur. Although this error can be detected during the initial execution and testing of an application, more complex execution paths can result in this error condition taking much longer to detect, which can be time consuming and costly.
Symbols can also remain undefined when a symbol reference in a relocatable object is bound to a symbol definition in an implicitly defined shared object. For example, continuing with the files main.c and foo.c used in the previous example:
Here prog is being built with an explicit reference to libbar.so , and because libbar.so has a dependency on libfoo.so , an implicit reference to libfoo.so from prog is established.
Because main.c made a specific reference to the interface provided by libfoo.so , then prog really has a dependency on libfoo.so . However, only explicit shared object dependencies are recorded in the output file being generated. Thus, prog will fail to run if a new version of libbar.so is developed that no longer has a dependency on libfoo.so .
For this reason, bindings of this type are deemed fatal, and the implicit reference must be made explicit by referencing the library directly during the link-edit of prog (the required reference is hinted at in the fatal error message shown in this example).
Generating a Shared Object
When the link-editor is generating a shared object, it will by default allow undefined symbols to remain at the end of the link-edit. This allows the shared object to import symbols from either relocatable objects or other shared objects when it is used to build a dynamic executable. The link-editor’s -z defs option can be used to force a fatal error if any undefined symbols remain (see also the extern mapfile directive described in «Defining Additional Symbols»).
In general, a self-contained shared object, in which all references to external symbols are satisfied by named dependencies, provides maximum flexibility. In this case the shared object can be employed by many users, without those users having to determine and establish dependencies to satisfy the shared objects requirements.
Weak Symbols
Weak symbol references that are not bound during a link-edit do not result in a fatal error condition, no matter what output file type is being generated.
If a static executable is being generated, the symbol is converted to an absolute symbol and assigned a value of zero.
If a dynamic executable or shared object is being produced, the symbol will be left as an undefined weak reference. During process execution, the runtime linker searches for this symbol, and if it does not find a match, binds the reference to an address of zero instead of generating a fatal runtime relocation error.
Historically, these undefined weak referenced symbols have been employed as a mechanism to test for the existence of functionality. For example, the following C code fragment might have been used in the shared object libfoo.so.1 :
When an application is built that references libfoo.so.1 , the link-edit will complete successfully regardless of whether a definition for the symbol foo is found. If, during execution of the application, the function address tests nonzero, the function is called. However, if the symbol definition is not found, the function address tests zero, and so is not called.
Compilation systems however, view this address comparison technique as having undefined semantics, which can result in the test statement being removed under optimization. In addition, the runtime symbol binding mechanism places other restrictions on the use of this technique, which prevents a consistent model from being available for all dynamic objects.
Undefined weak references in this manner are discouraged; instead, use dlsym(3DL) with the RTLD_DEFAULT flag as a means of testing for a symbols existence (see «Testing for Functionality»).
Источник
C++ Undefined Reference Linker Error and How To Deal With It
C++ undefined reference is a linker error that often may come up when the function is declared but not implemented. These errors are usually partly identified by the linker error messages, but a programmer still needs to manually investigate the code, build system or linked libraries.
In the following article, we will mostly focus on the causes that occur in source code rather than in the build process or during library linkage. Find out the details in the upcoming paragraphs.
What Does Undefined Reference Mean in C++?
Undefined reference means that the linker is not able to find a symbol definition in any object file, but it’s still referenced. Undefined reference error is not C++ language-specific but rather a result of the executable program generation process. The latter process roughly works as follows: the compiler translates the human-readable source code into machine instructions and generates objects files. Then, the linker will try to combine all needed object files to generate an executable program or, alternatively, a library.
The linker itself can be considered as standalone software which deals with the object files and symbols defined in them. Symbols represent different entities like global variables, function names, member function names, etc.
In the following example, we have a SampleClass class that declares a constructor member. The only thing missing is that no definition is provided. So, if we try to build this program, the linker will throw an undefined reference error related to SampleClass::SampleClass() symbol.
using std::string;
class SampleClass string user;
string name;
int number;public:
SampleClass();
>;
int main() <
SampleClass sp1;
return 0;
>
– Program Output:
/usr/bin/ld: /tmp/ccoWSfKj.o: in function `main’:
tmp.cpp:(.text+0x24): undefined reference to `SampleClass::SampleClass()’
/usr/bin/ld: tmp.cpp:(.text+0x35): undefined reference to `SampleClass::
SampleClass()’
collect2: error: ld returned 1 exit status
How To Fix Undefined Reference in C++
You can fix undefined reference in C++ by investigating the linker error messages and then providing the missing definition for the given symbols. Note that not all linker errors are undefined references, and the same programmer error does not cause all undefined reference errors.
However, it’s more likely to be function-related when it’s declared somewhere, but the definition is nowhere to be found. The issue in the previous example code can be very easily traced as the program is very small.
On the other hand, huge codebases can yield undefined reference errors that may be harder to track down. The next code snippet tries to demonstrate a similar scenario which generates quite a large output of errors from the linker. Notice that the error comes from the polymorphic class SampleClass, which declares PrintContents() as a virtual function.
However, it does not even include empty curly braces to denote the body and qualify for the definition, resulting in an undefined reference error.
#include
#include using std::cout;
using std::endl;
using std::string;
class SampleClass <
private:
string user;
string name;
int number;public:
SampleClass(string u, string n, int num) :
user, name, number <>;
SampleClass(string u, int num) :
user, name<“Name”>, number <> ;virtual string PrintContents() const;
string getName() const;
string getUser() const;
int getNumber() const;
>;
class DerivedClass : public SampleClass <
string identifier;public:
DerivedClass(string u, string n, int num, std::string id) :
SampleClass(std::move(u), std::move(n), num),
identifier <>;
string PrintContents() const override;
string getIdentifier() const;
>;
string DerivedClass::getIdentifier() const <
return this->identifier;
>
string DerivedClass::PrintContents() const <
std::stringstream ss;
ss getUser()
getName()
getNumber()
identifier name;
>
string SampleClass::getUser() const <
return this->user;
>
int SampleClass::getNumber() const <
return this->number;
>
void print(SampleClass& sp) <
cout – Program Output:
/usr/bin/ld: /tmp/cckqLhcA.o: in function `SampleClass::SampleClass(std::__cxx11::basic_string , std::allocator >, std::__cxx11::basic_string , std::allocator >, int)’:
tmp.cpp:(.text._ZN11SampleClassC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_i[_ZN11SampleClassC5ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_i]+0x1f): undefined reference to `vtable for SampleClass’
/usr/bin/ld: /tmp/cckqLhcA.o: in function `SampleClass::
SampleClass()’:
tmp.cpp:(.text._ZN11SampleClassD2Ev[_ZN11SampleClassD5Ev]+0x13): undefined reference to `vtable for SampleClass’
/usr/bin/ld: /tmp/cckqLhcA.o:(.data.rel.ro._ZTI12DerivedClass[_ZTI12DerivedClass]+0x10): undefined reference to `typeinfo for SampleClass’
collect2: error: ld returned 1 exit status
Undefined Reference in Programs Without Main Function
Undefined reference error can occur if you try to compile the source code file that does not have the main() function. To be more precise, these types of source files will yield linker errors if compiled with the usual compiler arguments.
If you intend to compile a given source file without the main() function, you should pass the special argument to not run the linker stage. The latter is usually achieved with a -c argument to the compiler command (e.g., g++ or clang++ ).
#include
#include using std::cout;
using std::endl;
using std::string;
class SampleClass string user;
string name;
int number;public:
SampleClass(string u, string n, int num) :
user, name, number <>;
SampleClass(string u, int num) :
user, name<“Name”>, number <> ;
virtual string PrintContents() const;string getName() const;
string getUser() const;
int getNumber() const;
>;
class DerivedClass : public SampleClass <
string identifier;
public:
DerivedClass(string u, string n, int num, std::string id) :
SampleClass(std::move(u), std::move(n), num),
identifier <>;
string PrintContents() const override;
string getIdentifier() const;
>;
string DerivedClass::getIdentifier() const <
return this->identifier;
>
string DerivedClass::PrintContents() const <
std::stringstream ss;
ss getUser()
getName()
getNumber()
identifier name;
>
string SampleClass::getUser() const <
return this->user;
>
int SampleClass::getNumber() const <
return this->number;
>
void print(SampleClass& sp) <
cout – Program Output:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o: in function `_start’:
(.text+0x24): undefined reference to `main’
collect2: error: ld returned 1 exit status
Tracking Down Undefined Reference Errors in Derived Classes
Another useful method to easily track down undefined reference errors in large codebases is enabling compiler warnings. Sometimes these may warn that functions are referenced but never defined. In the following example, the derived class explicitly overrides a virtual function but does not provide an implementation. Note that these types of errors may also be caused when the program build script or file does not include the corresponding source file.
#include
#include
#include “tmp.h”using std::cout;
using std::endl;
using std::cin;
using std::string;class SampleClass <
private:
string user;
string name;
int number;
public:
SampleClass(string u, string n, int num) :
user, name, number <>;
SampleClass(string u, int num) :
user, name<“Name”>, number <> ;
virtual string PrintContents() const < return <>; >;string getName() const;
string getUser() const;
int getNumber() const;
>;
class DerivedClass : public SampleClass <
string identifier;
public:
DerivedClass(string u, string n, int num, std::string id) :
SampleClass(std::move(u), std::move(n), num),
identifier <>;
string PrintContents() const override;
string getIdentifier() const;
>;
string DerivedClass::getIdentifier() const <
return this->identifier;
>
string SampleClass::getName() const <
return this->name;
>
string SampleClass::getUser() const <
return this->user;
>
int SampleClass::getNumber() const <
return this->number;
>
void print(SampleClass& sp) <
cout – Program Output:
/usr/bin/ld: /tmp/ccdcAqfb.o: in function `DerivedClass::DerivedClass(std::__cxx11::basic_string , std::allocator >, std::__cxx11::basic_string , std::allocator >, int, std::__cxx11::basic_string , std::allocator >)’:
tmp.cpp:(.text._ZN12DerivedClassC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_iS5_[_ZN12DerivedClassC5ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_iS5_]+0xa6): undefined reference to `vtable for DerivedClass’
/usr/bin/ld: /tmp/ccdcAqfb.o: in function `DerivedClass::
tmp.cpp:(.text._ZN12DerivedClassD2Ev[_ZN12DerivedClassD5Ev]+0x13): undefined reference to `vtable for DerivedClass’
collect2: error: ld returned 1 exit status
Key Takeaways
In this article, we covered common reasons that yield an undefined reference to C++ function errors and described several ways to identify them. Here are some key points to bear in mind:
- Undefined reference error is thrown by the linker rather than the compiler
- It’s usually caused by the reference to the function that has been declared, but a definition can’t be found
- Investigate linker error messages which can help to pin down the identifiers that are related to the cause of the problem
- Don’t run the linker stage on programs that don’t include the main function
Now you should be able to move on to some practical problems of analyzing linker errors and fixing them. You are definitely ready to try manually building relatively medium programs with multiple files and investigate possible causes for linker errors.
Источник
Vadim8063 1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
||||||||||||||||||||
1 |
||||||||||||||||||||
19.11.2012, 18:33. Показов 12420. Ответов 43 Метки нет (Все метки)
Прога компилируется без ошибок, когда запускается, то появляется 10 ошибок. И все одного характера Linker Error: undefined symbol.
__________________
0 |
Антикодер 1796 / 860 / 48 Регистрация: 15.09.2012 Сообщений: 3,056 |
|
19.11.2012, 18:36 |
2 |
ну и что же такое по вашему linker?
0 |
1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
|
20.11.2012, 10:45 [ТС] |
3 |
Ссылка Добавлено через 15 часов 54 минуты
0 |
Антикодер 1796 / 860 / 48 Регистрация: 15.09.2012 Сообщений: 3,056 |
|
20.11.2012, 11:01 |
4 |
Да? а Компоновщик PS тогда бы уж перевели его как «ссылочник»
0 |
1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
|
20.11.2012, 11:11 [ТС] |
5 |
А как это сделать? Добавлено через 1 минуту
0 |
Антикодер 1796 / 860 / 48 Регистрация: 15.09.2012 Сообщений: 3,056 |
|
20.11.2012, 11:13 |
6 |
Думаю что для начала прочитать это
0 |
1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
|
20.11.2012, 11:16 [ТС] |
7 |
Блин да всё добавлял и галочку ставил и библиотека рабочая….
0 |
Антикодер 1796 / 860 / 48 Регистрация: 15.09.2012 Сообщений: 3,056 |
|
20.11.2012, 11:17 |
8 |
ну классы я бы не стал помещать вместе с main-ом. это конечно решение проблемы, но кривое.
0 |
1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
|
20.11.2012, 11:18 [ТС] |
9 |
У меня дело в том что так и есть два файла h три cpp. Все аккуратно. Но блин не работает
0 |
Антикодер 1796 / 860 / 48 Регистрация: 15.09.2012 Сообщений: 3,056 |
|
20.11.2012, 11:21 |
10 |
обычно чтобы добавить какую нить библиотечку надо
0 |
Vadim8063 1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
||||
20.11.2012, 11:22 [ТС] |
11 |
|||
Ну а где тут не добавлено: всё есть
0 |
Антикодер 1796 / 860 / 48 Регистрация: 15.09.2012 Сообщений: 3,056 |
|
20.11.2012, 11:26 |
12 |
надо тогда комментировать весь код в main и закоментировать все #include и подключать их по одному, пока не появиться ошибка, когда она появиться нужно указать компоновщику имя библиотеки, которая должна быть связана с #include файлом
0 |
1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
|
20.11.2012, 11:29 [ТС] |
13 |
И так тоже пробывал, библиотеки все есть которые нужны. Добавлено через 32 секунды
0 |
Антикодер 1796 / 860 / 48 Регистрация: 15.09.2012 Сообщений: 3,056 |
|
20.11.2012, 11:30 |
14 |
могу подсказать что проблема скорее всего в этих модулях #include <graphics.h>( хотя это может быть тоже из стандартной библиотеки) может просто надо добавить в проект tstud.cpp action.cpp
0 |
1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
|
20.11.2012, 11:31 [ТС] |
15 |
Ну еслиб проблемма была в #include «tstud.h»
0 |
Антикодер 1796 / 860 / 48 Регистрация: 15.09.2012 Сообщений: 3,056 |
|
20.11.2012, 11:33 |
16 |
Может всё дело в компиляторе? может дело и в компиляторе хотя у меня не бывало ситуаций, чтоб gcc как-то неправильно работал
0 |
1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
|
20.11.2012, 11:36 [ТС] |
17 |
Так что мне делать? Я уже проверял препроверял 3 дня всё. Заново переписывал и т д .
0 |
быдлокодер 1722 / 909 / 106 Регистрация: 04.06.2008 Сообщений: 5,644 |
|
20.11.2012, 11:38 |
18 |
А щас чё у тебя, на каком этапе всё это дело?
0 |
1 / 1 / 0 Регистрация: 17.01.2012 Сообщений: 130 |
|
20.11.2012, 11:39 [ТС] |
19 |
Ну прога написана при компиле ошибок нет. А при запуке 10 ошибок линкер ерор к каждому обработчику цепляет
0 |
быдлокодер 1722 / 909 / 106 Регистрация: 04.06.2008 Сообщений: 5,644 |
|
20.11.2012, 11:45 |
20 |
А при запуке 10 ошибок линкер ерор к каждому обработчику цепляет скинь мне экзешник
0 |
Error description:
- What are undefined reference/unresolved external symbol errors? What are common causes and how to fix/prevent them?
Solution 1:
- The specified errors occur during this last stage of compilation, most commonly referred to as linking. It basically means that we compiled a bunch of implementation files into object files or libraries and now we want to get them to work together.
Common causes include:
- Failure to link against appropriate libraries/object files or compile implementation files
- Declared and undefined variable or function.
- Common issues with class-type members
- Template implementations not visible.
- Symbols were defined in a C program and used in C++ code.
- Incorrectly importing/exporting methods/classes across modules/dll. (MSVS specific)
- Circular library dependency
- undefined reference to `[email protected]’
- Interdependent library order
- Multiple source files of the same name
- Mistyping or not including the .lib extension when using the #pragma (MSVC)
- Problems with template friends
- Inconsistent UNICODE definitions
Solution 2:
- It can also happen that we forget to add the file to the compilation, in which case the object file won’t be generated. In gcc we’d add the files to the command line. In MSVS adding the file to the project will make it compile it automatically (albeit files can, manually, be individually excluded from the build).
Solution 3:
- The order in which libraries are linked DOES matter if the libraries depend on each other. In general, if library
A
depends on libraryB,
thenlibA
MUST appear beforelibB
in the linker flags.
Solution 4:
- The function (or variable)
void foo()
is defined in a C program and you attempt to use it in a C++ program:
void foo();
int main()
{
foo();
}
click below button to copy the code. By c++ tutorial team
- The C++ linker expects names to be mangled, so you have to declare the function as:
extern "C" void foo();
int main()
{
foo();
}
click below button to copy the code. By c++ tutorial team
- Equivalently, instead of being defined in a C program, the function (or variable)
void foo()
is defined in C++ but with C linkage:
extern "C" void foo();
click below button to copy the code. By c++ tutorial team
- and we attempt to use it in a C++ program with C++ linkage.
- If an entire library is included in a header file (and was compiled as C code); the include will need to be as follows;
extern "C" {
#include "cheader.h"
}
click below button to copy the code. By c++ tutorial team
Solution 5:
- We will be able to get rid of an unresolved external error in Visual Studio 2012 just by recompiling the offending file. When we re-build, the error goes away.
- This usually happens when two (or more) libraries have a cyclic dependency. Library A attempts to use symbols in B.lib and library B attempts to use symbols from A.lib. Neither exist to start off with. When we attempt to compile A, the link step will fail because it can’t find B.lib. A.lib will be generated, but no dll. We then compile B, which will succeed and generate B.lib. Re-compiling A will now work because B.lib is now found.