2
votes

I have created a sample c++ project under Visual Studio 2010 with following files.

A.h

#ifndef A_H
#define A_H

#include <iostream>

void foo();

#endif

A.cpp

#include "A.h"

void foo()
{
    int a = 1;
}

main.cpp

#include "A.h"

int main(int argc, char* argv[])
{
    foo();    

    return 0;
}

I am getting the following output after build:

1>------ Build started: Project: opengl_test, Configuration: Debug Win32 ------

1> main.cpp

1> A.h

1> A.cpp

1> Generating Code...

1>Debug\A.obj : warning LNK4042: object specified more than once; extras ignored

1>main.obj : error LNK2019: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ) referenced in function _main

1>C:\Users\alp\Projects\Test Samples\opengl_test\Debug\opengl_test.exe : fatal error LNK1120: 1 unresolved externals

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

What is the reason for this error?

4
For what it's worth, I cannot repro this in a new, empty project in VS 2010. I just added your 3 code files (A.h, A.cpp, and main.cpp) and then compiled. Works fine, no errors. So the question is, what's different about your setup than mine (and what you've described in the question)?Cody Gray
@CodyGray I created a new solution and added these files to the project and now builds without any errors or warnings. The thing is the project was first referencing opengl/glut functions and at some point visual studio started giving me this LNK2019 error and it wasn't giving it all the time as I described here stackoverflow.com/questions/8996385/… . Then it started giving it always. So I converted the project into this simple form and it kept giving the error. I don't know what caused the configuration difference between the 2 projects.Alp Hancıoğlu
So perhaps this question is relevant. Does the OpenGL libraries by chance contain a file with the name A that could be messing the linker up if/when it flattens the hierarchy?Cody Gray
In that question poster has a directory structure for the files. In my project I didn't have any directory structure, every file was in the same folder with the .vcxproj file. I tried that solution but it didn't resolve the warning. The file's name wasn't A before(it was Listing2_2 which I am pretty confident don't exist in opengl) and I changed it to A to make it simple for the postAlp Hancıoğlu

4 Answers

3
votes

I think what happened is that A.h was in the Source group of the project rather than the Header group, so it was compiled as if it were a .cpp. Since both A.cpp and A.h will generate an object file A.obj, the last one to compile is the only one that got linked. I believe the last one compiled was A.h, which didn't have an implementation of foo(), thus the linker couldn't find it.

0
votes

EDIT: Nevermind the original answer (below), I believe what you're looking for may be here: Visual Studio 2010's strange "warning LNK4042"

Original answer (not the problem, but maybe sound advice?): Your header should have guards around it, otherwise it will be defined each time it is called, and cause redefinitions.

#ifndef A_H
#define A_H

#include <iostream>

void foo();

#endif //A_H
0
votes

First, you need to include "stdafx.h" in your "a.cpp" file before the line for including "a.h".

Second, it is better you add "a.h" into your project "Header Files" and add "a.cpp" into your "Source Files".

Then it will be compiled without error! Good luck.

BTW, the reason to include "stdafx.h" is that by default the project use pre-compiled headers that is why the compiler looks for "stdafx.h".

If you want, you can disable the "precompiled Header" then you don't need "stdafx.h" and everything will be fine.

0
votes

The code works when I created a new project. I am not sure but the reason of the error might be that I added the folder "C:\Program Files\Microsoft SDKs\Windows\v7.1\Include" to the included directories at the project settings and Visual Studio already included the folder "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include"(which is for the 32 bit programs) by default. So there might be a clash because of that. I added the opengl header files only to the Program Files(x86) include folder, removed the include for 64 bit Program Files folder and the opengl code seems to be working now.