Why `static` functions in different TUs do not break the ODR?
Asked Answered
S

1

5

The ODR allows us to define several times the same inline function (with some restrictions).

However, what about the simpler case of static functions?

// First TU
static int foo() { return 0; }
int bar1() { return foo(); }

// Second TU
static int foo() { return 1; }
int bar2() { return foo(); }

If we do a quick read of [basic.def.odr]p4, we could naively conclude that this would be UB:

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement (9.4.1); no diagnostic required.

Where in the C++ standard is specified that each foo is a different function and therefore not breaking the ODR, even if they have the same name?

Is it simply a matter of reading [basic.link]p2.2 (i.e. due to internal linkage the names do not refer to the same entity and therefore [basic.def.odr]p4 does not apply here)? Or are there more nuances/rules involved to make this determination (like something in [basic.scope])?

Note that, with unnamed namespaces, the outcome is clear, because the name would be already different/unique.

Scintilla answered 9/5, 2019 at 16:39 Comment(4)
due to internal linkage the names do not refer to the same entity and therefore odr does not apply here Exactly right.Scalage
@Acorn Sorry, I've overlooked the language-lawyer tag.Staff
@πάνταῥεῖ No problem! :) Tell us about the bug! Linking-related ones always hurt a lot...Scintilla
@Scintilla We expected a specific behavior, that didn't happen, because the TU local function was defined without the static specifier, and the linker took on the first definition found from another TU, that was added later to the project :). I've even posted a not so well received quesiton after we found out.Staff
K
6

Correct — even though they have the same name locally, those are two different functions/entities, so there's no violation.

[basic.link]/4.3: When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit.

[basic.link]/5: A name having namespace scope has internal linkage if it is the name of a variable, variable template, function, or function template that is explicitly declared static; or [..]

I can't immediately find any further wording (normative or otherwise) that applies, but I don't think we need any.

Kinghood answered 9/5, 2019 at 16:48 Comment(2)
@Brian Actually that looks like the missing piece!Scintilla
Id' say [basic.link]/11 is what OP wants.Leptosome

© 2022 - 2024 — McMap. All rights reserved.