I've tried creating a static library with two copies of the same function, defined in two seperate header/source files. These 2 source files should be mutually exclusive and not includable within the same file as each other. I've recreated the issue with the example code below. This was written and tested on VS2019, I haven't tested this on any other compiler yet.
The following is in a foobar static lib:
foo.h
#pragma once
#ifdef BAR
static_assert(-1, "Bar is already included, you shouldn't include both foo & bar");
#endif //BAR
#define FOO
void foobar();
foo.cpp
#include "foo.h"
#include <iostream>
void foobar(){
std::cout << "this is foo!";
}
bar.h
#pragma once
#ifdef FOO
static_assert(-1, "Foo is already included, you shouldn't include both foo & bar");
#endif //FOO
#define BAR
void foobar();
bar.cpp
#include "bar.h"
#include <iostream>
void foobar(){
std::cout << "this is bar!";
}
I could then create an executable project with a single main.cpp
I've created 3 diffirent versions of this file, but they all print the same line "this is foo!"
Below are the 3 versions of the main file:
#include "bar.h"
int main() {
foobar();
}
#include "foo.h"
int main() {
foobar();
}
#include "foo.h"
#include "bar.h"
int main() {
foobar();
}
So my questions are:
- Why does the executable always print
"this is foo!"
, no matter what it includes? - Why doesn't compilation fail when
foo.h
&bar.h
are included in the same source file despite the static_assert in the header files? - Is there a way to achieve 2 definitoins of the same function within the same library, but not allow them to be called at the same time?
Edit:
Thank you very much @selbie, you're answer is very useful. I've rewritten it so that it's slightly less hacky.
foo.h
#pragma once
#ifdef BAR
static_assert(false, "Bar is already included, you shouldn't include both foo & bar");
#endif //BAR
#define FOO
#include "foobar.h"
bar.h
#pragma once
#ifdef FOO
static_assert(false, "Foo is already included, you shouldn't include both foo & bar");
#endif //FOO
#define BAR
#include "foobar.h"
foobar.h
#pragma once
void foobar_foo();
void foobar_bar();
inline void foobar() {
#ifdef FOO
foobar_foo();
#endif // FOO
#ifdef BAR
foobar_bar();
#endif // BAR
}
foobar.cpp
#include "foobar.h"
#include <iostream>
void foobar_foo() {
std::cout << "this is foo!";
}
void foobar_bar() {
std::cout << "this is bar!";
}