I was working on a small example program, as a prototype proof-of-concept:
// disable_lib.cpp
export module disable_lib;
import <iostream>;
extern bool bDoStuff;
export void do_stuff()
{
if (bDoStuff) { std::cout << "stuff" << std::endl; }
}
This module compiles with with this command:
g++-13 -std=c++23 -fmodules-ts -ggdb -c disable_lib.cpp -o disable_lib.o
Naturally, I tried to declare bDoStuff
as extern, because I want its definition specified in another translation unit, which could look like this:
import disable_lib;
bDoStuff = false;
int main()
{
do_stuff(); // <-- here, we should not print "stuff" !
return 0;
}
When I try to compile the main file, I get relocation errors:
/usr/bin/ld: disable_lib.o: warning: relocation against `_ZW11disable_lib8bDoStuff' in read-only section `.text'
/usr/bin/ld: disable_lib.o: in function `do_stuff@disable_lib()':
/home/gg/my-repos/modules-presentation/code/disable_lib.cpp:13: undefined reference to `bDoStuff@disable_lib'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
What I would like to achieve is a way of compiling a main file, which strictly fullfills to criteria:
- The assignment of
bDoStuff
gets evaluated at compile-time; - the
std::cout
call does not get executed; and - the function call to
do_stuff()
gets stripped from the binary
To satisfy 3), I might need to flag with -lto
, but obviously I didn't get that far yet.
Question
Is there a way to achieve 1), 2) and 3) while using C++ modules?
What you're talking about is not a thing that could happen without modules (unless you use macros), let alone with them.
If a variable is declared
constexpr
, it has to have an initializer. This means it must be a definition and therefore cannot be redefined in this TU. Aconst
qualified variable declaration also must have an initializer.Because of this, there's no way for code outside of this TU, or later in some inclusion graph, to change what value the variable has.
Compilers can do link-time optimizations for stuff that isn't
const
orconstexpr
. But that's the best you could hope for.Again, this is true whether you're using modules or not.