C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Proposal: Deprecate namespace-scope declarations that are declared both static and inline

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Mon, 22 Jun 2026 09:10:56 -0400
On Mon, Jun 22, 2026 at 8:21 AM Yexuan Xiao via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Since C does not have namespaces, these libraries use internal linkage to
> avoid symbol conflicts. However, in C++, especially when writing modules,
> this is entirely unnecessary. These libraries can detect __cplusplus or
> some specific macro and drop static accordingly, without breaking existing
> code.
>

It sounds like you're saying: "C needs internal linkage because it doesn't
have namespaces, so the choice is between writing
    static inline int private_helper(int x) { return x + 1; } // internal
linkage, invisible to other TUs
and
    inline int yexuans_detail_namespace_private_helper(int x) { return x +
1; } // external linkage, still practically invisible to other TUs because
they won't guess this secret name
and the latter is obviously too ugly, so internal linkage serves a valid
purpose in C. But in C++, the choice is merely between
    static inline int private_helper(int x) { return x + 1; } // internal
linkage, invisible to other TUs
and
    namespace yexuans_detail_namespace {
      inline int private_helper(int x) { return x + 1; } // external
linkage, still practically invisible to other TUs because they won't guess
this secret name
    } // namespace yexuans_detail_namespace
which is more ergonomic than `yexuans_detail_namespace_private_helper`. So
C++ doesn't need internal linkage at all, and we can just get rid of it."

But that's silly. For one thing, internal linkage helps the linker do its
job efficiently. And for another, there's still an important difference (to
some programmers) between "invisible" and "*practically* invisible." If we
have a foolproof way to hide a symbol from other TUs, we should use it.


Reading between the lines, I hypothesize that you might think there's some
difference between
  static inline int f() { return 42; }
and
  namespace /*unnamed*/ { inline int f() { return 42; } }
There is not.

I'm not aware that Modules changes anything about this stuff. But if you
think it does, then it'd be nice to provide a complete, compilable example
<https://sscce.org/>.

–Arthur

Received on 2026-06-22 13:11:14