次のプログラムを検討してください。
#include <cstdio>
int main()
{
int printf=9;
std::printf("%d",printf);
}
組み込み関数名を変数宣言の識別子として使用しても問題ありませんか? これは明確に定義されたプログラムですか?つまり、上記のプログラムの動作は明確に定義されていますか? C++ 標準で標準関数名を変数の識別子として使用できるかどうか知りたい
次のプログラムを検討してください。
#include <cstdio>
int main()
{
int printf=9;
std::printf("%d",printf);
}
組み込み関数名を変数宣言の識別子として使用しても問題ありませんか? これは明確に定義されたプログラムですか?つまり、上記のプログラムの動作は明確に定義されていますか? C++ 標準で標準関数名を変数の識別子として使用できるかどうか知りたい
どちらstd::printf
も::printf
( !によっても宣言されている可能性が<cstdio>
あります) が整数と同じスコープで宣言されていないため、整形式です。したがって、ブロックの期間中は自動的に優先されます。
[C++14: 3.3.1/1]:
[..]宣言のスコープを決定するために、宣言の潜在的なスコープを参照すると便利な場合があります。宣言のスコープは、潜在的なスコープに同じ名前の別の宣言が含まれていない限り、潜在的なスコープと同じです。その場合、内側の (含まれる) 宣言領域の宣言の潜在的なスコープは、外側の (含む) 宣言領域の宣言のスコープから除外されます。
たとえば、通常、名前空間スコープでこれを行うことはできません。
標準ライブラリ内のエンティティの名前は本質的に予約された名前ではないため、明確に定義されています。
[C++14: 2.11/3]:
さらに、一部の識別子は C++ 実装および標準ライブラリ (17.6.4.3.2) で使用するために予約されており、それ以外では使用されません。診断は必要ありません。
[C++14: 17.6.4.3.2/1]:
名前と関数シグネチャの特定のセットは、常に実装用に予約されています。
- 2 つのアンダースコアを含む名前、
_ _
またはアンダースコアで始まり、その後に大文字が続く名前 (2.12) は、実装で使用するために予約されています。- アンダースコアで始まる各名前は、グローバル名前空間で名前として使用するために実装に予約されています。
これを行うことは技術的に許可されています。グローバル名前空間で予約されている名前がありますが、関数内では変数名は関数の外では見えないので問題ありません。
これを使うのはひどい考えです。
また、このアプローチには問題がある可能性があることに注意してください。例えば:
#define NULL 0
int main()
{
int NULL = 42;
printf("%d", NULL);
}
NULL
はマクロであり、スコープ識別子ではないため、許可されていません。
printf
編集: 「組み込み関数」ではないことを付け加えます。「C標準ライブラリ関数」です。bultin 関数は のようなもの__builtin_sin
で、最適化できるようにコンパイラが「知っている」ものです。組み込み関数は通常、既存のライブラリおよびユーザー定義の名前との衝突を常に回避するために、「予約済みの名前」を使用することに注意してください。
そうしても構いません。定義した変数は、 で定義されている名前空間asにint printf
属していないためです。したがって、実際にはプログラムの名前に競合はありません。std
printf
cstdio
ただし、宣言すると
using namespace std;
プログラムの前にstd::
使用され、プログラムの後半で使用されない場合、注意しないと問題が発生します。一般に、名前の競合がある場合、コンパイラは最小のスコープで定義された名前を使用します。したがって、次のようなプログラムがある場合:
#include<cstdio>
using namespace std;
int main()
{
int printf = 42;
printf("%d", printf);
}
コンパイラは戻ります
error: ‘printf’ cannot be used as a function
これは、このプログラムでprintf
は、 が関数スコープで定義され、グローバル スコープint
で関数として定義されているためです。int printf( const char* format, ... )
関数のスコープはグローバル スコープよりも小さいため、 function では、関数int main()
ではなくprintf
として解釈されます。呼び出し可能ではないため、エラーメッセージが表示されます。int
int