C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Translation-unit-local functions that access private class fields

From: Rhidian De Wit <rhidiandewit_at_[hidden]>
Date: Sat, 20 Jun 2026 22:13:33 +0200
I agree that we should foresee the case that PEMs will be declared in
header files and that it is nearly impossible to stop this from occurring.

Why can Bar::Bar call Print on Foo? I thought a PEM can only be called from
> within a Foo member function. Otherwise it would not be private (at least
> not in the sense, private is currently understood).

You're right, it was a bad example.

I would have thought, PEMs have internal linkage and Print included in one
> translation unit would be (internally handled) different(ly) from Print
> included in another translation unit (even if they have the same C++ code)
> and there is not an ODR violation.

 Correct again, my example wouldn't have been an ODR violation.

So, to accommodate all the comments from everyone could the following
wording be more complete?
PEMs have internal linkage by default and declaring extern functions in a
PEM would lead to a compiler error. Furthermore, it is valid to define PEMs
in a header file and allow it to be included in other files but PEMs are
only callable by non-static member functions where the hidden this pointer
must be the same as the class that the PEM is extending.

This would allow for the following valid code:
 // Foo.h
class Foo {
private:
  int m_var;

public:
  Foo();
  void Print();
};

private impl Foo {
  std::string TransformVar() {
    return std::to_string(m_var); // trivial example
  }
}

// Foo1.cpp
#include "Foo.h"
void Foo::Print() {
  std::cout << TransformVar();
}

// Foo2.cpp
#include "Foo.h"
Foo::Foo() {
  Print();
}


Excuse the obviously very simple example, but this would be valid code
where a PEM is shared across TUs but only used by Foo.
This example does defeat the purpose of defeating a PEM because now we
expose the std::string symbol in Foo.h, but that's up to the user and this
allows PEMs to be valid in header files while not necessarily being the
intended usage of them.

I'm far from an expert in C++ modules as I haven't had much interaction
with them, so I'd more than welcome any thoughts on whether this would not
be achievable in modules, or easier in modules.

Thanks for all the comments,

Op za 20 jun 2026 om 20:30 schreef Thiago Macieira via Std-Proposals <
std-proposals_at_[hidden]>:

> On Friday, 19 June 2026 23:04:04 Pacific Daylight Time Sebastian Wittmeier
> via
> Std-Proposals wrote:
> > A) Write into the standard that all the tokens of a PEMs declaration
> have to
> > come from the highest level C++ file and not from tokens included by
> > #include. How about preprocessor macros? May the whole PEM or parts of
> it /
> > single identifiers or constants come from a #define?
> >
> >
> > B) The PEMs have external linkage. A redefinition with the same or
> different
> > code leads to a linker error. That would also affect PEMs, which are just
> > replicated, but would have the exact same code. So a PEM name (although
> > they are meant to be private and local) would not be allowed to be reused
> > anywhere. That affects helper functions.
> >
> >
> > C) The PEM has internal linkage. While a redefinition (or putting it
> into a
> > header) is not advised due to code duplication, it works just fine in
> > practice or is even efficient with link-time-optimization.
> >
> >
> > D) Like C, but redefining it is "ill-formed, no diagnostic required".
> Could
> > work in practice, but the standard forbids it to disencentivize the
> > programming practice.
>
> How about: "exactly like what we're already used to"?
>
> Declarations inside the class body don't define any symbols.
> Implementations
> inside the class body and those marked inline are inlineable and must be
> token-exact the same in all translation units, otherwise ODR. Out-of-body
> implementations without inline are in a single TU, otherwise ODR.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Principal Engineer - Intel Data Center - Platform & Sys. Eng.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>


-- 
Rhidian De Wit
Software Engineer - Barco

Received on 2026-06-20 20:13:50