I have a test class declared in a header file and defined in a separate file. The class must compile differently under Windows, so i use #if defined ( _WINDOWS_ ). When I compile the cpp file which also contains #if defined ( _WINDOWS_ ), the file is compiled as if the symbol _WINDOWS_ was not defined, although it is defined in another file. When I compile the code, I am getting the following error:
Error Code : error lnk2019 unresolved external symbol public
source code
// test.h
class Test
{
public:
#if defined (_WINDOWS_)
void printwindow();
#endif
void notwindows();
};
//test.cpp
#include "test.h"
#if defined (_WINDOWS_)
void Test::printwindow()
{
cout << "i am windows ";
}
#endif
void test::notwindows()
{
cout << " not windows " ;
}
//main.cpp
#include "windows.h"
#include "test.h"
void main()
{
test t1 ;
t1.printwindow() // OK I have declared function so my _WINDOWS_ is available but when i run it i get
}
Error Code : error lnk2019 unresolved external symbol public
NOTE : if i define the function directly it works without any problem
// test.h
class Test
{
public:
#if defined (_WINDOWS_)
void printwindow(){couT << "i am window" }
#endif
void notwindows();
};
but I don't like this method. I prefer to define them in separate files (h and cpp).
It would be better for you to use _WIN32 instead of _WINDOWS_ for your conditional compilation test. _WINDOWS_ is defined only if windows.h has been included, while the compiler automatically defines _WIN32 for any build for a Windows target, regardless of what headers are included. In your situation, _WINDOWS_ is defined when you compile main.cpp but not when you compile test.cpp becuase test.cpp doesn't include windows.h.
Also, the _WINDOWS_ macro definition is an implementation detail of the windows.h header, and is not guaranteed to be used. For example, the MinGW version of windows.h does not define _WINDOWS_.
You need to include windows.h in your test.cpp file
When you compile test.cpp it does not have the _WINDOWS_ symbol defined. So it creates an object file without the windows function.
Then in test.hpp it uses the symbol because you included windows.h in main.cpp
If you change the order of the includes it will behave differentially. You should rethink the way how you want to select the windows version which does not depend on the order of includes (for example see the other answer about _WIN32_).
You can not change the code in an already compiled object file (test.cpp) using some define in another code file (main.cpp)
Related
I'm using Xcode to build a C++ project.
But I don't understand the error message:
"Apple Mach-O linker command failed with exit code 1"
I found that #include is the reason.
I have two .cpp file which include a same .h file. If I remove #include of one, it will be build successfully.
Other header files are fine expect the header file described above. I already used "ifndef".
#ifndef include guards only work at the level of the translation unit (usually a single source file).
If you define the same object twice in two translation units, that won't be fixed by include guards but the linker will complain bitterly when you try to combine the two object files into a single executable.
I suspect your situation is akin to:
hdr.h:
#ifndef HDR_H
#define HDR_H
void rc(void);
int xyzzy;
#endif
prog1.c:
#include "hdr.h"
#include "hdr.h"
int main (void) { rc(); return xyzzy; }
prog2.c:
#include "hdr.h"
void rc(void) { xyzzy = 0; }
In a situation like that, the include guard will prevent the header being included twice in prog1.c but it will still be included in both prog1.c and prog2.c, meaning that each will have a copy of xyzzy.
When you link them together, the linker will not like that.
The solution is to not define things in headers but to merely declare them there, leaving the definition for a C file:
hdr.h:
#ifndef HDR_H
#define HDR_H
int rc(void);
extern int xyzzy; // declare, not define
#endif
prog1.c:
#include "hdr.h"
#include "hdr.h"
int main (void) { rc(); return xyzzy; }
prog2.c:
#include "hdr.h"
int xyzzy; // define
int rc(void) { xyzzy = 0; }
Declarations are things like function prototypes, extern variables, typedefs and so on (simplistically, things that declare something exists without actually creating an "object").
Definition are things that create "objects", like non-extern variables and so on.
You need to track down what "object" is being defined twice (the linker output should have something like doubly-defined symbol 'xyzzy') and then make sure it's not defined in the header.
I am trying to use a global variable from separated .cpp files. I have got an init.h file as:
//init.h
#ifndef init
#define init
int a = 3;
#endif
I have got an init.cpp file as:
//init.cpp
#include init.h
Then finally my main.cpp file is:
//main.cpp
#include "init.h"
int main(void)
{
while(1)
{
}
}
After this, I get the error:
1>init.obj : error LNK2005: "int a" (?a##3HA) already defined in main.obj
1> ..deneme.exe : fatal error LNK1169: one or more multiply defined symbols found
Why my #infdef control does not solve this problem?. I also tried using #pragma once but I got same error. What is wrong with my code?
You need to mark your variable as extern and define it only once in an implementation file.
As the code is now, you're breaking the one definition rule. The include guards don't help in this case, since all translation units that include that header re-define the variable.
What you actually need:
//init.h
#ifndef init
#define init
extern int a;
#endif
and the definition:
//init.cpp
#include "init.h"
int a = 3;
Also, think twice before using globals. What is it that you're actually trying to achieve?
I'm getting
error LNK2005: "bool __cdecl hasLogin(void)" (?hasLogin##YA_NXZ) already defined in B.obj
error. func is declared in B.cpp file, and it's called from A.cpp file. B.cpp is included in A.cpp. Google says that it's not good to include cpp in antother cpp. If I copy/paste func in A.cpp there's no problem. How to solve tsis problem correctly?
PS I'm new to c++, so forgive if the question is dump.
Create a header file named B.h and add the following function declaration:
#ifndef _B_HEADER_
#define _B_HEADER_
bool hasLogin(void);
#endif
Instead of #include "B.cpp" in A.cpp use #include "B.h".
You should generally declare your classes/functions in .h (header) files, and implement them in .cpp files. It's also usually a good idea to put include guards in your .h files so including them multiple times is not a problem. That way your .cpp files can include any .h file without causing any conflicts.
An example; test.h
#ifndef TEST_H
#define TEST_H
class test {
public:
void bop();
}
bool hasLogin();
#endif
and the corresponding .cpp file
#include <iostream>
#include "test.h"
void test::bop() {
std::cout << "bop" << std::endl;
}
bool hasLogin() {
return false;
}
write #pragma once in the .cpp//.h where the error is coming, sometimes it avoids the error.
I need to create structure like this:
// file main.h:
#pragma once
#ifndef _MAIN_H
#define _MAIN_H
#include <iostream>
#include "first.h"
#include "second.h"
#endif
// -----------------
// file first.h:
#pragma once
#ifndef _FIRST_H
#define _FIRST_H
#include "main.h" // because of using SomeFunction() in first.cpp
int SomeVar; // used in first.cpp
#endif
// -----------------
// file second.h:
#pragma once
#ifndef _SECOND_H
#define _SECOND_H
#include "main.h" // because of using SomeVar in second.cpp
int SomeFunction(); // implemented in second.cpp
#endif
// -----------------
By logic, if main.h will be compiled first, then each of this headers will be included only once and all variables/functions will be defined normally.
For example, this configuration compiled normally in IAR C++ Compiler, if set up in options "preinclude file" (not precompiled) to main.h.
But, in Visual Studio 2010 same structure causes linker errors like:
1>second.obj : error LNK2005: "int SomeVar" (?SomeVar##3HA) already defined in first.obj
1>second.obj : error LNK2005: "int SomeFunction" (?SomeFunction##3HA) already defined in first.obj
I think because of including files in alphabetic order. Apparently pragma- and define-guards are ignored by linker.
Errors can be fixed by additional header and external variables definitions, but this is hard and wrong way.
Question is: What should i do?
int SomeVar; // used in first.cpp
Variables should never be defined in headers. They should be declared with extern:
extern int SomeVar; // used in first.cpp
Then you can actually define them in "first.cpp" with int SomeVar;.
Also, "first.h" does not need to include "main.h". Headers should only include files if the definitions in that header absolutely need the contents of those files. The definitions in "first.h" do not need anything in "main.h". Therefore, it should not include it.
If "first.cpp" needs to include something from "second.h", then it is the responsibility of "first.cpp" to include it.
In the header file use extern keyword as:
//first.h
extern int SomeVar; //extern tells the compiler that definition is elsewhere
Then in .cpp file define it and use it:
//first.cpp
int SomeVar; //definition is here
As for SomeFunction, have you defined it header file itself? Re-check it. :-)
I had a very weird problem with precompile header. The linker generates LNK2019: unresolved external symbol error when I implement method in .cpp file. However, the program could be compiled if I implement method in .h file. I happened to find out a solution but I have no idea about the root cause of this error.
My project structure looks like this
Solution
->project 1
->project 2
Project 1 has 3 files. A.h, A.cpp and stdafx.h
file A.h
#pragma once
class A
{
public:
int num;
A();
};
file A.cpp
#include "stdafx.h"
A::A()
{
num = 2;
}
file stdafx.h
...
#include "A.h"
...
In project 2. I want to use A class.
file whatever.cpp
#include "stdafx.h"
#include "../Project1/A.h"
...
A* a_obj = new A();
...
In compile time, the linker reports unresolved external symbol error for the A construction function. If I implement the constructor in A.h file. the project2 could be successful complied. I want to know, why can not put the implementation in A.cpp file? What is the right way to organize precompile header?
Thank you
Project 2 does not include the definition of the A constructor - one way to give it visibility of this is to include the definition in the header file (which you did).
Another way would be to include the A.cpp file in project 2.
A third way would be to export the A class, or the A constructor using a .def file or using the dllexport directive.
Put this in the precompiled header file:
// set up export import macros for client project use
// define the symbol "PROJ1" before including this file in project 1 only
// leave it undefined for other projects
#ifdef PROJ1
#define DLLEXP __declspec(dllexport)
#else
#define DLLEXP __declspec(dllimport)
#endif
Then declare the A class in the A header:
DLLEXP class A
{
public:
A();
...
};
Or:
class A
{
public:
DLLEXP A();
...
};