![]() |
Boost : |
From: Ruben Perez (rubenperez038_at_[hidden])
Date: 2025-04-29 19:49:29
On Tue, 29 Apr 2025 at 18:30, Ruben Perez <rubenperez038_at_[hidden]> wrote:
>
> On Sun, 27 Apr 2025 at 15:15, ÐмиÑÑий ÐÑÑ
ипов via Boost
> <boost_at_[hidden]> wrote:
> >
> > Dear Boost community. The peer review of the proposed Boost.OpenMethod will
> > start on 28th of April and continue until May 7th. OpenMethods implements open
> > methods in C++. Those are "virtual functions" defined outside of classes. They
> > allow avoiding god classes, and visitors and provide a solution to the
> > Expression Problem, and the banana-gorilla-jungle problem. They also support
> > multiple dispatch. This library implements most of Stroustrup's multimethods
> > proposal, with some new features, like customization points and
> > inter-operability with smart pointers. And despite all that open-method calls
> > are fast - on par with native virtual functions.
> > [...]
> > * What is your evaluation of the implementation?
>
> I've seen that many of the macros use __COUNTER__ to generate unique
> identifiers. If I'm reading this correctly, this includes
> BOOST_OPENMETHOD_DECLARE_OVERRIDER and
> BOOST_OPENMETHOD_INLINE_OVERRIDE, which are supposed to be safe to be
> placed in headers. Is this correct?
>
> I've had bad experiences with macros using __COUNTER__ in headers in
> the past. boost/asio/coroutine.hpp, which simulates coroutines using
> switch/cases, uses __COUNTER__. Placing such constructs in headers can
> inadvertently yield ODR violations. In my case, the ODR violation went
> like this:
>
> // header1
> void f1() {
> BOOST_ASIO_CORO_REENTER(...) { ... } // Internally uses __COUNTER__
> }
>
> // header2
> void f2() {
> BOOST_ASIO_CORO_REENTER(...) { ... } // Internally uses __COUNTER__
> }
>
> // f1.cpp
> #include "header1.hpp" // __COUNTER__ here is 0
> #include "header2.hpp" // __COUNTER__ here is 1
>
> // f2.cpp
> #include "header2.hpp" // __COUNTER__ here is 0
> #include "header1.hpp" // __COUNTER__ here is 1
>
> This makes f1() and f2() have distinct bodies in f1.cpp and f2.cpp,
> which is an ODR violation. It caused random test failures under MSVC
> in Release mode only, and it took me forever to identify the root
> cause of the issue.
>
> Are the macros I mention also vulnerable to this problem?
Answering my own question: no, they are not because the generated
symbols have always static linkage. If used in headers as shown above,
several, potentially differently named symbols will be generated, but
that's okay since re-registering stuff multiple times seems to be a
no-op.
>
> Cheers,
> Ruben.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk