ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm trying to use the "namespace" feature of C++ but I'm getting linker errors. It seems like the fix should be trivial but I don't know how to do it.
Here's what I'm doing:
-------- Main File --------------------
#include (the standard stuff)
Then I also have "outer_file.h" and "outer_file.cpp" but they're the same as the inner_files with the exception that the namespace is now "outer". When I compile it, I get a linker error saying that
This is not a namespace related problem. The problem is that you are defining array "A" in an include file ( inner_file.h ) and then including that file in two c++ files. This causes the multiple definition.
To fix, change the "A" definition to a declaration by placing "extern" in front of it and define "A" one time in a c++ file ( inner_file.cpp seems like the sensible choice). This should take care of the "already exists" error.
Thanks a lot Dave. I figured something like that was up. Before reading your reply, I was able to get it to compile and link when I added
#pragma once
to all my header files AND I had to declare the array A to be static in both header files. Things seemed to work fine, but I don't really like my fix. Are there any potential downfalls of doing things this way?
Anyways, I'll go ahead and modify the header file declaration to an extern and actually define it in my cpp file.
I think the technique you described ( "pragma once" & static declarations ) would have gotten a clean compile and link even without the "pragma once". Just making the declarations static would be enough for a clean compile & link.
The downfall is that this does *not* give you the same meaning as extern declaration in include file with definition in cpp file. If the array definition is static then each compilation that includes this definition results in an independently defined "A" array. Changes made in the "A" array in one cpp file will have nothing to do with changes made in another cpp file.
I know you are already fixed and on your merry way... however I thought I give my 2 cents.
You'll notice the following alot in header files:
Code:
#ifndef HEADERFILENAME_H
#define HEADERFILENAME_H
<insert the meat and potatoes of your header here>
#endif
This ensures that your header file will be safe when linked into a large project where multiple objects might be including it that later get linked together. I pretty much consider it standard practice to declare headers in this way and you'll notice many others use this method as well.
Thanks "jtshaw" for your tip on the macro guard. Thank you Dave for explaining the downfall of static, but I'm afraid I'm still a bit confused.
What do you mean by:
Quote:
"each compilation that includes this definition results in an independently defined "A" array"
I thought static meant that there should be only one. So let me see if I understand you correctly:
Let "f1.cpp" and "f2.cpp" be two source files that include "header.h" ("header.h" contains a static array A[10]). Let "main.cpp" be the main program. Now if I do this:
Let "f1.cpp" and "f2.cpp" be two source files that include "header.h" ("header.h" contains a static array A[10]). Let "main.cpp" be the main program. Now if I do this:
#include "header.h"
#include <iostream>
using namespace std;
void initA1()
{
for (int i = 0; i < COUNT; ++i)
{
A[i] = 1;
}
}
void showA1()
{
cout << "f1.cpp: A Array:" << endl;
for (int i = 0; i < COUNT; ++i)
{
cout << "A[" << i << "] = " << A[i] << endl;
}
cout << endl;
}
f2.cpp
Code:
#include "header.h"
#include <iostream>
using namespace std;
void initA2()
{
for (int i = 0; i < COUNT; ++i)
{
A[i] = 2;
}
}
void showA2()
{
cout << "f2.cpp: A Array:" << endl;
for (int i = 0; i < COUNT; ++i)
{
cout << "A[" << i << "] = " << A[i] << endl;
}
cout << endl;
}
The main() routine calls initA1() and initA2() . If the arrays were the same, the second init would overwrite the results of the first. However, as the calls to showA1() and showA2() demonstrate, the arrays are distinct. Here are the compile and output results:
The static definition means that the scope ( i.e. visibility ) is limited to "only one" object file. This is what permits different definitions in different object files.
Thanks Dave again for all your help. That example clears things up. I thought static applied to the scope of the entire program. So here's a related question:
Suppose I had a class (SomeClass) and I define a static member variable called (SomeClass.instanceN) and increment this by one each time an instance is created. Then, does this mean that I cannot count on this variable to give the true number of instances across multiple CPP files... How would one keep track of the number of instances then?
A static data member in a class retains the same value for all objects of the class at any given time, regardless
of what translation unit the object itself was created. When a program is running, it has no concept of source
files.
A static data member in a class retains the same value for all objects of the class at any given time, regardless
of what translation unit the object itself was created. When a program is running, it has no concept of source
files.
That's right. The static modifier has a different meaning for class member variables than it does for variables that are defined outside of any particular scope. I remember this being counter intuitive when I first learned c++ but you get used to it pretty fast.
- Dave
Last edited by YetAnotherDave; 05-17-2005 at 05:36 PM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.