Undefined symbol linker error

Technical Information Database TI688C.txt Understanding

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

Содержание

  1. Error undefined symbol referenced in
  2. Undefined Symbols
  3. Generating an Executable Output File
  4. Generating a Shared Object Output File
  5. Weak Symbols
  6. Error undefined symbol referenced in
  7. Undefined Symbols
  8. Generating an Executable
  9. Generating a Shared Object
  10. Weak Symbols
  11. C++ Undefined Reference Linker Error and How To Deal With It
  12. What Does Undefined Reference Mean in C++?
  13. – Program Output:
  14. How To Fix Undefined Reference in C++
  15. Undefined Reference in Programs Without Main Function
  16. Tracking Down Undefined Reference Errors in Derived Classes
  17. 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.

#include
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
#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
#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
#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.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>
#include <graphics.h>
#include "tstud.h"
#include "action.h"
void Gl_Menu()
{
 clrscr();
 gotoxy(33,11); cout<<"1-vvod novih dannih";
 gotoxy(33,12); cout<<"2- prosmotr";
 gotoxy(33,13); cout<<"3- informatsiya o fakultete";
 gotoxy(33,14); cout<<"4 - informatsiya o gruppe";
 gotoxy(33,15); cout<<"ESC - vyhod";
}
void Menu_1()
{
  clrscr();
  gotoxy(33,11); cout<<"1 - c клавиатуры";
  gotoxy(33,12); cout<<"2 - из файла";
}
 
void main()
{
  char ch,ch1, *file_n;
  Action Act(20);
  TStud stud;
  do
  {
   clrscr();
   Gl_Menu();
   ch=getch();
   switch(ch)
   {
     case '1':
      Menu_1();
      ch1=getch();
      switch(ch1)
             {
        case '1':
          clrscr();
          cin>> stud;
              Act.Add(stud);
          break;
        case '2':
           clrscr(); cout<<"введите имя файла ";
          cin>>file_n;
          Act.FromFile(file_n);
           break;
      };
        break;
     case '2':
       clrscr();
       if(Act.GetN()>0) Act .ToScreen();
       break;
     case '3':
       clrscr(); 
       Act.Obrab_Fac();
       break;
     case '4':
       clrscr(); 
       Act.Obrab_Gr();
       break;
    };
  }while(ch!=27);
 if (Act.GetN()>0) 
      { Act.Sort_Spis();  Act.ToFile(); }
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "tstud.h" // class's header file
 
// class constructor
istream& operator >> (istream& s, TStud & A)
{
 cout<<"введите шифр факультета: "; s>>A.Shifr_Fac;
 cout<<" введите название факультета: "; s>>A.Name_Fac;
 cout<<" введите шифр группы: "; s>>A.Shifr_Gr;
 cout<<" введите количество студентов в группе"; s>>A.kol_stud;
 cout<<" введите общее количество пропусков в группе"; s>>A.prop;
 cout<<" введите количество пропусков по уважительной причине"; s>>A.uv_prop;
 return s;
}
ostream& operator << (ostream& s, TStud& A)
{
 cout<<" шифр факультета: "; s<<setw(2)<<A.Shifr_Fac<<endl;
 cout<<" название факультета: "; s<<setw(3)<<A.Name_Fac<<endl;
 cout<<" шифр группы: "; s<<setw(5)<<A.Shifr_Gr<<endl;
 cout<<" количество студентов в группе: "; s<<A.kol_stud<<endl;
 cout<<" общее количество пропусков в группе: "; s<<A.prop<<endl;
 cout<<" количество пропусков по уважительной причине: "; s<<A.uv_prop<<endl;
 return s;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
class TStud 
{
  private:
    char Shifr_Fac[3], Name_Fac[4], Shifr_Gr[6];
    int kol_stud;
    int prop;
    int uv_prop;
  friend istream& operator >> (istream&, TStud&);
  friend ostream& operator << (ostream&, TStud&);
 public:
  friend class Action;
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
Action::Action(int nn)
{  n=0; mas=new TStud[nn]; }
//------------------------------------------------------------
Action::~Action()
{  delete [] mas; n=0; }
//------------------------------------------------------------
void Action::Add(TStud stud)
{  *(mas+n)= stud; n++; }
 //------------------------------------------------------------
void Action::ToFile()
{
  ofstream zap("Spisok.txt");
  if(!zap) 
  {
     cout<<"nevozmozno otkrit fale lkz zapisi.Nazmite lubyy klavishy...";
     getch();  exit(1);
  };
  zap<<n<<endl;
  for(int i=0; i<n; i++)  zap<<*(mas+i);
  zap.close();
  clrscr();
  cout<<"Ввод данных закончен "<<
   "("<<GetN()<<" zap)"<<" Nazmite lubyy klavishy..."; getch();
}
//------------------------------------------------------------
void Action::FromFile(char *fname)
{
  int nn; TStud stud;
  ifstream chten(fname, ios::in|ios::nocreate);
  if(!chten)
    {
    cout<<endl<<"невозможно открыть файл для чтения.Нажмите любую клавишу...";
    getch();  exit(1);
  }
  Clear();
  chten>>nn;
  for(int i=0; i<nn; i++)
  {
    chten>> stud;
    clrscr();cout<< stud; getch();
    Add(stud);
  };
  chten.close();
  clrscr();
  cout<<"Счет завершен. Нажмите любую клавишу..";
}
//------------------------------------------------------------
void Action::Obrab_Fac()
{
  char sh_fac[3];
  int stud=0, propusk=0;
  float  stud_propusk=0;
  TStud *ptr;
  cout<<" введите шифр факультета:";
  cin>> sh_fac;
  for(int i=0; i<n; i++)
  {
    ptr=(mas+i);
    if(strcmp(ptr->Shifr_Fac, sh_fac)==0)
    {
      stud+=ptr->kol_stud;
      propusk+=ptr->prop;
      stud_propusk+=(ptr->prop - ptr->uv_prop);
    }
   }
  if (stud!=0)
  {
   stud_propusk=float (stud_propusk/stud);
    clrscr();
    cout<<"  Информация по факультету "<<sh_fac<<": "<<endl;
    cout<<"  общее количество студентов : "<< stud<<endl;
    cout<<"  Общее количество пропущеных часов: "<< propusk<<endl;
    cout<<"  Среднее количество пропущеных часов на одного студента:
     "<< stud_propusk<<endl;
  }
  else cout<<"Такой факультет не найден"<<endl;
  getch();
}
//------------------------------------------------------------
void Action::Obrab_Gr()
{
  TStud *ptr; int max=0, imax=0;
  if(n>0)
  {
    for(int i=0; i<n; i++)
    {
      ptr=(mas+i);
      if (ptr->uv_prop>max)
      { imax=i; max=ptr->uv_prop; }
     }
   cout<<" Сведения о группе, имеющей макс. кол-во пропусков по ув. причине:"   <<endl;
  cout<<*(mas+imax);
  getch();
 }
}
//------------------------------------------------------------
void Action::Sort_Spis()
{
  TStud tmp, *ptr1, *ptr2;
  if(n>0)
  {
     L1:
     for(int i=0; i<n-1; i++)
     {  ptr1=(mas+i); ptr2=(mas+i+1);
     if (ptr2->prop> ptr1->prop)
      { tmp=*ptr2; *ptr2=*ptr1; *ptr1=tmp; goto L1; }
      }
   }
}
//------------------------------------------------------------
void Action::ToScreen()
{
  int i=0; char ch;
  do
  {
    clrscr();
    cout<<"--- " <<i+1<<"-ая запись из "<< GetN() <<" ----"<<endl;
    cout<<*(mas+i)<<endl;
    ch=getch();
    switch(ch)
    {
      case 0:   ch=getch();
      case 72: if (i==0) i=GetN()-1; else i--; break;  // нажмите  Page Up
      case 80: if (i==GetN()-1) i=0; else i++;           //нажмите Page Down
    }
  } while(ch!=27);      // выход по нажатию Esc
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Action
{
 private:
  int n;
  TStud *mas;
 public:
  int GetN() {return n;}
  Action( int ); 
  ~Action();
  void Clear(){ n=0; }
  void Add(TStud);
  void ToFile();
  void FromFile(char*);
  void Obrab_Fac();
  void Obrab_Gr();
  void Sort_Spis();
  void ToScreen();
};

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



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 минуту
Всмысле классы с main ом в один файл поместить?



0



Антикодер

1796 / 860 / 48

Регистрация: 15.09.2012

Сообщений: 3,056

20.11.2012, 11:13

6

Думаю что для начала прочитать это
http://forum.codenet.ru/q69347… myfile.cpp
(первая ссылка в гугле по Linker Error: undefined symbol, причем ваша тема на втором месте в гугле(с чем я вас и поздравляю — скоро возьмём первое ))



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

обычно чтобы добавить какую нить библиотечку надо
1) добавить в исходник #include с хидером библиотеки
2) указать компоновщику где хранятся библиотеки и какие библиотеки нужно подключить
либо просто подключить файлик .cpp к проекту чтобы он скомпилировался вместе с вашими исходниками в объектный файл



0



Vadim8063

1 / 1 / 0

Регистрация: 17.01.2012

Сообщений: 130

20.11.2012, 11:22

 [ТС]

11

Ну а где тут не добавлено: всё есть

C++
1
2
3
4
5
6
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>
#include <graphics.h>
#include "tstud.h"
#include "action.h"



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>( хотя это может быть тоже из стандартной библиотеки)
#include «tstud.h»
#include «action.h»

может просто надо добавить в проект tstud.cpp action.cpp



0



1 / 1 / 0

Регистрация: 17.01.2012

Сообщений: 130

20.11.2012, 11:31

 [ТС]

15

Ну еслиб проблемма была в #include «tstud.h»
#include «action.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

Цитата
Сообщение от Vadim8063
Посмотреть сообщение

А при запуке 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 library B, then libA MUST appear before libB 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.

Понравилась статья? Поделить с друзьями:
  • Undefined reference to pow collect2 error ld returned 1 exit status
  • Undefined reference to main collect2 error ld returned 1 exit status
  • Undefined reference to collect2 exe error ld returned 1 exit status
  • Undefined object 7 error index primary does not exist
  • Undefined function or variable matlab как исправить