(質問に対するコメントは、C99 セクション 7.1.3 の意味で予約済みの識別子について話していることを説明しています。つまり、ファイル スコープ内、外部リンケージなどの/^_[A-Z_]/
任意の場所に一致する識別子です。あなたが求めていることの...)/^_/
/^str[a-z]/
コンパイラ (の特定のフェーズ) がそれらの誤用を診断することが期待されているという意味で、それらは予約されていません。むしろ、それらを自分で (誤用) 使用するほど愚かである場合、後でプログラムが動作しなくなったり、コンパイルが停止したりしても、文句を言うことができないという点で予約されています。
危険な量の知識しか持っていない人がシステム ヘッダーの内部を調べて、独自のヘッダー ガードを作成するとどうなるかを見てきました。
#ifndef _MYHEADER_H
#define _MYHEADER_H
// ...
#endif
彼らは未定義の動作を呼び出していますが、これを「エラー: エンドユーザー コードで使用される予約済み識別子」と診断するものは何もありません。代わりに、ほとんどの場合、彼らは幸運で、すべてが順調です。しかし、時折、実装にとって重要な識別子と衝突し、紛らわしいことが起こります。
同様に、次のような名前の外部から見える関数がよくありますstrip()
。
char *strip(char *s) {
// remove leading whitespace
}
C99 の 7.1.3、7.26、および 7.26.11 を読んだところ、これは未定義の動作を引き起こします。しかし、私はこれを気にしないことにしました。識別子は、今日何か悪いことが起こると予想されるという点で予約されているわけではありませんが、標準str-ip()
は将来の改訂で新しい標準ルーチンを発明する権利を留保しているためです。そして私は、文字列-ip
は、それが何であれ、将来追加される文字列操作の名前としてはありそうもない- と考えることに決めた.それ。技術的には、未定義の動作を呼び出していますが、噛まれるとは思っていません。
最後に、ポイント4の反例:
#include <string.h>
#define memcpy(d,s,n) (my_crazy_function((n), (s)))
void foo(char *a, char *b) {
memcpy(a, b, 5); // intends to invoke my_crazy_function
memmove(a, b, 5); // standard behaviour expected
}
これは、4.1、4.2、4.3 に準拠しています (最後の 1 つの意図を理解している場合)。ただし、memmove
を で記述したマクロ (7.1.4/1 経由) として追加実装memcpy
すると、問題が発生します。