Thread: What's a link error?

  1. #1
    Registered User
    Join Date
    Mar 2002
    Posts
    15

    Question What's a link error?

    What does this mean?

    I keep getting

    Link error : Undefined symbol: ??.........

  2. #2

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    15
    ok, so how do I fix this?

  4. #4
    Registered User matheo917's Avatar
    Join Date
    Sep 2001
    Posts
    279
    we would need the code, at least a bit of code to determnine where the problem is...

  5. #5
    Registered User
    Join Date
    Mar 2002
    Posts
    15
    deleted
    Last edited by asdf; 04-05-2002 at 10:56 PM.

  6. #6
    Registered User matheo917's Avatar
    Join Date
    Sep 2001
    Posts
    279
    i just looked over the code but everything seams ok.......let me try it on my compiler......

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    You need to define your AminoAcidAnalyzer and Element constructors. Even if they're empty, the linker requires that they be defined somewhere, which they aren't as is.

    -Prelude
    My best code is written with the delete key.

  8. #8
    Evil Member
    Join Date
    Jan 2002
    Posts
    638
    The linker is what matches function calls to declaractions in different units. An undefined symbol or unresolved external happens if a function definition is not found.

    1: You need to #include the corresponding .cpp file at the bottom of a .h file. aminoacid_analyzyer.cpp is never included into the program, so the funtion defined therein is never defined for your main() to use it.

    2: Its is generally bad practice for an implementation file to include things. move all the #includes in aminoacid_analyzer.cpp into the top of aminoacid_analyzer.h. That way you know from the interface what includes a header needs.

    3: If element is part of the implementation of aminoacid_analyzer, you can safely remove the #include for it in your main program. If you use them as two distinct concrete types, then best to leave it as is.

    4: I find it is helpful to explicitly define blank constructors. Some compilers might handle this for you, but it is good practice, and tells users that it is intentional, and not a work in progress.

    So, in short:

    remove all includes from the top of aminoacid_analyzer.cpp, and place <iostream> and "element.h" at the top of aminoacid_analyzer.h.

    add an #include "aminoacid_analyzer.cpp" to the bottom of aminoacid_analyzer.h

    remove the include from the top of element.h (element does not need aminoacid to work, you got it the other way round)

    remove the include to element.h from the top of your main file. (unless used as a concrete type)

  9. #9
    Registered User
    Join Date
    Mar 2002
    Posts
    15
    Imperito, I followed what you said but now aminoacid_analyzer.cpp does not recognize the class from aminoacid_analyzer.h
    Last edited by asdf; 04-05-2002 at 10:17 PM.

  10. #10
    Evil Member
    Join Date
    Jan 2002
    Posts
    638
    Did you put the #include "aminoacid_analyzer.cpp" line at the bottom of the .h file, just above the #endif? Also, make sure that you include the .h in your main file, not the .cpp.

    [EDIT]
    Also, as prelude mentioned, define your constructors. If this does not help, post your source again.
    [/EDIT]

  11. #11
    Registered User
    Join Date
    Mar 2002
    Posts
    15
    Here is what I got now. The error is "unknowed identifier 'AminoAcidAnalyzer'

    Also, I'm not sure if I need to pass a acidCount as a parameter in the constructor?

    aminoacid_main.cpp
    Code:
    #include "aminoacid_analyzer.h"
    //#include "element.h"
    
    int main( void )
    {
    	char elementFile[] = "elements.dat";
    	
    	AminoAcidAnalyzer *aaa = new AminoAcidAnalyzer;
    	
    	aaa->populate(elementFile);
    	
    	return 0;
    }
    aminoacid_analyzer.cpp
    Code:
    //#include <iostream.h>
    //#include "aminoacid_analyzer.h"
    
    AminoAcidAnalyzer::AminoAcidAnalyzer()
    {
    	acidCount = 0;
    }
    
    void AminoAcidAnalyzer::populate(char *elementFile)
    {
    	cout<<"It's Working!";
    }
    aminoacid_analyzer.h
    Code:
    #ifndef _AMINO_ACID_ANALYZER_
    #define _AMINO_ACID_ANALYZER_
    
    #include <iostream.h>
    #include "element.h"
    
    class AminoAcidAnalyzer
    {
    	Element elements[5];
    	int acidCount;
    	
    	public:
    		AminoAcidAnalyzer();
    		void populate(char * elementFile);		 
    };
    
    #include "aminoacid_analyzer.cpp"
    
    #endif
    element.h
    Code:
    #ifndef __ELEMENT_H__
    #define __ELEMENT_H__
    
    class Element
    {
    	char atomic_symbol;
    	double atomic_mass;
    };
    
    #endif
    element.h
    still yet to be implemented
    Last edited by asdf; 04-05-2002 at 11:14 PM.

  12. #12
    Evil Member
    Join Date
    Jan 2002
    Posts
    638
    Odd, that example compiles and runs fine for me.

    First of all, no, you don't have to pass member data from a class to member functons. There is something called a *this pointer that handles that for you. Just know that any member funciton of a class has all other memeber functions and data member in scope. For this reason, it is a good idea to declare member functions const unless they need to modify data members.

    As for your problem. what system/compiler do you use? Are you sure you have LFN support? What file/line number is given with the error?

  13. #13
    Registered User
    Join Date
    Mar 2002
    Posts
    15
    Ok I bolded my errors (all in the aminoacid_analyzer.cpp file)

    As for the compiler I am using Metroworks CodeWarrior Learning Edition v1.0. Don't know if it's got LFN support. I would love to use another compiler as CW is crap but my program has to work on the CW compiler at school!

  14. #14
    Evil Member
    Join Date
    Jan 2002
    Posts
    638
    Well, I'm out. That's compilant and it compiles for me. anybody got knowledge of CW know what is missing? Prelude, any thoughts?

  15. #15
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >That's compilant and it compiles for me
    Really? What compiler do you use? I get 7 errors with the code that was posted. Also make sure that you try to run the program, if all you do is compile it will go through cleanly because the linker activates after the compiler.

    >Prelude, any thoughts?
    Hehe

    Try this:
    Code:
    main.cpp:
    
    #include <iostream.h>
    #include "element.h"
    #include "aminoacid_analyzer.h"
    #include "aminoacid_analyzer_fleshy.h"
    
    int main( void )
    {
      char elementFile[] = "elements.dat";	
      AminoAcidAnalyzer *aaa = new AminoAcidAnalyzer;	
      aaa->populate(elementFile);	
      return 0;
    }
    Code:
    aminoacid_analyzer.h:
    
    #ifndef AMINO_ACID_ANALYZER__
    #define AMINO_ACID_ANALYZER__
    
    class AminoAcidAnalyzer
    {
      Element elements[5];
      int acidCount;	
    public:
      AminoAcidAnalyzer();
      void populate(char * elementFile);		 
    };
    
    #endif
    Code:
    aminoacid_analyzer_fleshy.h:
    
    AminoAcidAnalyzer :: AminoAcidAnalyzer()
    {
      acidCount = 0;
    }
    
    void AminoAcidAnalyzer :: populate(char *elementFile)
    {
      cout<<"It's Working!";
    }
    Code:
    element.h:
    
    #ifndef ELEMENT_H__
    #define ELEMENT_H__
    
    class Element
    {
      char atomic_symbol;
      double atomic_mass;
    };
    
    #endif
    Notes: The double underscore prefix in your mangled names is reserved by the implementation, avoid using it. You want to avoid #include'ing headers and source files anywhere but your main driver files or you risk linkage problems due to the spaghetti effect.

    Personally, I prefer to define my class methods in another header if the class is large or in the same header as the declaration if the class is small. This is mostly because I don't like to include source files as a matter of style, it keeps things simpler to follow.

    -Prelude
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Testing some code, lots of errors...
    By Sparrowhawk in forum C Programming
    Replies: 48
    Last Post: 12-15-2008, 04:09 AM
  3. Avoiding Global variables
    By csonx_p in forum Windows Programming
    Replies: 32
    Last Post: 05-19-2008, 12:17 AM
  4. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  5. DX - CreateDevice - D3DERR_INVALIDCALL
    By Tonto in forum Game Programming
    Replies: 3
    Last Post: 12-01-2006, 07:17 PM