- Title
- Unnamed types in entities with linkage
- Status
- cd1
- Section
- 6.7 [basic.link]
- Submitter
- Daveed Vandevoorde
Created on 2002-10-31.00:00:00 last changed 217 months ago
Messages
Date: 2004-10-15.00:00:00
[Voted into WP at October 2004 meeting.]
Date: 2004-10-15.00:00:00
[Voted into WP at October 2004 meeting.]
Date: 2003-04-15.00:00:00
Notes from April 2003 meeting: There was agreement that this check is not needed for variables
and functions with extern "C" linkage, and a change there is
desirable to allow use of legacy C headers. The check is also not needed for
entities with internal linkage, but there was no strong sentiment
for changing that case. We also considered relaxing this requirement for extern "C++"
variables but decided that we did not want to change that case. We noted that if extern "C" functions are allowed an additional
check is needed when such functions are used as arguments in calls
of function templates. Deduction will put the type of the extern "C"
function into the type of the template instance, i.e., there would
be a need to mangle the name of an unnamed type. To plug that hole
we need an additional requirement on the template created in
such a case. Proposed resolution (April 2003, revised slightly October 2003
and March 2004): In 6.7 [basic.link] paragraph 8, change to Change 13.4.2 [temp.arg.type] paragraph 2 from (note:
this is the wording as updated by issue 62) to Once this issue is ready, issue 319
should be moved back to ready as well.
A name with no linkage (notably, the name of a class or enumeration
declared in a local scope (6.4.3 [basic.scope.block]))
shall not be used to declare an
entity with linkage. If a declaration uses a typedef name, it is
the linkage of the type name to which the typedef refers that is
considered.
A type is said to have linkage if and only if
A type without linkage shall not be used as the type of a variable or
function with linkage, unless the variable or function has extern "C"
linkage (9.12 [dcl.link]).
[Note: in other words, a type without linkage contains
a class or enumeration that cannot be named outside
of its translation unit. An entity with external linkage
declared using such a type could not correspond to any other entity
in another translation unit of the program and is thus not permitted.
Also note that classes with linkage may contain members whose types do
not have linkage, and that typedef names are ignored in the determination of
whether a type has linkage.]
The following types shall not be used as a template-argument
for a template type-parameter:
A type without linkage (6.7 [basic.link])
shall not be used as a template-argument
for a template type-parameter.
Date: 2026-07-27.15:54:01
6.7 [basic.link] paragraph 8 says (among other things): I would expect this to catch situations such as the following: The problem here is that most implementations must generate the same
mangled name
for "f" in two translation units. The quote from the standard above
isn't quite
clear, unfortunately: There is no type name to which the typedef refers. A related situation is the following:
Finally, these problems are much less relevant when declaring names
with internal
linkage. For example, I would expect there to be few problems with: I recently tried to interpret 6.7 [basic.link] paragraph 8
with the assumption that types with no names
have no linkage. Surprisingly, this resulted in many diagnostics on
variable declarations (mostly like "answer" above). I'm pretty sure the standard needs clarifying words in this matter, but
which way should it go? See also issue 319.
A name with no linkage (notably, the name of a class or enumeration
declared in a local scope (6.4.3 [basic.scope.block])) shall not
be used to declare an entity with linkage.
If a declaration uses a typedef name, it is the linkage of the type
name to which the typedef refers that is considered.
// File 1:
typedef struct {} *UP;
void f(UP) {}
// File 2:
typedef struct {} *UP; // Or: typedef struct {} U, *UP;
void f(UP);
enum { no, yes } answer;
The variable "answer" is declared as having external linkage, but it is
declared
with an unnamed type. Section 6.7 [basic.link]
talks about the linkage of names, however,
and does therefore not prohibit this. There is no implementation issue
for most
compilers because they do not ordinarily mangle variable names, but I
believe
the intent was to allow that implementation technique.
typedef struct {} *UP;
static void g(UP);
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2008-10-05 00:00:00 | admin | set | status: wp -> cd1 |
| 2005-05-01 00:00:00 | admin | set | status: dr -> wp |
| 2004-11-07 00:00:00 | admin | set | status: ready -> dr |
| 2004-04-09 00:00:00 | admin | set | status: review -> ready |
| 2004-02-13 00:00:00 | admin | set | messages: + msg951 |
| 2004-02-13 00:00:00 | admin | set | status: ready -> review |
| 2003-11-15 00:00:00 | admin | set | status: review -> ready |
| 2003-04-25 00:00:00 | admin | set | messages: + msg815 |
| 2003-04-25 00:00:00 | admin | set | messages: + msg814 |
| 2003-04-25 00:00:00 | admin | set | status: open -> review |
| 2002-10-31 00:00:00 | admin | create | |