これは別の質問。
元の質問には他にも問題がありましたが、主な問題は(CLangによると)time
異なる記号としての再定義一方、ニースC++ インクルードが使用されました。
ということで、簡略化したバージョンを以下に示します。
#include<iostream>
using std::cout;
using std::endl;
class time
{
public:
int h, min, sec;
};
const int full = 60;
void canonify(time& pre) // Error here (line 14)
{
pre.min += pre.sec / full;
pre.h += pre.min / full;
pre.sec %= full;
pre.min %= full;
}
int main()
{
time a; // and here (line 23)
a.h = 3;
a.min = 128;
a.sec = 70;
canonify(a);
cout << a.h << ":" << a.min << ":" << a.sec << endl;
}
もちろん、time
別のシンボルに置き換えたり使用したりするstruct time
だけで問題は解決します。言い換えると、私の質問はないコードを実行する方法ではなく、Cライブラリのシンボルを次のように表示する必要があるかどうかだけです。予約トークンC++ の場合、Clang 11 (MSVC19 上) は次の点で動作しません:
1>ess.cpp(14,15): error : must use 'class' tag to refer to type 'time' in this scope
1>...\ucrt\time.h(518,42): message : class 'time' is hidden by a non-type declaration of 'time' here
1>ess.cpp(23,5): error : must use 'class' tag to refer to type 'time' in this scope
1>...\ucrt\time.h(518,42): message : class 'time' is hidden by a non-type declaration of 'time' here
そこで疑問になるのが、C++ 標準では、コンパイル単位に明示的に含まれていない C 標準ライブラリのシンボルを自由に使用することをどこで禁止しているのかということです。
興味深いことに、同じコード (一度翻訳すると...) は C でも正常に動作します。
#include <stdio.h>
//
typedef struct
{
int h, min, sec;
}time;
//
const int full = 60;
//
void canonify(time* pre)
{
pre->min += pre->sec / full;
pre->h += pre->min / full;
pre->sec %= full;
pre->min %= full;
}
int main()
{
time a;
a.h = 3;
a.min = 128;
a.sec = 70;
canonify(&a);
printf("%d:%d:%d\n", a.h, a.min, a.sec);
return 0;
}
ベストアンサー1
[外部名]
3外部リンケージで宣言された C 標準ライブラリの各名前は、名前空間 std とグローバル名前空間の両方で、extern "C" リンケージを持つ名前として使用するために実装用に予約されています。
この段落では名前自体が予約されていることに注意してください。したがって、time
グローバル名前空間でのエイリアス化はこの契約に違反します。