If you want both to reference the same variable, one of them should have int k;
, and the other should have extern int k;
For this situation, you typically put the definition (int k;
) in one .cpp
file, and put the declaration (extern int k;
) in a header, to be included wherever you need access to that variable.
If you want each k
to be a separate variable that just happen to have the same name, you can either mark them as static
, like: static int k;
(in all files, or at least all but one file). Alternatively, you can us an anonymous namespace:
namespace {
int k;
};
Again, in all but at most one of the files.
In C, the compiler generally isn’t quite so picky about this. Specifically, C has a concept of a «tentative definition», so if you have something like int k;
twice (in either the same or separate source files) each will be treated as a tentative definition, and there won’t be a conflict between them. This can be a bit confusing, however, because you still can’t have two definitions that both include initializers—a definition with an initializer is always a full definition, not a tentative definition. In other words, int k = 1;
appearing twice would be an error, but int k;
in one place and int k = 1;
in another would not. In this case, the int k;
would be treated as a tentative definition and the int k = 1;
as a definition (and both refer to the same variable).
description | title | ms.date | f1_keywords | helpviewer_keywords | ms.assetid |
---|---|---|---|---|---|
Learn more about: Linker Tools Error LNK2005 |
Linker Tools Error LNK2005 |
11/04/2016 |
LNK2005 |
LNK2005 |
d9587adc-68be-425c-8a30-15dbc86717a4 |
symbol already defined in object
The symbol symbol was defined more than once.
This error is followed by fatal error LNK1169.
Possible causes and solutions
Generally, this error means you have broken the one definition rule, which allows only one definition for any used template, function, type, or object in a given object file, and only one definition across the entire executable for externally visible objects or functions.
Here are some common causes for this error.
-
This error can occur when a header file defines a variable. For example, if you include this header file in more than one source file in your project, an error results:
// LNK2005_global.h int global_int; // LNK2005
Possible solutions include:
-
Declare the variable
extern
in the header file:extern int global_int;
, then define it and optionally initialize it in one and only one source file:int global_int = 17;
. This variable is now a global that you can use in any source file by declaring itextern
, for example, by including the header file. We recommend this solution for variables that must be global, but good software engineering practice minimizes global variables. -
Declare the variable static:
static int static_int = 17;
. This restricts the scope of the definition to the current object file, and allows multiple object files to have their own copy of the variable. We don’t recommend you define static variables in header files because of the potential for confusion with global variables. Prefer to move static variable definitions into the source files that use them. -
Declare the variable selectany:
__declspec(selectany) int global_int = 17;
. This tells the linker to pick one definition for use by all external references and to discard the rest. This solution is sometimes useful when combining import libraries. Otherwise, we do not recommend it as a way to avoid linker errors.
-
-
This error can occur when a header file defines a function that isn’t
inline
. If you include this header file in more than one source file, you get multiple definitions of the function in the executable.// LNK2005_func.h int sample_function(int k) { return 42 * (k % 167); } // LNK2005
Possible solutions include:
-
Add the
inline
keyword to the function:// LNK2005_func_inline.h inline int sample_function(int k) { return 42 * (k % 167); }
-
Remove the function body from the header file and leave only the declaration, then implement the function in one and only one source file:
// LNK2005_func_decl.h int sample_function(int);
// LNK2005_func_impl.cpp int sample_function(int k) { return 42 * (k % 167); }
-
-
This error can also occur if you define member functions outside the class declaration in a header file:
// LNK2005_member_outside.h class Sample { public: int sample_function(int); }; int Sample::sample_function(int k) { return 42 * (k % 167); } // LNK2005
To fix this issue, move the member function definitions inside the class. Member functions defined inside a class declaration are implicitly inlined.
// LNK2005_member_inline.h class Sample { public: int sample_function(int k) { return 42 * (k % 167); } };
-
This error can occur if you link more than one version of the standard library or CRT. For example, if you attempt to link both the retail and debug CRT libraries, or both the static and dynamic versions of a library, or two different versions of a standard library to your executable, this error may be reported many times. To fix this issue, remove all but one copy of each library from the link command. We do not recommend you mix retail and debug libraries, or different versions of a library, in the same executable.
To tell the linker to use libraries other than the defaults, on the command line, specify the libraries to use, and use the /NODEFAULTLIB option to disable the default libraries. In the IDE, add references to your project to specify the libraries to use, and then open the Property Pages dialog for your project, and in the Linker, Input property page, set either Ignore All Default Libraries, or Ignore Specific Default Libraries properties to disable the default libraries.
-
This error can occur if you mix use of static and dynamic libraries when you use the /clr option. For example, this error can occur if you build a DLL for use in your executable that links in the static CRT. To fix this issue, use only static libraries or only dynamic libraries for the entire executable and for any libraries you build to use in the executable.
-
This error can occur if the symbol is a packaged function (created by compiling with /Gy) and it was included in more than one file, but was changed between compilations. To fix this issue, recompile all files that include the packaged function.
-
This error can occur if the symbol is defined differently in two member objects in different libraries, and both member objects are used. One way to fix this issue when the libraries are statically linked is to use the member object from only one library, and include that library first on the linker command line. To use both symbols, you must create a way to distinguish them. For example, if you can build the libraries from source, you can wrap each library in a unique namespace. Alternatively, you can create a new wrapper library that uses unique names to wrap references to one of the original libraries, link the new library to the original library, then link the executable to your new library instead of the original library.
-
This error can occur if an
extern const
variable is defined twice, and has a different value in each definition. To fix this issue, define the constant only once, or use namespaces orenum class
definitions to distinguish the constants. -
This error can occur if you use uuid.lib in combination with other .lib files that define GUIDs (for example, oledb.lib and adsiid.lib). For example:
oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject already defined in uuid.lib(go7.obj)
To fix this issue, add /FORCE:MULTIPLE to the linker command line options, and make sure that uuid.lib is the first library referenced.
Whiteha, include guard это те самые
C | ||
|
Защищают от множественного включения одного файла. Если, например, сделать
C | ||
|
И в этих хэдэрах подключается один и тот же заголовочныый файл, в котором не стоят инклуд гуарды, то собрать проект не выйдет.
Так что лучше их использовать всегда.
Директива #include просто подставляет содержимое файла. Так что сами представьте, что будет, если подставить содержимое одного файла дважды. Уж точно ничего хорошего
Сообщение от Whiteha
Насколько я помню расширение подключаемых файлов может быть хоть txt, тк препроцессор работает с текстовыми файлами, а какое им задать расширение это дело традиции
Совершенно верно. Однако, следует помнить, что иные способы могут вызвать кучу недоразумений и непониманий. Собственно отсюда и пошли традиции — чтобы все друг друга понимали.
Сообщение от Kuzia domovenok
Скажи, зачем мэйкфайлы человеку пытающемуся создать первый проект из двух файлов спп в MSVS? Инклуд стражи он уже использовал не там где надо.
То, что MSVS сама генерирует мэйкфайл или что-либо подобное не значит, что его нет или что этого человека можно обманывать, говоря о линкере как о всеумеющей тулзе. Это не так.
Не по теме:
Сообщение от Kuzia domovenok
Мне впадлу было.
Я так посмотрю с Вами часто такое.
- Remove From My Forums
-
Question
-
I recently installed VC++ 2005 EXP edition.
1) I created a project name Radius and created two new items hello.cpp and area.cpp.
2) area.cpp is the first item and hello.cpp is the second one.
3) When I build the project Radius, I got the error
LNK2005: _main already defined in area.obj
Can you guide me to fix the compilation error.
Thanks GKW82
Answers
-
This error is because of multiple definitions of main. You must have defined main in area.cpp as well as in hello.cpp. In C/C++ programs, you can write only one main per application.
Remove one definition of main and it should work fine.
Cheers
Привет!
Возникла проблема в VS 2017 с ошибкой линкования файлов (LNK2005), прикреплю скриншоты для наглядности.
В проекте 3 файла:
- MyForm.h — файл самой формы C++CLI, здесь я делаю #include «source.cpp», что скорее всего и падает, также здесь использую методы взаимодействия с формой типа openFileDialog и т.д.
spoiler
- Source.cpp — основной скрипт на 1.3к строк, мне нужно в MyForm.h вызвать вызвать функцию void solve() {…}, которая работает только в пределах стандартных библиотек и самого Source.cpp, не вызывая ничего «изнутри», для простоты все закомментировал и во всем файле оставил:
void solve() { // }
spoiler
- MyForm.cpp — нужен только для определения точки входа в приложение, там ничего не происходит.
spoiler
Возможно напутал с пространством имен или подключением, но если создать заголовок H1.h, где написать:
#include "source.cpp"
void solve();
— тоже не рабит(
В гугле нашел информацию про переопределение в нескольких файлах одной и той же функции, но у меня всего 1 файл с определением и подключаю его всего 1 раз;
Если мысль, что ошибка из-за того, что подключаю как-то так: Source.cpp -> MyForm.h -> MyForm.cpp…
Подскажите, как правильно!