标题几乎说明了一切,但我要重申这个问题……
下面的程序是C99标准下的“严格符合程序”吗?
#include <stdlib.h>
/* Removing any pre-existing macro definition, in case one should exist in the implementation.
* Seems to be allowed under 7.1.3 para 3, as malloc does not begin with _X where X is any capital letter.
* And 7.1.4 para 1 explicitly permits #undef of such macros.
*/
#ifdef malloc
#undef malloc
#endif
/* Macro substitution has no impact on the external name malloc
* which remains accessible, e.g., via "(malloc)(s)". Such use of
* macro substitution seems enabled by 7.1.4 para 1, but not specifically
* mentioned otherwise.
*/
void * journalling_malloc(size_t size);
#define malloc(s) ((journalling_malloc)(s))
int main(void)
{
return malloc(10) == NULL ? 1 : 0;
/* Just for the sake of expanding the
* macro one time, return as exit code
* whether the allocation was performed.
*/
}发布于 2010-02-16 05:15:50
让我们看看C99标准对此有什么规定:
见7.1.3,§1,第5条:
使用以下任意子句中列出的文件作用域
每个标识符...是否保留以用作宏名称,如果包含任何与其相关联的标头,则将其用作具有相同名称空间中的文件范围的标识符。
由于包含stdlib.h,因此名称malloc将保留用作宏名称。
但是7.1.4,§1允许在保留名称上使用#undef:
使用
#undef删除任何宏定义也将确保引用实际的函数。
这使得重新#define malloc成为可能,这导致根据7.1.3,§2:
如果程序...将保留标识符定义为宏名称,行为为 undefined。
为什么标准会有这样的限制?因为标准库的其他函数可能被实现为与原始函数类似的宏,所以隐藏声明可能会破坏这些其他函数。
在实践中,只要您对malloc的定义满足标准为库函数提供的所有规定,就应该没问题,这可以通过包装对malloc()的实际调用来实现。
发布于 2010-02-16 02:44:43
您可能希望将journalling_malloc(...)从void更改为void *,将注释更改为// (因为它们注释掉了您的undef),并在顶部附近添加一个#endif,但除此之外,它看起来还不错。
发布于 2010-02-16 04:23:43
它会工作吗:是的。
它是否符合:不符合。
根据C标准:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
标准库中的所有名称都是保留的(包括malloc)。
7.1.3 Reserved identifiers
Specifically:
<quote>Each macro name in any of the following subclauses</quote>
<quote>All identifiers with external linkage in any of the
following subclauses</quote>此外,严格一致的程序将不能定义为实现保留的名称(即,这包括保留的名称和标识符、为当前库保留的名称和为将来使用的名称)。
7.1.3 (note 2)
Specifically:
<quote>If the program declares or defines an identifier in a context in which
it is reserved or defines a reserved identifier as a macro name,
the behavior is undefined.</quote>因此,根据定义:定义malloc()是不一致的,因为它是未定义的行为(非法)。
https://stackoverflow.com/questions/2268149
复制相似问题