0

In C++, you can declare a member function and immediately give it a body:

// Let's assume this is in some Utilities.h file.
struct Foo
{
    void doIt() { /* Very important code */ }
};

But now you are in for some trouble, because if you #include <Utilities.h> from multiple .cpp files, you now have multiple definitions of doIt, which is undefined behavior, and the compiler will light your computer on fire.

I know two ways of getting around this:

The stupid one: Make doIt a template:

template<typename Dummy = void>
void doIt() { ... }

The "Do you like giant executables?" one: Declare doIt inline:

inline void doIt() { ... }

Is there a better way of declaring a member function with an in-line body without having it actually inlined by the compiler (as far as that's possible).

idmean
  • 14,540
  • 9
  • 54
  • 83
Niko O
  • 406
  • 3
  • 15
  • 2
    What makes you think the compiler is so eager to inline code? And there's no UB in `Utilities.h`. A member function declared inline is implicitly `inline`. – StoryTeller - Unslander Monica Feb 28 '22 at 16:18
  • 2
    That's not **undefined behavior**, because the multiple inline definitions are identical. It's only **undefined behavior** if the definitions are not the same. In C++, `inline` (including *implicit* inline, such as the first example) doesn't actually mean "inline" anymore; means something closer to "weak linkage". Hence, no "giant executables". – Eljay Feb 28 '22 at 16:19
  • 1
    *"you now have multiple definitions of doIt, which is undefined behavior"* There are no ODR violations, member function defined in the class are implicitly `inline`. – Jarod42 Feb 28 '22 at 16:20
  • `inline` and inlining are different. (The former is at best an hint for the later). – Jarod42 Feb 28 '22 at 16:22
  • `"Do you like giant executables?"` you are overthink this. Compiler and linker can detect those repetitions and tweak them depending on configuration used. I suspect that you are to focused on some unimportant micro-optimization (many beginners have such tendency). – Marek R Feb 28 '22 at 16:22
  • In the original code, `doIt` is implicitly inline, because it's defined inside the class definition. So marking it `inline` doesn't make any difference. The code is perfectly legal and its effect is well defined. No night terrors here. – Pete Becker Feb 28 '22 at 16:38
  • Even if `doIt` weren’t inline here, it would still be fine: you’re allowed to have multiple definitions of `Foo`, and the behavior is as if there is only one definition, so there’s only one definition of `Foo`. (This is a modern interpretation, made necessary by things like lambdas in the class body.) – Davis Herring Mar 01 '22 at 04:28

0 Answers0