On Fri, Jan 02, 2026 at 10:45:29AM +0100, Jakub Jelinek wrote:
> Seems we already do support the gnu_inline extern inline behavior for
> namespace scope functions as well as member functions if just
> declared constexpr and gnu_inline inside of the class and defined
> extern constexpr right after the class (but the dtor if any needs to be
> defined first), e.g. -O2

Actually, I was wrong, as documented for C++ [[gnu::gnu_inline]] doesn't
even need the extern keyword.

So:

[[gnu::gnu_inline]] constexpr inline int foo (int x) { return x + 42; }
static_assert (foo (0) == 42);
int bar (int x) { return foo (x); }
auto p = &foo;
struct S {
  [[gnu::gnu_inline]] constexpr inline int qux (int x) { return x + 42; }
  [[gnu::gnu_inline]] constexpr inline virtual int garply (int x) { return x + 
43; }
  [[gnu::gnu_inline]] constexpr inline virtual ~S () {}
};
static_assert (S {}.qux (0) == 42);
static_assert (S {}.garply (0) == 43);
int freddy (S s, int x) { return s.qux (x); }
int corge (S s, int x) { return s.garply (x); }
auto q = &S::qux;
int plugh (S &s, int x) { return s.garply (x); }
//S s;

already works the intended way except for key method and the question how to
cleanly define the out-of-line copy of it.
For the key method, if people don't use gnu_inline attribute on virtual
methods in the wild perhaps we could just allow virtual methods with
gnu_inline attribute to be key methods.  Because if people used it in the
wild, it wouldn't work very well before.

struct T {
  [[gnu::gnu_inline]] virtual inline int garply (int x) { return x + 43; }
  [[gnu::gnu_inline]] virtual inline ~T () {}
};
T t;

Without the explicit inline (or constexpr) keyword we get warnings:
/tmp/05.C:2:48: warning: ‘gnu_inline’ attribute ignored [-Wattributes]
    2 |   [[gnu::gnu_inline]] virtual int garply (int x) { return x + 43; }
      |                                                ^
/tmp/05.C:3:35: warning: ‘gnu_inline’ attribute ignored [-Wattributes]
    3 |   [[gnu::gnu_inline]] virtual ~T () {}
      |                                   ^
and with inline or constexpr we get the vtable/rtti emitted in the current
TU, but those refer to the methods that need to be defined somewhere else
with no clean way to define those right now.

        Jakub

Reply via email to