Thread: Incomprehensible LNK1169 error

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    271

    Incomprehensible LNK1169 error

    First, here's a class definition and some associated functions inside a header names "phonemes.h"

    It's very long so don't look at it all. Just the final "operator-" definition is causing the problem. I just posted the entire code just in case something in there that I'd overlooked was causing the problem.

    Code:
    #ifndef _PHONEMES_H__INCLUDED_
    #define _PHONEMES_H__INCLUDED_
    
    #include "main_header.h"
    
    struct core_features{
    	UINT cons			:1;	//consonantal
    	UINT syll			:1;	//syllabic
    	UINT son			:1;	//sonorant
    	UINT lab			:1;	//labial
    	UINT cor			:1;	//coronal
    	UINT back			:1;	//back
    };
    
    struct secondary_features
    {
    	UINT ant			:1;	//anterior
    	UINT dist			:1;	//distributed
    	UINT high			:1;	//high
    	UINT low			:1;	//low
    	UINT voice			:1;	//voiced
    	UINT spread			:1;	//spread glottis
    	UINT constr			:1;	//constricted glottis
    	UINT cont			:1;	//continuant
    	UINT del_rel		:1;	//delayed release
    	UINT lat			:1;	//lateral
    	UINT nas			:1;	//nasal
    	UINT atr			:1;	//advanced tongue root
    };
    
    struct ternary_features
    {
    	UINT spread			:1;
    	UINT atr			:1;
    };
    
    
    class Phoneme{
    protected:
    	core_features c_feat;
    	secondary_features s_feat;
    	UCHAR uc_c_feat;
    	WCHAR wc_s_feat;
    public:
    	Phoneme(){*(PUCHAR)(&c_feat) = 0; *(PWCHAR)(&s_feat) = 0; uc_c_feat = 0; wc_s_feat = 0;}
    	~Phoneme(){}
    	void set_cons(int i = 1){c_feat.cons = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 5) : ((k <<=5) & uc_c_feat ? uc_c_feat ^= k : 0);}
    	void set_syll(int i = 1){c_feat.syll = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 4) : ((k <<=4) & uc_c_feat ? uc_c_feat ^= k : 0);}
    	void set_son(int i = 1){c_feat.son = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 3) : ((k <<=3) & uc_c_feat ? uc_c_feat ^= k : 0);}
    	void set_lab(int i = 1){c_feat.lab = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 2) : ((k <<=2) & uc_c_feat ? uc_c_feat ^= k : 0);}
    	void set_cor(int i = 1){c_feat.cor = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 1) : ((k <<=1) & uc_c_feat ? uc_c_feat ^= k : 0);}
    	void set_back(int i = 1){c_feat.back = i; UCHAR k = 1; i ? uc_c_feat |= 1 : (k & uc_c_feat ? uc_c_feat ^= k : 0);}
    	void set_ant(int i = 1){s_feat.ant = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 11) : ((k <<= 11) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_dist(int i = 1){s_feat.dist = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 10) : ((k <<= 10) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_high(int i = 1){s_feat.high = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 9) : ((k <<= 9) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_low(int i = 1){s_feat.low = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 8) : ((k <<= 8) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_voice(int i = 1){s_feat.voice = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 7) : ((k <<= 7) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_spread(int i = 1){s_feat.spread = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 6) : ((k <<= 6) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_constr(int i = 1){s_feat.constr = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 5) : ((k <<= 5) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_cont(int i = 1){s_feat.cont = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 4) : ((k <<= 4) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_del_rel(int i = 1){s_feat.del_rel = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 3) : ((k <<= 3) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_lat(int i = 1){s_feat.lat = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 2) : ((k <<= 2) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_nas(int i = 1){s_feat.nas = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 1) : ((k <<= 1) & wc_s_feat ? wc_s_feat ^= k : 0);}
    	void set_atr(int i = 1){s_feat.atr = i; WCHAR k = 1; i ? wc_s_feat |= 1 : (k & wc_s_feat ? wc_s_feat ^= k : 0);}
    	core_features* p_c_feat(){return &c_feat;}
    	secondary_features* p_s_feat(){return &s_feat;}
    	UCHAR uc_c_feat_value(){return uc_c_feat;}
    	WCHAR wc_s_feat_value(){return wc_s_feat;}
    	virtual void initialize(){*(PUCHAR)(&c_feat) = 0; *(PWCHAR)(&s_feat) = 0;}
    	//friend operator-(Phoneme&, Phoneme&);
    };
    
    class Vowel : public Phoneme
    {
    public:
    	Vowel()
    	{
    		*(PUCHAR)(&c_feat) = 0;
    		*(PWCHAR)(&s_feat) = 0;
    		this->set_son();
    		this->set_syll();
    		this->set_cont();
    		this->set_voice();		
    	}
    	~Vowel(){}
    	virtual void initialize()
    	{
    		*(PUCHAR)(&c_feat) = 0;
    		*(PWCHAR)(&s_feat) = 0;
    		this->set_son();
    		this->set_syll();
    		this->set_cont();
    		this->set_voice();
    	}
    };
    
    class Consonant : public Phoneme
    {
    public:
    	Consonant()
    	{
    		*(PUCHAR)(&c_feat) = 0;
    		*(PWCHAR)(&s_feat) = 0;
    		this->set_cons();
    	}
    	~Consonant(){}
    	virtual void initialize()
    	{
    		*(PUCHAR)(&c_feat) = 0;
    		*(PWCHAR)(&s_feat) = 0;
    		this->set_cons();
    	}
    };
    
    inline int bit_diff(UINT i, UINT j)
    {
    	i ^= j;
    	int result = 0;
    	for(; i > 0; i >>= 1)
    		i & 1 ? result++ : 0;
    	return result;
    }
    
    template<class T>
    inline int bit_diff_t(T i, T j)
    {
    	i ^= j;
    	T result = 0;
    	for(; i > 0; i >>= 1)
    		i & 1 ? result++ : 0;
    	return result;
    
    }
    
    
    //Commenting out this function gets rid of the problem.
    int operator-(Phoneme& p1, Phoneme& p2)
    {
    	//return 10 * bit_diff(*((PUINT) p1.p_c_feat()), *((PUINT) p2.p_c_feat())) + bit_diff(*((PUINT) p1.p_s_feat()), *((PUINT) p2.p_s_feat()));
    	return 10 * bit_diff_t<UCHAR>(p1.uc_c_feat_value(), p2.uc_c_feat_value()) + bit_diff_t<WCHAR>(p1.wc_s_feat_value(), p2.wc_s_feat_value());
    }
    
    #endif
    The error message I get when I compile is as follows:
    Code:
    OT_OK error LNK2005: "int __cdecl operator-(class Phoneme &,class Phoneme &)" (??G@YAHAAVPhoneme@@0@Z) already defined in main.obj
    OT_OK fatal error LNK1169: one or more multiply defined symbols found
    The strange thing is, when I move that "operator-" function out of the header and into the cpp file containing the main routine, it compiles just fine.
    What am I doing wrong?

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Don't define non-inline methods inside a header file (even one with include guards). Either mark it as inline, or define it in a single cpp file. The problem is that multiple cpp files are including that header, which is allowed for declarations. However, each cpp file is compiling that function separately and the linker is finding multiple definitions.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    That solved it. Thanks a gesundheit.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Making C DLL using MSVC++ 2005
    By chico1st in forum C Programming
    Replies: 26
    Last Post: 05-28-2008, 01:17 PM
  3. Connecting to a mysql server and querying problem
    By Diod in forum C++ Programming
    Replies: 8
    Last Post: 02-13-2006, 10:33 AM
  4. Learning OpenGL
    By HQSneaker in forum C++ Programming
    Replies: 7
    Last Post: 08-06-2004, 08:57 AM
  5. Couple C questions :)
    By Divx in forum C Programming
    Replies: 5
    Last Post: 01-28-2003, 01:10 AM