私は特に C/C++ の初心者ではありませんが、今日、予期していなかったことがいくつかわかりました。これは gcc でコンパイルされます。
/* test.c */
#include <stddef.h> // !
typedef unsigned long int size_t; // NO ERROR
typedef unsigned long int size_t; // NO ERROR
int
main(void)
{
typedef unsigned long int size_t; // NO ERROR
return 0;
}
これはしません:
/* test.c */
#include <stddef.h>
typedef unsigned long int size_t; // NO ERROR
typedef unsigned long int size_t; // NO ERROR
int
main(void)
{
typedef unsigned long int size_t; // NO ERROR
typedef unsigned long int size_t; // ERROR
return 0;
}
これはどちらもしません:
/* test.h */ // ! header
typedef unsigned long int size_t;
typedef unsigned long int size_t; // ERROR
同様に g++ では、これはコンパイルされます:
/* test.h */ // ! header
#include <cstddef>
inline void* operator new(size_t, void* p) throw() { return p; }
これはしません:
/* test.h */ // ! header
#include <new> // !
inline void* operator new(size_t, void* p) throw() { return p; } // ERROR
これは次のことを行います。
/* test.cc */
#define _NEW
#include <new> // !
#include <iostream>
#include <cstdlib>
using std::cout;
using std::endl;
inline void* operator new(size_t size) throw() // NO ERROR EXPECTED
{
cout << "OPERATOR NEW CALLED" << endl;
return malloc(size);
}
inline void* operator new(size_t, void* p) throw() // NO ERROR
{
cout << "PLACEMENT NEW CALLED" << endl;
return p;
}
int main()
{
char *buffer[4];
int *i = new (buffer) int;
int *j = new int;
return 0;
}
(標準の new 演算子を置き換えることは、上記のすべてのケースで機能します。置換 new 演算子を置き換えることは違法です。私は知っています。)
パターンを見るのは簡単ですが、誰かが「標準的な」説明をしてくれませんか? .h ファイルではできないことを .c または .cc ファイルで実行できるのはなぜですか (古い typedef を再定義し、置換が違法な関数を置換します)。
返信いただきありがとうございます。ヘッダー ガードを含む一部のコードを省略しました。最後の .cc の例では、 << を & gt として HTML エンコードしました。> cstdlib を含めるのを忘れていました。コンパイルできるようにコードを修正しました。ただし、もう 1 つ省略していたのは #define _NEW で、これは非常に重要であることがわかりました。どうやら GNU では <new> のヘッダー ガードで _NEW が定義されているため、ここでそれを定義すると、標準の新しいヘッダーを含めることができなくなり、置換が機能しました。
m@m:~/Desktop/Library$ ./a.out プレースメント 新しいと呼ばれる オペレーターが新しく呼び出されました
ええ、説明されていない唯一のことは、.c/.cc ファイルで複数回 typedef を再定義できるのに、.h ではできないということです。
/* test.c */
#include <stddef.h>
typedef unsigned long int size_t; // NO ERROR
typedef unsigned long int size_t; // NO ERROR
int
main(void)
{
typedef unsigned long int size_t; // NO ERROR
return 0;
}
とにかくそうしたいというわけではありませんが、ただ疑問に思っています。
編集:ありがとう、それは本当にすべてに答えます。それを xyz に変更すると、特定のスコープで複数の定義が許可されなくなります。これは正しいと感じます。:) 私がこれらの小さなテストを行った理由は、小さなオペレーティング システム用に C および C++ のサブセットを作成しているからですが、既存のライブラリを使用して何も削除せずにテストを支援しているため、試していました。 (1) 自分のコードがテストで呼び出されていること (例: 新しいプレースメント) と (2) 自分のコードが GNU ライブラリと衝突しないことを確認する方法を見つけます。(1) に対する答えは、かなり明白に思えます。標準 Xh から Xh にヘッダー ガード マクロを #define するだけです :)。