2

それについての議論があったに違いないと思いますが、なぜisspaceC と C++ で一貫していないのか理解できません

( clangアナライザーを使用して定義情報を取得しています)

// test.c
#include <ctype.h>
int main(int argc, char *argv[]) {
  isspace('a');
  return 0;
}

clang は、isspace の宣言として以下を報告します。

# define isspace(c) __isctype((c), _ISspace)  // LINE 207 in /usr/include/ctype.h

そして、このスニペットの場合:

// test.cpp
#include <cctype>
int main() {
  std::isspace('t');
  return 0;
}

clang はここで宣言を報告します。

__exctype (isspace);  // LINE 120 in /usr/include/ctype.h
// #define  __exctype(name) extern int name (int) __THROW

では、なぜこのような違いが必要なのでしょうか?

4

3 に答える 3

2

C++ には、実際にマクロである場合、template< class CHAR > bool isspace( CHAR, const std::locale& );恐ろしく壊れる関数があります。isspace歴史的に、C ではパフォーマンス上の理由からマクロでした。

于 2013-06-02T22:35:03.573 に答える
2

一貫して動作する限り、C および C++ 標準が必要とするのはそれだけです。

C では、標準isspaceでライブラリ関数として定義されています。他の標準ライブラリ関数と同様に、マクロが関数と同じことを行う限り、実装はマクロとして追加で定義することが許可されていますが、必須ではありません。マクロとして定義されている場合は、いつでもバイパスして関数にアクセスできます。

(isspace)(c) /* the parentheses around the name inhibit macro expansion */

また

#undef isspace
isspace(c);

ただし、関数へのポインターが必要でない限り、これを行う理由はほとんどありません。

C++ では、マクロは名前空間の影響を受けstd::isspaceないため、マクロを参照できません。実装によってはisspace、Cで参照されているのと同じ関数を参照している可能性があります。接頭辞#include <ctype.h>を使用しても使用しなくても、マクロを参照できます。std::

しかし、そうする正当な理由はありません。isspaceその引数が空白文字であるかどうかを示します。これは、実行する必要があることです。

于 2013-06-03T00:24:48.887 に答える
0

どのような違いについて話しているのですか?これらは、同じ関数の 2 つの異なる名前です。

C言語ライブラリ

C++ ライブラリには、ヘッダー ファイルの同じ構造で編成された C 言語ライブラリと同じ定義が含まれていますが、次の違いがあります。

  • 各ヘッダー ファイルは、C 言語バージョンと同じ名前ですが、"c" プレフィックスが付き、拡張子はありません。たとえば、C 言語のヘッダー ファイルに相当する C++ <stdlib.h><cstdlib>.

  • ライブラリのすべての要素はstd名前空間内で定義されます。

ここから)


ctype.hOK、あなたが言及したこれらの行を見回すと、 120行目でこの関数が宣言されていることに気付くでしょう。そして、その実装は 207 行目に示されています。

あなたはそれをすべて気にするべきではありません。本当。

于 2013-06-02T13:47:52.323 に答える