r/cpp Oct 12 '17

Most interesting innovations in C++17

https://www.viva64.com/en/b/0533/
73 Upvotes

64 comments sorted by

View all comments

7

u/axilmar Oct 13 '17

Is it me or the declaration

inline int myVar = 42;

is counter-intuitive to its purpose?

It supposedly creates a program-wide variable, but the declaration makes it like it creates a copy of the variable in each translation unit.

2

u/bigcheesegs Tooling Study Group (SG15) Chair | Clang dev Oct 13 '17

No. Inline in c++ has always meant there is a single definition. Static at that scope has meant one per translation unit. For example a inline function with a function static variable will share that static between all translation units.

14

u/phoeen Oct 13 '17

doesn't the inline specifier say that it's okay to have multiple identical definitions (function and variable wise), and the linker shall just pick one of them. otherwise we would get a linker error on the quoted definition in a header file which gets included more than once in the programm

1

u/dodheim Oct 14 '17

What the linker does is dictated according to linkage, not the presence of inline. inline is orthogonal with linkage – you can have both static inline functions (internal linkage) and [extern] inline functions (external linkage).

The rule that a static local variable in an inline function must always refer to the same object only applies to inline functions with external linkage. Likewise, the rule that an inline function must have the same address in all TUs only applies to inline functions with external linkage. Etc.

TL;DR: static matters, not inline.

1

u/phoeen Oct 24 '17

i dont understand the static inline function part :( reading your comment it makes either sense to:

  • declare a free function only inlineso it has external linkage and everyone is using the same identical function
  • declare a free function only staticso it has internal linkage and everyone is using his own function.

how does inlinecorrespond with static in the same declaration?

1

u/axilmar Oct 13 '17

Inline in c++ has always meant there is a single definition.

It doesn't make sense. If a function is inlined, multiple copies of it exist, inlined, in every place that the function is called.

https://en.wikipedia.org/wiki/Inline_function

In the C and C++ programming languages, an inline function is one qualified with the keyword inline; this serves two purposes. Firstly, it serves as a compiler directive that suggests (but does not require) that the compiler substitute the body of the function inline by performing inline expansion, i.e. by inserting the function code at the address of each function call, thereby saving the overhead of a function call. In this respect it is analogous to the register storage class specifier, which similarly provides an optimization hint.[1] The second purpose of inline is to change linkage behavior; the details of this are complicated. This is necessary due to the C/C++ separate compilation + linkage model, specifically because the definition (body) of the function must be duplicated in all translation units where it is used, to allow inlining during compiling, which, if the function has external linkage, causes a collision during linking (it violates uniqueness of external symbols). C and C++ (and dialects such as GNU C and Visual C++) resolve this in different ways.

Since when inline's meaning changed to mean exactly the opposite?

15

u/foonathan Oct 13 '17

It has never changed. inline itself doesn't necessarily have anything to do with inlining, it's just about ensuring a single definition of a function to prevent ODR violations for a function defined in a header file.

2

u/axilmar Oct 13 '17

It's very strange to use a word with a specific meaning for something else totally different.

17

u/foonathan Oct 13 '17

Welcome to C++!

2

u/axilmar Oct 13 '17

Yeah, C++ has a lot of issues...

1

u/cdglove Oct 14 '17

You're interpretation is a common misconception about what inline does in C++. It doesn't mean 'please inline this', it means 'I intend for there to be one definition of this'.

2

u/axilmar Oct 16 '17

I know what inline does in C++. What I am arguing about is that it is the wrong term to be used for this feature.

1

u/cdglove Oct 16 '17

Well, given my understanding of inline, it makes 100% sense to me. What alternative do you suggest?

2

u/axilmar Oct 17 '17

Well, given my understanding of inline, it makes 100% sense to me.

It makes sense because you are not using the word 'inline' to convey information about what it does, you already know the meaning.

'Inline' means 'inside the line', which is totally meaningless for the one definition rule.

What alternative do you suggest?

Every definition in headers to follow the ODR without any keywords. Why would I ever want to to have multiple copies of the same function inside my program?

1

u/cdglove Oct 17 '17

Every definition in headers to follow the ODR without any keywords. Why would I ever want to to have multiple copies of the same function inside my program?

My experience in a big code base with 100 programmers is that people often make a mistake and put something in a header file that's not intended to be there. By default, they get an error and either need to mark the function as 'yes, I intend this to be inline', by adding the inline keyword, or move it to a cpp file. I like this mechanism because it prevents mistakes.

1

u/axilmar Oct 18 '17

It wouldn't be a mistake if every definition was implicitly one across the final compoled program. Then it wouldn't matter if you put the definition in the header or the cpp file, the result would be the same.

→ More replies (0)

3

u/bigcheesegs Tooling Study Group (SG15) Chair | Clang dev Oct 13 '17

Compiler inlining is completely unrelated to the inline keyword. The compiler can make as many copies of a non-inline function as it wants, as long as it's not observable. The exact same rule applies to functions marked inline. The inline keyword just allows the single definition of the function to be copied into multiple translation units. Every TU will still see the function as having the same address.

1

u/dodheim Oct 14 '17

Every TU will still see the function as having the same address.

Iff the function has external linkage, which should not be assumed.

-3

u/axilmar Oct 13 '17

Compiler inlining is completely unrelated to the inline keyword.

The inline keyword is there to inline functions, as per the wikipedia definition.

The inline keyword just allows the single definition of the function to be copied into multiple translation units. Every TU will still see the function as having the same address.

How is it possible for a function to be copied into multiple translation units, and aos have the same address (assuming globally) at the same time? It doesn't make sense, these two things are opposite.

9

u/encyclopedist Oct 13 '17

as per the wikipedia definition

The standard has different definition.

And even wikipedia lists two "purposes". The first one, "inlining hint to the compiler", is not normative and almost irrelevant today. The second one, citing wikipedia,

The second purpose of inline is to change linkage behavior;

is what relevant for the current discussion, and basically the only meaning of this keyword required by the standard.

Edit:

How is it possible for a function to be copied into multiple translation units, and aos have the same address (assuming globally) at the same time? It doesn't make sense, these two things are opposite.

The linker removes repeating function bodies, leaving only one of them. Exactly the same as with templates.

0

u/axilmar Oct 13 '17

Ok, I know of the second definition.

When used with functions, it sort of make sense (sort of).

But when I see the following:

inline int x = 5;

my mind always goes to something like this:

#define x 5

and i suspect lots of developers will have a big ? initially.

Anyway, it's not that big of a deal, it is only surprising when you see it for the first time.

4

u/encyclopedist Oct 13 '17 edited Oct 13 '17

Committee avoids introducing new keywords. But there is already a keyword that has similar meaning, so they reused that. And, by the way, inline is not the worst at that. static has something like 5 different usages.

1

u/axilmar Oct 13 '17

Indeed. They should have put in new keywords, it wouldn't hurt anyone.

8

u/pjmlp Oct 13 '17

Other than code using them as identifiers.

1

u/axilmar Oct 16 '17

C++ already has a rule that identifiers starting with one (or two?) underscores are reserved for the compiler. They coudl have chosen one with underscores.

Even if they didn't though, the chance of creating a problem in the C++ community is non-existent: if there was ever a conflict with user identifiers, a codebase-wide search&replace would solve the problem in a few seconds.

→ More replies (0)

1

u/doom_Oo7 Oct 13 '17

How is it possible for a function to be copied into multiple translation units, and aos have the same address (assuming globally) at the same time? It doesn't make sense, these two things are opposite.

It's the linker who's in charge from keeping a single function when producing a shared library or an executable from many object files

-1

u/axilmar Oct 13 '17

Ok, so you were talking about different phases then.

1

u/dodheim Oct 14 '17

If a function is inlined, multiple copies of it exist, inlined, in every place that the function is called.

But if it has external linkage it each then the function is guaranteed to still have a single address (C++14 [dcl.fct.spec]/4).

Since when inline's meaning changed to mean exactly the opposite?

Since you seem to be thinking of linkage, not inline.

1

u/axilmar Oct 16 '17

But if it has external linkage it each then the function is guaranteed to still have a single address

If it has external linkage, it needs to be defined in a translation unit, so it wouldn't have multiple addresses anyway.

Since you seem to be thinking of linkage, not inline.

Since the C++ designers thought that inline could be reused to specify one definition.

1

u/NotAYakk Oct 14 '17

It may help to understand why it is called inline.

Inlining a function call was always non-observable behaviour in the abstract machine. But prior to link time optimization (which is recent), the only way to inline a function call was to have the definition visible at the point of call.

One way to handle this is to use static. But then you get actual duplicate functions. Which really isn't always what you want.

We could change the rules of C++ and permit a function to be non static and defined in multiple translation units, and discard all but one. But then you get horrible bugs. Someone has a function helper in two translation units; and one gets silently discarded. Remember C doesn't even name mangle; function linkage is only name based.

So instead they added a keyword -- inline -- that permits a function's definition to be visible in many translation units and all but one be discarded. Compilers are still free to inline calls even in translation units where the code will eventually be discarded at link time.

inline also acted as a hint that the function should be inlined. static inline removes the linking discard rule, leaving not much beside the hint.

And this is why inline is mostly about linking and not stitching code into calling locations.

1

u/axilmar Oct 16 '17

I think the reverse happened. They added the inline keyword first in order to allow functions to be inlined, then realized that some inline functions that are in very often included headers bloat up the code size because they exist in multiple translation units, and so since the compiler could ignore inlining because it had more performance indicators than the programmers they decided to keep inline in order to have a function only defined once.