<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 2372</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="2372"></A><H4>2372.
  
Incorrect matching rules for block-scope <TT>extern</TT> declarations
</H4>
<B>Section: </B>6.7&#160; [<A href="https://wg21.link/basic.link">basic.link</A>]
 &#160;&#160;&#160;

 <B>Status: </B>CD5
 &#160;&#160;&#160;

 <B>Submitter: </B>Chen Fuxingi
 &#160;&#160;&#160;

 <B>Date: </B>2017-12-17<BR>


<P>[Accepted as a DR at the February, 2019 meeting.]</P>

<P>According to 6.7 [<A href="https://wg21.link/basic.link#6">basic.link</A>] paragraph 6,</P>

<BLOCKQUOTE>

The name of a function declared in block scope and the name
of a variable declared by a block scope <TT>extern</TT>
declaration have linkage. If there is a visible declaration
of an entity with linkage having the same name and type,
ignoring entities declared outside the innermost enclosing
namespace scope, the block scope declaration declares that
same entity and receives the linkage of the previous
declaration. If there is more than one such matching entity,
the program is ill-formed. Otherwise, if no matching entity
is found, the block scope entity receives external linkage.

</BLOCKQUOTE>

<P>The requirement that the entities have the same type does
not cover all cases that it should. Consider an example like:</P>

<PRE>
  static int a[3];
  void g() {
    printf("%p\n", (void*)a);
    extern int a[];
    printf("%p\n", (void*)a);
  }
</PRE>

<P>According to the cited wording, the block-scope declaration of
<TT>a</TT> does not match the namespace scope declaration because
<TT>int[]</TT> and <TT>int[3]</TT> are different types, thus the
first reference to <TT>a</TT> refers to the static variable while
the second one refers to a variable <TT>a</TT> defined in some
other translation unit. This is clearly not intended, and current
implementations treat both references as referring to the static
variable.</P>

<P><B>Notes from the October, 2018 teleconference:</B></P>

<P>CWG agreed with the direction and noted that a similar situation
occurs with <TT>extern "C"</TT> functions.</P>

<P><B>Proposed resolution (November, 2018):</B></P>

<P>Change 6.7 [<A href="https://wg21.link/basic.link#6">basic.link</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>The name of a function declared in block scope and the
name of a variable declared by a block scope <TT>extern</TT>
declaration have linkage. If there is a visible declaration
of an entity with linkage<DEL> having the same name and
type</DEL>, ignoring entities declared outside the innermost
enclosing namespace scope, <INS>such that the block scope
declaration would be a (possibly ill-formed) redeclaration
if the two declarations appeared in the same declarative
region,</INS> the block scope declaration declares that same
entity and receives the linkage of the previous
declaration. If there is more than one such matching entity,
the program is ill-formed. Otherwise, if no matching entity
is found, the block scope entity receives external
linkage. If, within a translation unit, the same entity is
declared with both internal and external linkage, the
program is ill-formed. [<I>Example:</I>
</P>

<PRE>
  static void f();
<INS>  extern "C" void h();</INS>
  static int i = 0;      //<SPAN CLASS="cmnt"> #1</SPAN>
  void g() {
    extern void f();     //<SPAN CLASS="cmnt"> internal linkage</SPAN>
<INS>    extern void h();     //<SPAN CLASS="cmnt"> </SPAN>C<SPAN CLASS="cmnt"> language linkage</SPAN>
</INS>
    int i;               //<SPAN CLASS="cmnt"> #2: <TT>i</TT> has no linkage</SPAN>
    {
      extern void f();   //<SPAN CLASS="cmnt"> internal linkage</SPAN>
      extern int i;      //<SPAN CLASS="cmnt"> #3: external linkage, ill-formed</SPAN>
    }
  }
</PRE>

<P>Without the declaration at line #2, the declaration at
line #3 would link with the declaration at line #1.  Because
the declaration with internal linkage is hidden, however, #3
is given external linkage, making the program
ill-formed. &#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR>
</BODY>
</HTML>
