C++N4606(82)7.5 Linkage specifications [dcl.link] p191


#はじめに
N4606 Working Draft, Standard for Programming Language C++
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/#mailing2016-11
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf

n4606は、ISO/IEC JTC1 SC22 WG21の作業原案(Working Draft)です。
公式のISO/IEC 14882原本ではありません。
ISO/IEC JTC1 SC22 WG21では、可能な限り作業文書を公開し、幅広い意見を求めています。
一連の記事はコード断片をコンパイルできる形にする方法を検討してコンパイル、リンク、実行して、規格案の原文と処理系(g++, Clang++)との違いを確認し、技術内容を検討し、ISO/IEC JTC1 SC22 WG21にフィードバックするために用います。
また、CERT C++, MISRA C++等のコーディング標準のコード断片をコンパイルする際の参考にさせていただこうと考えています。CERT C++, MISRA C++が標準化の動きとの時間的なずれがあれば確認できれば幸いです。また、boostライブラリとの関連、Linux OS, TOPPERSカーネル、g++(GCC), clang++(LLVM）との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。

##作業方針
１）コンパイルエラーを収集する。
２）コンパイルエラーをなくす方法を検討する。
コンパイルエラーになる例を示すだけが目的のコードは、コンパイルエラーをなくすのではなく、コンパイルエラーの種類を収集するだけにする。
文法を示すのが目的のコード場合に、コンパイルエラーをなくすのに手間がかかる場合は、順次作業します。
３）リンクエラーをなくす方法を検討する。
文法を示すのが目的のコード場合に、リンクエラーをなくすのに手間がかかる場合は、順次作業します。
４）意味のある出力を作る。
コンパイル、リンクが通っても、意味のある出力を示そうとすると、コンパイル・リンクエラーが出て収拾できそうにない場合がある。順次作業します。

１）だけのものから４）まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。

## list
N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(1) coding list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/


## Compiler
###clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)

###g++-7 --version
g++-7 (Homebrew GCC 7.3.0_1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.

#(82)7.5 Linkage specifications [dcl.link]
p191

```c++:p191.cpp
// N4606 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf 
#define msg "p191.cpp(82)7.5 Linkage specifications [dcl.link]"

#include <iostream>
#define complex _Complex double

complex sqrt(complex); // C++ linkage by default
extern "C" {
  double sqrt(double); // C linkage
}
extern "C" void f1(void(pf)(int));
// the name f1 and its function type have C language
// linkage; pf is a pointer to a C function
extern "C" typedef void FUNC();
FUNC f2; // the name f2 has C++ language linkage and the
// function’s type has C language linkage
extern "C" FUNC f3; // the name of function f3 and the function’s type
// have C language linkage
void (*pf2)(FUNC); // the name of the variable pf2 has C++ linkage and
// the type of pf2 is pointer to C++ function that
// takes one parameter of type pointer to C function
extern "C" {
  static void f4(); // the name of the function f4 has
  // internal linkage (not C language
  // linkage) and the function’s type
  // has C language linkage.
}
extern "C" void f5() {
  extern void f4(); // OK: Name linkage (internal)
  // and function type linkage (C
  // language linkage) obtained from
  // previous declaration.
}
extern void f4(); // OK: Name linkage (internal)
// and function type linkage (C
// language linkage) obtained from
// previous declaration.
void f6() {
  extern void f4(); // OK: Name linkage (internal)
  // and function type linkage (C
  // language linkage) obtained from
  // previous declaration.
}
extern "C" typedef void FUNC_c();
class C {
  void mf1(FUNC_c*); // the name of the function mf1 and the member
  // function’s type have C++ language linkage; the
  // parameter has type pointer to C function
FUNC_c mf2; // the name of the function mf2 and the member
  // function’s type have C++ language linkage
static FUNC_c* q; // the name of the data member q has C++ language
  // linkage and the data member’s type is pointer to
  // C function
};
extern "C" {
  class X {
    void mf(); // the name of the function mf and the member
    // function’s type have C++ language linkage
    void mf2(void(*)()); // the name of the function mf2 has C++ language
    // linkage; the parameter has type pointer to
    // C function
  };
}
int x;
namespace A {
  extern "C" int f();
  extern "C" int g() { return 1; }
  extern "C" int h();
  extern "C" int x(); // ill-formed: same name as global-space object x
}
namespace B {
  extern "C" int f(); // A::f and B::f refer to the same function
  extern "C" int g() { return 1; } // ill-formed, the function g
  // with C language linkage has two definitions
}
int A::f() { return 98; } //definition for the function f with C language linkage
extern "C" int h() { return 97; } // definition for the function h with C language linkage
// A::h and ::h refer to the same function
extern "C" double f();
static double f(); // error
extern "C" int i; // declaration
extern "C" {
  int i; // definition
}
extern "C" static void g(); // error

int main(){
  std::cout<< msg << std::endl;
  return EXIT_SUCCESS;
}
```

```shell_session
$ ./cppgl17.sh p191
$ clang++ p191.cpp
p191.cpp:70:18: error: declaration of 'x' with C language linkage conflicts with declaration in global scope
  extern "C" int x(); // ill-formed: same name as global-space object x
                 ^
p191.cpp:65:5: note: declared in global scope here
int x;
    ^
p191.cpp:74:18: error: redefinition of 'g'
  extern "C" int g() { return 1; } // ill-formed, the function g
                 ^
p191.cpp:68:18: note: previous definition is here
  extern "C" int g() { return 1; }
                 ^
p191.cpp:80:19: error: functions that differ only in their return type cannot be overloaded
extern "C" double f();
           ~~~~~~ ^
p191.cpp:67:18: note: previous declaration is here
  extern "C" int f();
             ~~~ ^
p191.cpp:86:12: error: cannot combine with previous 'extern' declaration specifier
extern "C" static void g(); // error
           ^
p191.cpp:86:24: error: functions that differ only in their return type cannot be overloaded
extern "C" static void g(); // error
                  ~~~~ ^
p191.cpp:68:18: note: previous definition is here
  extern "C" int g() { return 1; }
             ~~~ ^
5 errors generated.

$ g++-7 p191.cpp
p191.cpp:80:21: warning: declaration of 'double f()' with C language linkage
 extern "C" double f();
                     ^
p191.cpp:73:18: warning: conflicts with previous declaration 'int B::f()'
   extern "C" int f(); // A::f and B::f refer to the same function
                  ^
p191.cpp:81:15: error: 'double f()' was declared 'extern' and later 'static' [-fpermissive]
 static double f(); // error
               ^
p191.cpp:80:19: note: previous declaration of 'double f()'
 extern "C" double f();
                   ^
p191.cpp:86:12: error: invalid use of 'static' in linkage specification
 extern "C" static void g(); // error
            ^~~~~~
p191.cpp:86:26: warning: declaration of 'void g()' with C language linkage
 extern "C" static void g(); // error
                          ^
p191.cpp:74:18: warning: conflicts with previous declaration 'int B::g()'
   extern "C" int g() { return 1; } // ill-formed, the function g
                  ^
```

#検討事項
コンパイルエラーをなくす修正。

#参考資料

コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)
https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da

Clang/Clang++(LLVM) gcc/g++(GNU) コンパイラ警告等比較
https://qiita.com/kaizen_nagoya/items/9a82b958cc3aeef0403f

Qiitaに投稿するCのStyle例(暫定)
https://qiita.com/kaizen_nagoya/items/946df1528a6a1ef2bc0d

MISRA C++ 5-0-16
https://qiita.com/kaizen_nagoya/items/7df2d4e05db724752a74

C++ Templates Part1 BASICS Chapter 3. Class Templates 3.2 Use of Class Template Stack stack1test.cpp
https://qiita.com/kaizen_nagoya/items/cd5fc49106fad5a4e9ed


ISO/IEC TS 17961:2013 C Secure Coding Rules(1) All list(to be confirmed)
https://qiita.com/kaizen_nagoya/items/54e056195c4f11b850a1

C言語（C++)に対する誤解、曲解、無理解、爽快。
https://qiita.com/kaizen_nagoya/items/3f3992c9722c1cee2e3a

C Puzzle Bookの有り難み5つ、C言語規格及びCコンパイラの特性を認識
https://qiita.com/kaizen_nagoya/items/d89a48c1536a02ecdec9

'wchar.h' file not found で困った clang++ macOS
https://qiita.com/kaizen_nagoya/items/de15cd46d657517fac11

Open POSIX Test Suiteの使い方を調べはじめました
https://qiita.com/kaizen_nagoya/items/644d5e407f5faf96e6dc

MISRA-C 2012 Referenceに掲載している文献の入手可能性を確認
https://qiita.com/kaizen_nagoya/items/96dc8b125e462d5575bb

どうやって MISRA Example Suiteをコンパイルするか
https://qiita.com/kaizen_nagoya/items/fbdbff5ff696e2ca7f00

MISRA C まとめ #include <misra_c.h>
https://qiita.com/kaizen_nagoya/items/f1a79a7cbd281607c7c9

#文書履歴
0.10 初稿 2080417