简体   繁体   中英

What is the purpose of the bullet points in [basic.link]/8 in N4140? They don't seem to bring anything new the statement preceding them

[basic.link]/8 in N4140 contains the following statement:

A type without linkage shall not be used as the type of a variable or function with external linkage unless
(8.7) — the entity has C language linkage (7.5), or
(8.8) — the entity is declared within an unnamed namespace (7.3.1), or
(8.9) — the entity is not odr-used (3.2) or is defined in the same translation unit.

Clearly a condition satisfying (8.8) is not possible, as an entity declared in an unnamed namespace cannot have external linkage, at the same time.

Then I decided to find an example of a function with external linkage returning a type with no linkage, ie, returning an object of a local class, to no avail, irrespective whether the function was, or wasn't, in the same TU as the type. I'm afraid the set of options satisfying (8.9) may also be empty. If that's the case, I'd like to hear some confirmation on this.

In reference to (8.7) I don't know what to say, but it seems to me that this bullet point will not add anything new to the problem either.

So it looks like 8.8 is a defect it is covered by defect report 2058: More errors from internal-linkage namespaces :

Issue 1603 dealt with omissions in the application of the change to give unnamed namespaces internal linkage, but its resolution overlooked a couple of items.

[...]

Also, 3.5 [basic.link] paragraph 8 says,

A type without linkage shall not be used as the type of a variable or function with external linkage unless

...

the entity is declared within an unnamed namespace (7.3.1 [namespace.def]), or

...

This bullet cannot occur, since a function or variable declared within an unnamed namespace cannot have external linkage.

And 8.9 was added by defect report 757 which includes a rationale.

One case is if you have templates.

template<typename T>
void f(T t) { t(); }

int main() { f([]{}); }

The instantiated function has external linkage, while T is a type without linkage. Strictly speaking, though, the instantiation is not instantiated into a TU (instantiations live in instantiation units, really). But I suspect that text is meant to apply here aswell.

As does this (I assume you already know, but this of course is a variable)

struct { } x;

With that in place, you can construct normal functions that satisfy the rule aswell

decltype(x) f() { return {}; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM