unresolved externals - function already defined in file ... .obj

Pages: 12
Hello,
I have some problem with unresolved external and cannot find out how this happens.
I am on Windows Visual Studio where I have file stdafx.h which includes headers. Standard files like string, vector etc. are there. The program worked until I decided to create one more file to include functions and definitions. Last 5 lines from stdafx.h:

1
2
3
4
5
#include "definitions.h" // constants
#include "fnc.h" // my functions
#include "myColorConverter.h"
#include "strings.h"
#include "file.h" // GetEncoderClsid; MyGlobalClass::IsDirectory 


Main project file is called parse3.cpp and it starts like this:
1
2
3
#include "stdafx.h"
#include "main.h" // MyGlobalClass
using namespace std;


Header of fnc.h (the file I just added):
1
2
void error(char * str);
LIMITS1 getNumberFromRegex(std::string s, char ch);


Header of definitions.h (another file I just added):
1
2
3
4
5
6
7
8
9
10
#ifndef DESTINATION_CONST
#define DESTINATION_CONST

#define ERR_regex ": bracket not found in regex: {y:number} or {x:number}"
#define ERR_regex_ "Incorrect syntax in -r regex. Expression expected: {x:number}_{y:number} or {y:number}_{x:number} or similar."

struct LIMITS1 { int min; int max; } Limits1;
struct LIMITS2 { int xmin; int xmax; int ymin; int ymax; } Limits2;

#endif 


And fnc.cpp:
http://paste.ofcode.org/vRE2JvhprULRg5rtUGPkge

there is no definitions.cpp

I got these errors:
------ Debug Win32 ------
parse3.cpp
Generating Code...
Compiling...
stdafx.cpp
fnc.cpp
fnc.cpp(17): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\c++\visual studio 10.0\vc\include\string.h(188) : see declaration of 'strncpy'
fnc.cpp(22): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\c++\visual studio 10.0\vc\include\string.h(188) : see declaration of 'strncpy'
fnc.cpp(23): warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\c++\visual studio 10.0\vc\include\string.h(197) : see declaration of 'strtok'
fnc.cpp(25): warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\c++\visual studio 10.0\vc\include\string.h(197) : see declaration of 'strtok'
file.cpp
Generating Code...
fnc.obj : error LNK2005: "struct LIMITS1 Limits1" (?Limits1@@3ULIMITS1@@A) already defined in file.obj
fnc.obj : error LNK2005: "struct LIMITS2 Limits2" (?Limits2@@3ULIMITS2@@A) already defined in file.obj
parse3.obj : error LNK2005: "struct LIMITS1 Limits1" (?Limits1@@3ULIMITS1@@A) already defined in file.obj
parse3.obj : error LNK2005: "struct LIMITS2 Limits2" (?Limits2@@3ULIMITS2@@A) already defined in file.obj
stdafx.obj : error LNK2005: "struct LIMITS1 Limits1" (?Limits1@@3ULIMITS1@@A) already defined in file.obj
stdafx.obj : error LNK2005: "struct LIMITS2 Limits2" (?Limits2@@3ULIMITS2@@A) already defined in file.obj
fnc.obj : error LNK2019: unresolved external symbol "void __cdecl error(char *)" (?error@@YAXPAD@Z) referenced in function "struct LIMITS1 __cdecl getNumberFromRegex(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,char)" (?getNumberFromRegex@@YA?AULIMITS1@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@D@Z)
Debug\parse3.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Can you find what's wrong?
Last edited on
Did you include the implementation of those functions (the code after main in the link) in your code?
I have this in strings.h

http://paste.ofcode.org/vBWaSNjpkKGRFdaNYEziLF

I include
#include "strings.h"
from stdafx.h
which is included from main file cpp.

then I have the main function.

I don't add the functions after main(){} how the author did. But that should not be problem I think.
The problem was that the implementation was in strings.h and not in strings.cpp. I thought it shouldn't make problem, but it did. But I have one more error:

strings.cpp(5): error C3861: 'strlen': identifier not found

I have
included
#include <string>
before
#include "strings.h"
so also have no idea why this happens
strlen if declared in <cstring> (or string.h), not <string>
So I have fixed it. It wanted to include the strings header in strings.h. But it was in stdax.h so not clear why needed. Maybe I must always include the header which are used in cpp files? I though I need that only once. That's confusion.

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

char* trimRight(char* string, char junk)
{
	char* original = string + strlen(string);
	while(*--original == junk);
	*(original + 1) = '\0';
	return string;
}
char* trimLeft(char *string, char junk)
{
	char* original = string;
	char *p = original;
	int trimmed = 0;
	do
	{
		if (*original != junk || trimmed)
		{
		trimmed = 1;
		*p++ = *original;
		}
	}
	while (*original++ != '\0');
	return string;
}
Hello,
I have some problem with unresolved external and cannot find out how this happens.
I am on Windows Visual Studio where I have file stdafx.h which includes headers. Standard files like string, vector etc. are there. The program worked until I decided to create one more file to include functions and definitions. Last 5 lines from stdafx.h:

1
2
3
4
5
#include "definitions.h" // constants
#include "fnc.h" // my functions
#include "myColorConverter.h"
#include "strings.h"
#include "file.h" // GetEncoderClsid; MyGlobalClass::IsDirectory 


Main project file is called parse3.cpp and it starts like this:
1
2
3
#include "stdafx.h"
#include "main.h" // MyGlobalClass
using namespace std;


Header of fnc.h (the file I just added):
1
2
void error(char * str);
LIMITS1 getNumberFromRegex(std::string s, char ch);


Header of definitions.h (another file I just added):
1
2
3
4
5
6
7
8
9
10
#ifndef DESTINATION_CONST
#define DESTINATION_CONST

#define ERR_regex ": bracket not found in regex: {y:number} or {x:number}"
#define ERR_regex_ "Incorrect syntax in -r regex. Expression expected: {x:number}_{y:number} or {y:number}_{x:number} or similar."

struct LIMITS1 { int min; int max; } Limits1;
struct LIMITS2 { int xmin; int xmax; int ymin; int ymax; } Limits2;

#endif 


And the fnc.cpp:
http://paste.ofcode.org/vRE2JvhprULRg5rtUGPkge

there is no definitions.cpp

I got these errors:
------ Debug Win32 ------
parse3.cpp
Generating Code...
Compiling...
stdafx.cpp
fnc.cpp
fnc.cpp(17): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\c++\visual studio 10.0\vc\include\string.h(188) : see declaration of 'strncpy'
fnc.cpp(22): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\c++\visual studio 10.0\vc\include\string.h(188) : see declaration of 'strncpy'
fnc.cpp(23): warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\c++\visual studio 10.0\vc\include\string.h(197) : see declaration of 'strtok'
fnc.cpp(25): warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\c++\visual studio 10.0\vc\include\string.h(197) : see declaration of 'strtok'
file.cpp
Generating Code...
fnc.obj : error LNK2005: "struct LIMITS1 Limits1" (?Limits1@@3ULIMITS1@@A) already defined in file.obj
fnc.obj : error LNK2005: "struct LIMITS2 Limits2" (?Limits2@@3ULIMITS2@@A) already defined in file.obj
parse3.obj : error LNK2005: "struct LIMITS1 Limits1" (?Limits1@@3ULIMITS1@@A) already defined in file.obj
parse3.obj : error LNK2005: "struct LIMITS2 Limits2" (?Limits2@@3ULIMITS2@@A) already defined in file.obj
stdafx.obj : error LNK2005: "struct LIMITS1 Limits1" (?Limits1@@3ULIMITS1@@A) already defined in file.obj
stdafx.obj : error LNK2005: "struct LIMITS2 Limits2" (?Limits2@@3ULIMITS2@@A) already defined in file.obj
fnc.obj : error LNK2019: unresolved external symbol "void __cdecl error(char *)" (?error@@YAXPAD@Z) referenced in function "struct LIMITS1 __cdecl getNumberFromRegex(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,char)" (?getNumberFromRegex@@YA?AULIMITS1@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@D@Z)
Debug\parse3.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Can you find what's wrong?
Last edited on
> I have some problem with unresolved external and cannot find out how this happens.
http://www.cplusplus.com/forum/general/113904/


> "struct LIMITS1 Limits1" (?Limits1@@3ULIMITS1@@A) already defined in file.obj
struct LIMITS1 { int min; int max; } Limits1;
Don't define variables in header files.
I don't see how you are using it, but if you want a global variable that is shared between compilation units, declare it as extern in the header, and define it in just one source file
1
2
3
4
5
//header.h
extern int foo;

//source.cpp
int foo = 42;



1
2
limits.min = (int) strtok(var,"-");
	if ( limits.min != NULL)

¿what do you think you are doing there?
The last command: there should be a string in var like 12-15 and I need to set limits.min=12 and limits.max=15

but I did not get to this point to check it

Also new error:
fnc.h(2): error C2146: syntax error : missing ';' before identifier 'getNumberFromRegex'
Last edited on
> and I need to set limits.min=12 and limits.max=15
then do that
¿how is limits.min = (int) strtok(var,"-"); even close to limits.min=12?

> Also new error:
If you have modified your code, then show the updated code.

> but I did not get to this point to check it
I'm not sure what you are trying to say.

By the way var = strncpy(var, cs+2, sizeof(cs)-1);
First, 'var' is pointing to a not mutable string
Second, that string does not had reserved enough space to write all that
Third, sizeof(cs) is a constant
I found the error.

problem was that in header there was

1
2
3
struct LIMITS1 { int min; int max; } Limits1;
struct LIMITS2 { int xmin; int xmax; int ymin; int ymax; } Limits2;
LIMITS1 getNumberFromRegex(std::string s, char ch);


and in cpp there was:
1
2
3
4
LIMITS1 getNumberFromRegex(std::string s, char ch)
{
function definition here
}


I recalled that you said no definitions in header file so I moved it to cpp and removed the declaration line
 
struct LIMITS1 { int min; int max; } Limits1;

and now it works.
But it is not fully clear to me why it does not work with the declaraton in header file.
But it is not fully clear to me why it does not work with the declaraton in header file.

Because you've both declared and defined struct LIMITS1 {...} Limits1; and struct LIMITS2 {...} Limits2 in the header file.

The problem is struct LIMITS1 {...} Limits1 and struct LIMITS2 {...} Limits2 are both declarations and definitions. You include the header file in multiple .cpp files, you therefore have multiple definitions visible to the linker, which is what it is complaining about.

The proper way to do this is to declare only the struct in the header file.
struct LIMITS1 { int min; int max; }; // note: def of Limits1 removed
Then in the .cpp file, you can define the struct variable.
LIMITS1 Limits1;

Not clear from your code if you need Limits1 to be global and visible in multiple compilation units (not a good idea). If so, you can do the following:
In the .h file:
extern LIMITS1 Limits1;
Then in one and only one .cpp define the structure variable.
LIMITS1 Limits1;
Last edited on
Thanks for explanation. Great experience.
Problem which I did not noticed before because of other errors occurred.

I did exactly as you say, but I got new error in main file where I am using getNumberFromRegex . I got

Error C3861: 'getNumberFromRegex': identifier not found

fnc.h:
1
2
3
void error(char * str);
struct LIMITS1 { int min; int max; };
// LIMITS1 getNumberFromRegex(std::string s, char ch); 


fnc.cpp:
1
2
3
4
5
6
7
#include "stdafx.h"
LIMITS1 Limits1;
LIMITS1 getNumberFromRegex(std::string s, char ch)
{
char * var = "";
// code there ...
}


Now, if I uncomment the line with declaration of getNumberFromRegex in fnc.h
I got this error:

fnc.obj : error LNK2019: unresolved external symbol "void __cdecl error(char *)" (?error@@YAXPAD@Z) referenced in function "struct LIMITS1 __cdecl getNumberFromRegex(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,char)" (?getNumberFromRegex@@YA?AULIMITS1@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@D@Z)

So if I do not declare function I have error. I I declare function with LIMITS1 type I got error too. I am confused again.
Last edited on
Before you can use something, it must be declared.

1
2
3
4
5
6
7
8
9
10
11
//definitions.h
#ifndef DESTINATION_CONST
#define DESTINATION_CONST

#define ERR_regex ": bracket not found in regex: {y:number} or {x:number}"
#define ERR_regex_ "Incorrect syntax in -r regex. Expression expected: {x:number}_{y:number} or {y:number}_{x:number} or similar."

struct LIMITS1 { int min; int max; }; //note, no variable creation.
struct LIMITS2 { int xmin; int xmax; int ymin; int ymax; };

#endif 
1
2
3
4
5
//fnc.h
#include "definitions.h" //so we get LIMITS1
#include <string> //so we get std::string
void error(char * str);
LIMITS1 getNumberFromRegex(std::string s, char ch);
1
2
3
4
5
6
7
8
9
10
//fnc.cpp
#include "definition.h" //so we get the macros
#include "fnc.h" //if you need the prototypes
#include <iostream>
#include <cstdlib>
void error(char * str, int error){
    std::cerr << str; //cerr is the error stream
    //_getch(); //I hate these programs that don't terminate when they end
    exit(error);
}


> unresolved external symbol
I already told you about that, ¿where is 'error()' defined?
It still does not work.

The error says unresolved external symbol "void __cdecl error(char *)" (?error@@YAXPAD@Z) referenced in function "struct LIMITS1 __cdecl getNumberFromRegex

It wants definition or declaration of the error function. But it is declared in header which is included and it is defined in cpp...

Did you try the code you pasted? I think you should have the same error like me.

I got it solved. How? Notice the difference in arguments between the two functions error(...).

Well, FINALLY I MUST REMEBER. NOT ONLY THE NAME OF FUNCTION WHAT I HAVE TO CHECK BUT ALSO THE CORRECT ARGUMENTS. THE COUNT OF ARGUMENTS ANT THE TYPE OF THE ARGUMENTS MUST BE SAME OTHERWISE COMPILER CANNOT FIND THE FUNCTION BECAUSE IT IS NOT DEFINED REALLY.

That's why it took to me so long. But nobody told me this before and I think I did not read this anywhere before, being it tutorial. But this is good advice now for me I must remember well. Good practice!

And pls, help me to solve last problem. Is it possible to pass constant within function parameter or not?
help me to solve last problem. Is it possible to pass constant within function parameter or not?


Yes, it is possible to pass a const parameter and is recommended if the function does not change the argument.

1
2
3
int func (const Foo & foo)  // foo passed by reference as const argument
{  return 0;
}


Not sure if that's exactly what you were asking.
Last edited on
And Foo is type?

Here I have defined errors:

1
2
#define ERR_regex ": bracket not found in regex: {y:number} or {x:number}"
#define ERR_regex_2 "Incorrect syntax in -r regex. Expression expected: {x:number}_{y:number} or {y:number}_{x:number} or similar." 

Then in the declaration what should I replace Foo with?

void error(const Foo & error, int * eno);

And implementation

1
2
3
4
void error(const Foo & error, int * eno){
cout << "error" << error;
exit(eno);
}

foo is not a type. programmers use it for examples. here it is meant to show any datatype that can be passed by reference
This is exactly what I mean. how to refer to the ERR_regex or ERR_regex_2 constant?
Pages: 12