Oipo commented on a change in pull request #293:
URL: https://github.com/apache/celix/pull/293#discussion_r526360622
##########
File path: libs/framework/include/celix/dm/Component_Impl.h
##########
@@ -63,7 +88,7 @@ Component<T>& Component<T>::addInterfaceWithName(const
std::string &serviceName,
template<class T>
template<class I>
-Component<T>& Component<T>::addInterface(const std::string &version, const
Properties &properties) {
+inline Component<T>& Component<T>::addInterface(const std::string &version,
const Properties &properties) {
Review comment:
Consider the following situation:
example.h
```c++
#pragma once
void someFunction() {
printf("funcy!");
}
```
some_file.cpp:
```c++
#include <example.h>
void stuff() {
someFunction();
}
```
some_other_file.cpp:
```c++
#include <example.h>
void other_stuff() {
someFunction();
}
```
What the compiler does when it tries to compile some_file.cpp is it looks
for example.h, finds it, simply pastes the code into the translation unit
(still some_file.cpp) and sees that a function `someFunction` is not only
defined but also implemented. It generates the `someFunction` assembly and
outputs some_file.o.
Then the compiler see some_other_file.cpp and does the same thing. Looks for
the header, sees a definition and an implementation, creates the assembly for
`someFunction` and outputs it into some_other_file.o.
Now the linker is told to create some_executable from the two object files
some_file.o and some_other_file.o. But he sees `someFunction` twice and does
not know how to deal with it. Which one is correct? It doesn't know how to
determine that and instead of guessing what you meant and creating a random
executable, it gives you an error like the following:
```
/usr/bin/ld:
CMakeFiles/dm_example_cxx_phase3.dir/src/Phase3BaseActivator.cc.o: in function
`std::function<void (IPhase2*, std::map<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >,
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>
>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > >,
std::allocator<std::pair<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > const,
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
> > >&&)>::operator bool() const':
/home/oipo-unencrypted/Programming/celix-apache/libs/framework/include/celix/dm/ServiceDependency_Impl.h:240:
multiple definition of `celix::dm::DependencyManager::clear()';
CMakeFiles/dm_example_cxx_phase3.dir/src/Phase3Activator.cc.o:/home/oipo-unencrypted/Programming/celix-apache/libs/framework/include/celix/dm/DependencyManager_Impl.h:77:
first defined here
```
The key being "first defined here". It's telling you "which of these two
functions do you want me to use? Remove the other one please".
You can either change the header to only have a definition like so:
example.h
```c++
#pragma once
void someFunction();
```
example.cpp
```c++
#include <example.h>
void someFunction() {
printf("funcy!");
}
```
Which would only generate the assembly for `someFunction` when the compiler
is compiling example.cpp into example.o and never for another translation unit.
Or you can add inline like so:
example.h
```c++
#pragma once
inline void someFunction() {
printf("funcy!");
}
```
This will cause some_file.o to contain the function `stuff()` which doesn't
do a function call, but instead simply puts the printf call in the `stuff`
function and does the same for `some_stuff` in some_other_file.o. The function
`someFunction` simply "disappears" from the generated assembly.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]