Hi,
Why do I need to define a function as static (inside a .h file) to avoid the
following linker error?
CSession error LNK2005: "void __stdcall AllocString(unsigned short *
*,unsigned int)" (?AllocString@@YGXPAPAGI@Z) already defined in stdafx.obj
I know that the MSDN talks about this, but not why it is needed.
ms-help://MS.MSDNQTR.2005APR.1033/vccore/html/LNK2005.htm
and b.t.w. the file is included only once and it has #pragma once
Thanks... 11 1427
Egbert Nierop (MVP for IIS) wrote: Hi,
Why do I need to define a function as static (inside a .h file) to avoid the following linker error?
CSession error LNK2005: "void __stdcall AllocString(unsigned short * *,unsigned int)" (?AllocString@@YGXPAPAGI@Z) already defined in stdafx.obj
I know that the MSDN talks about this, but not why it is needed. ms-help://MS.MSDNQTR.2005APR.1033/vccore/html/LNK2005.htm
and b.t.w. the file is included only once and it has #pragma once
Thanks...
C and C++ have a rule known as the "one definition rule". Under this
rule, each function may only have one definition in a particular
program. If you have two different source files that include the header
you mention, then your program will actually have two definitions of
AllocString available to it, one in each of the source files, which
causes the linker to complain (when linking, it tries to resolve all
references to a function to the definition of that function, but you
have two definitions, so it doesn't know which one to pick).
Static "fixes" the problem since then the definition of AllocString is
private to the two source files that use it, but you end up with two
independent copies of AllocString, one in each source file - in effect,
you now have two different AllocString functions that happen to share
the same name.
Other fixes include:
- Move the _definition_ of AllocString out of the header and into a
source file. Obviously the declaration should stay in the header.
- Put "inline" in front of the function declaration.
Note that #pragma once/include guards/etc. don't help here, since that
only ensures that a header is only included once for a particular source
file, not across the whole program.
Tom
"Tom Widmer" <to********@hotmail.com> wrote in message news:el**************@TK2MSFTNGP15.phx.gbl... Egbert Nierop (MVP for IIS) wrote:
Note that #pragma once/include guards/etc. don't help here, since that only ensures that a header is only included once for a particular source file, not across the whole program.
Though I'm not sure about the pragma, why wouldn't include guards
work? They're based on compiler directives. If the define is true,
it should jump to the #endif. If this weren't true, how could templates
work when their definitions are all in the header file? Does the
compiler treat non class templates differently somehow?
"Tom Widmer" <to********@hotmail.com> wrote in message
news:el**************@TK2MSFTNGP15.phx.gbl... Egbert Nierop (MVP for IIS) wrote: Hi,
Why do I need to define a function as static (inside a .h file) to avoid the following linker error?
CSession error LNK2005: "void __stdcall AllocString(unsigned short * *,unsigned int)" (?AllocString@@YGXPAPAGI@Z) already defined in stdafx.obj
I know that the MSDN talks about this, but not why it is needed. ms-help://MS.MSDNQTR.2005APR.1033/vccore/html/LNK2005.htm
and b.t.w. the file is included only once and it has #pragma once
Thanks... C and C++ have a rule known as the "one definition rule". Under this rule, each function may only have one definition in a particular program. If you have two different source files that include the header you mention, then your program will actually have two definitions of AllocString available to it, one in each of the source files, which causes the linker to complain (when linking, it tries to resolve all references to a function to the definition of that function, but you have two definitions, so it doesn't know which one to pick).
Static "fixes" the problem since then the definition of AllocString is private to the two source files that use it, but you end up with two independent copies of AllocString, one in each source file - in effect, you now have two different AllocString functions that happen to share the same name.
Other fixes include: - Move the _definition_ of AllocString out of the header and into a source file. Obviously the declaration should stay in the header. - Put "inline" in front of the function declaration.
Thanks...
This solved my 'problem' :)
I did not know, the compiler worked like this. So I only include the .h file
while the .cpp 'seems' unreferenced in the project.
Note that #pragma once/include guards/etc. don't help here, since that only ensures that a header is only included once for a particular source file, not across the whole program.
Tom
Duane Hebert wrote: Though I'm not sure about the pragma, why wouldn't include guards work? They're based on compiler directives. If the define is true, it should jump to the #endif. If this weren't true, how could templates work when their definitions are all in the header file? Does the compiler treat non class templates differently somehow?
This is the linker error. In the following example the linker will
notice that problematic function is defined twice.
First.cpp
---------
#include "ProblematicHeader.h"
Second.cpp
----------
#include "ProblematicHeader.h"
Duane Hebert wrote: "Tom Widmer" <to********@hotmail.com> wrote in message news:el**************@TK2MSFTNGP15.phx.gbl... Egbert Nierop (MVP for IIS) wrote:
Note that #pragma once/include guards/etc. don't help here, since that only ensures that a header is only included once for a particular source file, not across the whole program.
Though I'm not sure about the pragma, why wouldn't include guards work? They're based on compiler directives. If the define is true, it should jump to the #endif. If this weren't true, how could templates work when their definitions are all in the header file? Does the compiler treat non class templates differently somehow?
Yes - Templates are special in that the compiler is required to merge
multiple definitions of a template function or template class, as long as
they're all the same (otherwise it's an ODR - One Definition Rule -
violation). While templates need not be all inline (though they frequently
are), they get essentially the same treatment from the compiler as an inline
function that wasn't in fact inlined (since the compiler is free to ignore
any inline suggestion that you give, and routinely does so in debub builds).
-cd
"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam > wrote in message
news:e3**************@TK2MSFTNGP14.phx.gbl... Yes - Templates are special in that the compiler is required to merge multiple definitions of a template function or template class, as long as they're all the same (otherwise it's an ODR - One Definition Rule - violation). While templates need not be all inline (though they frequently are), they get essentially the same treatment from the compiler as an inline function that wasn't in fact inlined (since the compiler is free to ignore any inline suggestion that you give, and routinely does so in debub builds).
Thanks. But I'm still not seeing why header guards don't work. Once
a header guard is passed, shouldn't the code in the header be read
once and the next time it's seen shouldn't the #ifndef/#endif take it
out of the picture? Is this something that happens only for free
functions? If you put them in a namespace does this solve the
problem?
Like I said before, I don't remember ever having free functions
defined in a header file (except for templates) I'm just curious
why this would be a problem. Thanks for the explanation.
Duane Hebert wrote: Thanks. But I'm still not seeing why header guards don't work. Once a header guard is passed, shouldn't the code in the header be read once
Once per unit, not once per project. If you define a function in a
header file H.h:
#pragma once
int MyFunc() { return 0; }
you can still include it from two different units:
//A.cpp
#include "H.h"
//B.cpp
#include "H.h"
which results in duplicate definition within the same project. A.obj
will contain MyFunc, and B.obj will contain it too, thus the linker will
complain about double definition. It's a linker error, not a compiler error.
Rule of thumb: Every non-member function implemented in the header file
must be explicitly declared inline, or the implementation must be moved
to the .cpp file, otherwise you run the risk of double definition.
Tom
Tamas Demjen wrote: Rule of thumb: Every non-member function implemented in the header file must be explicitly declared inline, or the implementation must be moved to the .cpp file, otherwise you run the risk of double definition.
Correction: Every non-member non-template function [...]
Tom
"Tamas Demjen" <td*****@yahoo.com> wrote in message news:OG**************@tk2msftngp13.phx.gbl... which results in duplicate definition within the same project. A.obj will contain MyFunc, and B.obj will contain it too, thus the linker will complain about double definition. It's a linker error, not a compiler error.
Rule of thumb: Every non-member function implemented in the header file must be explicitly declared inline, or the implementation must be moved to the .cpp file, otherwise you run the risk of double definition.
Thanks. I never realized that. I normally put the definitions in cpp files
anyway. BTW, what's this #pragma once? I imagine that it functions
like header guards but is it portable?
Duane Hebert wrote: BTW, what's this #pragma once? I imagine that it functions like header guards but is it portable?
Yes, it does.
No, it's not.
-cd
"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam > wrote in message
news:OR**************@TK2MSFTNGP09.phx.gbl... Duane Hebert wrote: BTW, what's this #pragma once? I imagine that it functions like header guards but is it portable?
Yes, it does.
No, it's not.
Thanks. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: A |
last post by:
Hi,
Consider this code:
//Header File - Foo.h
int i = 0; // non-static global variable
class Foo{
...
|
by: vp |
last post by:
Can I safely assume that all static variables are initialized as NULL
or zero, depending on the types of the variables, no matter on which
platform that app is compiled ?
Thanks for your help,
...
|
by: Michael B Allen |
last post by:
Is it legit to modify static data like the following code?
#include <stdlib.h>
#include <stdio.h>
struct tbl {
int i;
char *s;
};
|
by: Bas Wassink |
last post by:
Hello there,
I'm having trouble understanding a warning produced by 'splint', a
code-checker. The warning produced is:
keywords.c: (in function keyw_get_string)
keywords.c:60:31: Released...
|
by: pemo |
last post by:
Could someone tell me if I have this right please?
Given this definition:
void someFunc(char a){}
The 'static' says that a will not be a NULL pointer, and will always
** 10 elements.
...
|
by: John Goche |
last post by:
Hello,
The extern keyword can be used in C and C++
to share global variables between files by
declaring the variable in header file and
defining it in only one of the two files.
For example,...
|
by: nospam_timur |
last post by:
Let's say I have two files, myfile.h and myfile.c:
myfile.h:
int myfunction(int x);
myfile.c:
#include "myfile.h"
|
by: Rajesh |
last post by:
Based on my understanding static members do not have access to non-
static members. In the below example static method 'name' accessing
non-static method creating reference. Seems to me it is not...
|
by: arkmancn |
last post by:
Any comments? thanks.
Jim
|
by: sergey.lukoshkin |
last post by:
Hello everyone!
My task is in converting numbers from string to int variables. I used
istringstream to perform it.
So I wrote simple test function. But it doesn't work as I expected
because...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
| |