My function test is added to two different .cpp-files and the functions are private to their respective files as shown below
test1.cpp
#include <iostream>
using namespace std;
void test()
{
cout << "test" << endl;
}
test2.cpp
#include <iostream>
using namespace std;
void test()
{
cout << "test" << endl;
}
main.cpp
#include <iostream>
using namespace std;
int main()
{
return 0;
}
During linking I get the error multiple definition of test() - but how is that possible, considering that the two files have their own private scope!? I could understand it if I included the function prototype in each .cpp-files' corresponding header, but there is no such thing in this example.
You need the inline keyword for that:
inline void test()
{
cout << "test" << endl;
}
This allows you to have multiple definitions in separate source files without violating the one-definition rule. However, note that the function still has external linkage and they will all resolve to the same address. Also:
An inline function shall be defined in every translation unit in which
it is odr-used and shall have exactly the same definition in every
case
If you want separate functions with different addresses (internal linkage), use the static keyword instead.
Both test functions are in the same global namespace of the program. In order to avoid error you may:
1) wrap any or both functions in namespace:
namespace A
{
void test()
{
...
}
}
2) use static keyword
3) just rename one of them
Add static in each test function.
#include <iostream>
using namespace std;
static
void test()
{
cout << "test" << endl;
}
To elaborate on above answers:
In C++, function declarations can be repeated as many times as you want. A function definition however (i.e. the function body), can occur only once.
When creating your binary, the compiler compiles each file to a obj file so in your example you end up with test1.obj, test2.obj and main.obj. After all files compiled successfully, the linker links them together to create your executable. This is where multiple definitions for the same function are found and why linking fails.
Depending on what you want, you can do the following to resolve this:
If you want multiple different functions with the same name, then you have to disambiguate them. C++ wouldn't be C++ if you only had one way to do this:
The old c way: use the static keyword
Use an anonymous namespace
Use a namespace
If you want only one function:
Separate the definition from the declaration, i.e. put the declaration in a header file and move the definition to a source file.
Define the function as inline in a header
Related
I just feel weird about how does that work ?
That my first time that I've ever seen that , two c++ files located in the same directory "Test1.cpp,Test2.cpp"
Test1.cpp :
#include <iostream>
void magic();
int main(){
magic();
return 0;
}
Test2.cpp :
#include <iostream>
using namespace std;
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
As I mentioned above , they are in the same directory , with prototype of 'magic' function.
Now my question is , how does magic work without any inclusion of Test2.cpp ?
Does C++ include it by default ? if that's true , then why do we need to include our classes ? why do we need header file while cpp file can does its purpose ?
In order to obtain an executable from a C++ source code two main phases are required:
compilation phase;
linking phase.
The first one searches only for the signature of the functions and check if the function call is compatible with the found declarations.
The second one searches the implementation of the function among the libraries or objects linked through the options specified through command line of the linker (some compilers can automatically run the linker adding some command line options).
So you need to understand the compiler and linker options in order to understand this process.
The main catch of headers file is simplifying writing of code.
Let's think about next example:
test2.cpp
#include <iostream>
using namespace std;
void my ()
{ magic(); } // here we don't know what magic() is and compiler will complain
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
This code gives next error:
gaal#linux-t420:~/Downloads> g++ test2.cpp
test2.cpp: In function ‘void my()’:
test2.cpp:6:9: error: ‘magic’ was not declared in this scope
{ magic(); } // here we don't know what magic() is and compiler will complain
^
To avoid this error we need to place declaration of magic() function before definition of my(). So it is good idea to place ALL declarations in one place. Header file is a such place. If we don't use headers, we'll need to paste declaration of magic() function in any cpp-file where it will be used.
Please consider this code:
#include <iostream>
namespace Foo{
void ool() // Version A
{
std::cout << "Foo::ool" << std::endl;
}
inline namespace Bar{
void ool() // Version B
{
std::cout << "Foo::Bar::ool" << std::endl;
}
}
}
int main()
{
Foo::ool(); // <- error
}
Both Clang and G++ correctly mark Foo::ool as ambiguous. I can call Foo::Bar::ool without problem but is there a way to call the version A without changing its declaration?
I found people in similar position trying to understand what happens but I did not see a solution for this case.
I am in this situation because I have a project that includes a declaration of std::__1::pair and std::pair, made in different places, with std::__1 being an inline namespace. I need the code to point to the std::pair explicitly. Is there a solution for that?
I don't think that is possible; from cppreference:
Qualified name lookup that examines the enclosing namespace will include the names from the inline namespaces even if the same name is present in the enclosing namespace.
However, it seems you are not actually in the situation you describe, as you say that the two definitions are pulled from different files. Thus you "bookmark" the more external definition in order to be able to call it when you need it:
#include <iostream>
// Equivalent of first include
namespace Foo{
void ool() // Version A
{
std::cout << "Foo::ool" << std::endl;
}
}
const auto& foo_ool = Foo::ool;
// Equivalent of second include
namespace Foo{
inline namespace Bar{
void ool() // Version B
{
std::cout << "Foo::Bar::ool" << std::endl;
}
}
}
int main()
{
foo_ool(); // Works
}
If the thing you want to bookmark is a type, a simple using directive should suffice. The equivalent code for you would look like:
#include <my_first_include>
// bookmark code
#include <my_second_include>
// rest of the code
You cannot unambiguously refer to the symbol defined in the enclosing namespace once the inline namespace has been seen.
In particular for you case, the qualified lookup in main is rightfully flagged as being ambiguous (as you said yourself). See the last point on cppreference:
Qualified name lookup that examines the enclosing namespace will include the names from the inline namespaces even if the same name is present in the enclosing namespace.
Yet, has other pointed out in comments, you are probably facing a problem of configuration in your toolchain invocation when you try to use std::pair.
To fix you problem, you need to make sure the compiler is invoked to compile C++11 code, which would be with the flag:
-std=c++11 or -std=c++0x depending on your version of Clang/GCC
To give further context:
The inline namespace is a C++11 feature, mainly introduced to allow for symbol versioning in libraries. A C++ standard library implementation could then define different versions of symbols in nested namespaces (with non-standard names), and depending on the requested library version when compiling, the toolchain defines one of those nested namespaces as inline. It seems you are using a c++11 version of the library (since it defines some symbols, in particular pair, in the inline namespace _1), so having symbols in an inline namespace in actually what you want.
I don't think you can refer ool ambiguously when an inline namespace do have a method with same name ool .
But You can try this;
#include <iostream>
namespace Foo{
inline namespace A {
void ool() // Version A
{
std::cout << "Foo::ool" << std::endl;
}
}
namespace Bar{
void ool() // Version B
{
std::cout << "Foo::Bar::ool" << std::endl;
}
}
}
int main()
{
Foo::ool(); // no error
}
Wrap methods in namespace Foo in a namespace A then inline namespace A.
Remove inline from Bar.
Now if you make a call Foo::ool(); it will invoke inline A::ool()
Bar::ool can be invoked by Foo::Bar::ool
So I am working on my first multiple file, non-toy, c++ project. I have a class that represents a multi-spectral image and all the information that goes along with it.
My problem is how to design the part of the program that loads and object of this class with a file from disk!
I don't think I need a class for this. Would switching to a functional approach be better for the file loading. This way I can have just a source file (.cpp) that has functions I can call while passing in pointers to the relevant objects that will be updated by the file accessed by the function.
I don't think static functions are what I want to use? As I understand it they(static functions) are for accessing static variables within a class, aren't they?
If I go the functional route, from main(), how do I access these functions? I assume I would include the functions .cpp file at the beginning of the main() containing file. From there how do I call the functions. Do i just use the function name or do I have to pre-pend something similar to what you have to pre-pend when including a class and then calling its methods.
Here is some example code of what I have tried and the errors I get.
OpenMultiSpec.cpp
#include <iostream>
void test(){
std::cout << "Test function accessed successfully" << std::endl;
}
main.cpp
int main(){
test();
return 1;
}
The error says " 'test' was not declared in this scope "
OpenMultiSpec.h
void test();
main.cpp
#include "OpenMultiSpec.h"
int main(){
test();
return 1;
}
If they're in two separate files, and in your case, one being a header, use
#include "OpenMultiSpec.h"
If you decide to only use one file (as your comment says above), you won't need #include for your header file. Just place your function declaration anywhere before you call it.
#include <iostream>
void test() {
std::cout << "Test function accessed successfully" << std::endl;
}
int main() {
test();
return 1;
}
Is there any difference between wrapping both header and cpp file contents in a namespace or wrapping just the header contents and then doing using namespace in the cpp file?
By difference I mean any sort performance penalty or slightly different semantics that can cause problems or anything I need to be aware of.
Example:
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
namespace X
{
void Foo::TheFunc()
{
return;
}
}
VS
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
using namespace X;
{
void Foo::TheFunc()
{
return;
}
}
If there is no difference what is the preferred form and why?
The difference in "namespace X" to "using namespace X" is in the first one any new declarations will be under the name space while in the second one it won't.
In your example there are no new declaration - so no difference hence no preferred way.
Namespace is just a way to mangle function signature so that they will not conflict. Some prefer the first way and other prefer the second version. Both versions do not have any effect on compile time performance. Note that namespaces are just a compile time entity.
The only problem that arises with using namespace is when we have same nested namespace names (i.e) X::X::Foo. Doing that creates more confusion with or without using keyword.
There's no performance penalties, since the resulting could would be the same, but putting your Foo into namespace implicitly introduces ambiguity in case you have Foos in different namespaces. You can get your code fubar, indeed. I'd recommend avoiding using using for this purpose.
And you have a stray { after using namespace ;-)
If you're attempting to use variables from one to the other, then I'd recommend externalizing them, then initializing them in the source file like so:
// [.hh]
namespace example
{
extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
int a, b, c;
}
// Then in the function below, you can init them as what you want:
void reference
{
example::a = 0;
}
If the second one compiles as well, there should be no differences. Namespaces are processed in compile-time and should not affect the runtime actions.
But for design issues, second is horrible. Even if it compiles (not sure), it makes no sense at all.
The Foo::TheFunc() is not in the correct namespacein the VS-case. Use 'void X::Foo::TheFunc() {}' to implement the function in the correct namespace (X).
In case if you do wrap only the .h content you have to write using namespace ... in cpp file otherwise you every time working on the valid namespace. Normally you wrap both .cpp and .h files otherwise you are in risk to use objects from another namespace which may generate a lot of problems.
I think right thing to do here is to use namespace for scoping.
namespace catagory
{
enum status
{
none,
active,
paused
}
};
void func()
{
catagory::status status;
status = category::active;
}
Or you can do the following:
// asdf.h
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
Then
// asdf.cpp
#include "asdf.h"
void X::Foo::TheFunc()
{
return;
}
Say I have two different cpp files. Both declare classes with the same name, but perhaps a totally different structure (or perhaps the same structure, different implementation). The classes do not appear in the header files. (As an example, suppose they are Node classes for different list classes.)
I've seen these classes conflict. Is this expected by the standard? What solutions are there to this problem?
UPDATE:
As suggested by answers/comments, anonymous namespaces are what I was looking for.
The standard way around this problem is to wrap the classes in different namespaces.
It violates One Definition Rule. It's hard for compiler to detect the error, because they are in different compilation units. And even linker cannot detect all errors.
See an example in http://www.cplusplus.com/forum/general/32010/ . My compiler and linker (g++ 4.2.1) can build the final executable without any error, but the output is wrong.
If I change the example a bit, I get segmentation fault.
// main.cpp
#include <iostream>
#include <list>
using namespace std;
struct Handler
{
Handler() : d(10, 1.234) {}
list<double> d;
};
extern void test_func();
int main(void)
{
Handler h;
cout << h.d.back() << endl;
test_func();
return 0;
}
// test.cpp
#include <iostream>
#include <string>
using namespace std;
struct Handler
{
Handler() : d("test Handler") {}
string d;
};
void test_func()
{
Handler h;
cout << h.d << endl;
}
It's recommended to differentiate you class by namespace. For example of Node, you can use nest class and define the Node in the parent list class. Or you can add you class in anonymous namespace. See How can a type that is used only in one compilation unit, violate the One Definition Rule?
I'm not sure if I'm missing some detail here, but you wrap each class in a namespace.
namespace A {
class Node { };
}
namespace B {
class Node { };
}
Then you can use A::Node or B::Node.
You can use namespace to have multiple classes with same name by sub-scoping them in different namespaces. See: http://www.cplusplus.com/doc/tutorial/namespaces/
I've seen these classes conflict. Is this expected by the standard?
The standard says you can't do that. It would violate the one definition rule. (How to fix this has already been covered in other answers)