【发布时间】:2009-04-18 04:01:06
【问题描述】:
我对 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 运算符是非法的,我知道。)
很容易看到一种模式,但有人可以给我一个“标准”的解释吗? 为什么我可以在 .c 或 .cc 文件中做一些我在 .h 文件中做不到的事情(重新定义旧的 typedef,替换非法替换的函数)?
感谢您的回复。我省略了一些代码,包括标题保护。在最后一个 .cc 示例中,我将 HTML 编码为 的标头保护定义了 _NEW,所以我在这里定义它阻止了标准新标头的包含,所以我替换工作了
m@m:~/Desktop/Library$ ./a.out 安置新呼叫 操作员新呼叫所以,是的,唯一无法解释的是我为什么可以多次在 .c/.cc 文件中重新键入定义内容,但不能像这样在 .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)的答案现在看起来很明显。我只是将标准 X.h 中的标头保护宏#define 到我的 X.h 中:)。
【问题讨论】:
-
听起来像是 GCC 特有的问题。
标签: c++ operator-overloading new-operator replace