No Global Namespace Leakage (Siamese)
On this platform, #include <cstdint> doesn’t just give you std::int64_t — it conventionally also injects a bare ::int64_t into the global namespace, a C-compatibility convenience that has never been part of what the standard actually guarantees, just something implementations have long provided anyway. Code that quietly leans on the bare name is common, especially in anything with roots in C or older C++. import std; doesn’t carry that convenience forward.
1 export module Siamese;
2
3 import std;
4
5 // #include <cstdint> conventionally also injects a bare ::int64_t into the
6 // global namespace on this platform -- a C-compatibility convenience, not
7 // something the standard guarantees. import std; gives you only the
8 // std::-qualified name.
9 export std::int64_t const nine_lives{9};
10
11 export auto meow() -> void {
12 std::println("แมวสยามพูดว่า \"แง้ว\" ({} lives)", nine_lives);
13 }
Every reference to the fixed-width integer type here is qualified: std::int64_t (line 9), std::println (line 12). Try the unqualified name and the error is immediate and unambiguous:
1 import Siamese;
2
3 // int64_t x{}; // error: 'int64_t' does not name a type -- only
4 // std::int64_t exists here; uncomment to see it fail
5
6 auto main() -> int {
7 meow();
8
9 return 0;
10 }
1 error: 'int64_t' does not name a type
2 3 | int64_t x = 5;
3 | ^~~~~~~
4 note: 'int64_t' is defined in header '<cstdint>'; this is probably fixable
5 by adding '#include <cstdint>'
GCC’s own suggested fix — add #include <cstdint> — is exactly the trap: that would reintroduce the bare global name by including the header textually, defeating the reason to prefer import std; in the first place. The actual fix is simply to qualify the name, std::int64_t, which was always the portable spelling regardless of whether a project uses modules or headers.
Building Siamese is otherwise identical to Importing the Standard Library.