473,396 Members | 1,998 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

static keyword in non-class functions?

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...

Nov 17 '05 #1
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
Nov 17 '05 #2

"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?
Nov 17 '05 #3
"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


Nov 17 '05 #4
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"
Nov 17 '05 #5
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
Nov 17 '05 #6

"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.
Nov 17 '05 #7
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
Nov 17 '05 #8
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
Nov 17 '05 #9

"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?
Nov 17 '05 #10
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
Nov 17 '05 #11

"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.
Nov 17 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: A | last post by:
Hi, Consider this code: //Header File - Foo.h int i = 0; // non-static global variable class Foo{ ...
9
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, ...
12
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; };
3
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...
11
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. ...
14
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,...
4
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"
8
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...
27
by: arkmancn | last post by:
Any comments? thanks. Jim
12
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...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
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...
0
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...
0
marktang
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,...
0
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...
0
Oralloy
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,...
0
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...
0
tracyyun
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...
0
agi2029
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,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.