标题几乎说明了一切,但我会重申这个问题……
以下程序是否符合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. */ }
解决方法
让我们来看看C99标准对它的看法:
见第7节7.1.3,§1:
Each identifier with file scope listed in any of the following subclauses […] is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.
当您包含stdlib.h时,名称malloc保留用作宏名称.
但是7.1.4,§1允许在保留名称上使用#undef:
The use of
#undef
to remove any macro definition will also ensure that an
actual function is referred to.
这使得可以重新定义malloc,根据7.1.3,§2导致未定义的行为:
If the program […] defines a reserved identifier as a macro name,the behavior is undefined.
为什么标准会制定此限制?因为标准库的其他函数可以在原始函数方面实现为类函数宏,所以隐藏声明可能会破坏这些其他函数.
实际上,只要你的malloc定义满足标准为库函数提供的所有规定,你就应该没问题,这可以通过将实际调用包装到malloc()来实现.