Using constexpr and string_view in module

2.5k Views Asked by At

Modern C++ offers constexpr and std::string_view as a convenient alternative to string literals. However, I am unable to link to a "constexpr std::string_view" within a module. By contrast, I am able to use string_view (not constexpr) within the module as well as a "constexpr std::string_view" outside of the module. Furthermore, the problem does not occur for other uses of constexpr within the module, such as for integers.

Below is the minimal code to recreate the error:

module interface unit (my_string.cpp):

export module my_string;

import <string_view>;

export namespace my_string {
struct MyString {
    static std::string_view string_at_runtime;
    static constexpr std::string_view string_at_compilation{"Hello World at compilation (inside module)"};
    static constexpr int number_at_compilation{1};
};
}

module implementation unit (my_string_impl.cpp):

module;

module my_string;

namespace my_string {
    std::string_view MyString::string_at_runtime = "Hello World at runtime";
}

hello_world.cpp:

import <iostream>;
import <string_view>;

import my_string;

static constexpr std::string_view hello_world{"Hello World at compilation (outside module)"};

int main(){
    std::cout << hello_world << std::endl;
    std::cout << my_string::MyString::string_at_runtime << std::endl;
    std::cout << my_string::MyString::number_at_compilation << std::endl;
    std::cout << my_string::MyString::string_at_compilation << std::endl; //<-- ERROR is here
}

Compilation and attempt to link (using gcc 11.2.0 running on Linux):

g++ -c -fmodules-ts -std=c++20 -xc++-system-header iostream  string_view 
g++ -c my_string.cpp -fmodules-ts -std=c++20
g++ -c my_string_impl.cpp -fmodules-ts -std=c++20
g++ -c hello_world.cpp -fmodules-ts -std=c++20
g++ -o main my_string.o my_string_impl.o hello_world.o -fmodules-ts -std=c++20

Only the last instruction (linking) results in an error:

g++ -o main my_string.o my_string_impl.o hello_world.o -fmodules-ts -std=c++20
/usr/bin/ld: hello_world.o: in function `main':
hello_world.cpp:(.text+0x97): undefined reference to `my_string::MyString::string_at_compilation'
collect2: error: ld returned 1 exit status

In addition to searching the answers to related questions (e.g. constexpr in modules and constexpr and namespaces) I have reread the GCC Wiki. I have not yet tried this code with other compilers (e.g. clang, msvc). Is this error a failure in my code or a not-yet-implemented feature in gcc?

1

There are 1 best solutions below

0
On BEST ANSWER

I have found a work around solution: adding a getter method.

In the module interface unit (my_string.cpp) add:

static std::string_view GetStringAtCompilation();

In the module implementation unit (my_string_impl.cpp) add:

std::string_view MyString::GetStringAtCompilation(){
    return string_at_compilation;
}

And now the following line in the "main" function (see hello_world.cpp in question) compiles, links and executes without error:

std::cout << my_string::MyString::GetStringAtCompilation() << std::endl;

I believe that the reasons that the original attempt did not work without a getter method is given in this answer about constexpr and string_view in headers