We've been struggling with this issue for some time and, well, it sounds weird. This isn't a general undefined reference question, because for some compilers this definitely works, for the one I'm asking here it doesn't.
Let's say, we have some constants, an ìnt
, a char const* const
and a std::string
. They are all declared extern
in a header file and instantiated in a source file. And finally used in a main.
my_file.hpp:
#include <string>
extern int my_int;
extern char const* const my_c_str;
extern std::string const my_string;
my_file.cpp
#include "my_file.hpp"
int my_int = 42;
char const* const my_c_str = "foo-bar";
std::string const my_string = "bar...foo";
main.cpp
#include "my_file.hpp"
#include <iostream>
int main()
{
std::cout << my_int << std::endl;
std::cout << my_c_str << std::endl;
std::cout << my_string << std::endl;
return 0;
}
And yes, both object files are used for linking the final executable using a CMake file like this:
cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
project(test)
add_executable(my_extern_test
my_file.cpp
main.cpp
)
With gcc/clang/MinGW, there is no issue with that, I've used it over and over again. On MSVC however we get the error "unresolved external symbol" for my_string
- not for the other variables.
To make it more precise:
- For basic C types it works
- For C++ stl-types it doesn't work
If I remove the use of the stl-type object in the main-function, it compiles as well.
The offending compiler is MSVC 14.31-17.2.
We use a workaround, so it is not a critical issue for us, but out of interest, I'd like to ask: Is there a bug in this very compiler-version?
Edit: made question more explicit, added remark about CMake.
PS: Wouldn't be the first, couldn't yet make pimpl work with std::unique_ptr
, as they do for MinGW/gcc or clang.