【发布时间】:2014-06-07 20:17:37
【问题描述】:
我对 Eric Roberts 的 Programming Abstractions in C 中的一些代码有疑问。他使用自己的几个库来为读者简化事情并教授如何编写库。 (本书的所有图书馆代码都可以在on this site找到。)
一个库genlib 提供了一个宏,用于泛型分配指向struct 类型的指针。我不明白宏的一部分。我将复制下面的代码,以及如何使用它的示例,然后我将更详细地解释我的问题。
/*
* Macro: New
* Usage: p = New(pointer-type);
* -----------------------------
* The New pseudofunction allocates enough space to hold an
* object of the type to which pointer-type points and returns
* a pointer to the newly allocated pointer. Note that
* "New" is different from the "new" operator used in C++;
* the former takes a pointer type and the latter takes the
* target type.
*/
#define New(type) ((type) GetBlock(sizeof *((type) NULL)))
/* GetBlock is a wrapper for malloc. It encasulates the
* common sequence of malloc, check for NULL, return or
* error out, depending on the NULL check. I'm not going
* to copy that code since I'm pretty sure it isn't
* relevant to my question. It can be found here though:
* ftp://ftp.awl.com/cseng/authors/roberts/cs1-c/standard/genlib.c
*/
Roberts 打算将代码按如下方式使用:
typedef struct {
string name;
/* etc. */
} *employeeT;
employeeT emp;
emp = New(employeeT);
他更喜欢使用指向记录的指针作为类型名称,而不是记录本身。所以New 提供了一种通用的方式来分配这样的struct 记录。
在宏New中,我不明白的是:sizeof *((type)) NULL)。如果我没看错,它会说“将NULL 的取消引用转换的大小取为struct 类型type 在给定调用中表示的任何值”。我想我理解取消引用:我们想为结构分配足够的空间;指针的大小不是我们需要的,所以我们取消引用以获得底层记录类型的大小。但我不明白将NULL 转换为类型的想法。
我的问题:
- 你可以投
NULL吗?这到底是什么意思? -
为什么需要演员表?当我尝试删除它时,编译器显示
error: expected expression。那么,sizeof *(type)不是表达式吗?这让我很困惑,因为我可以执行以下操作来获取任意指向结构的指针的大小:#define struct_size(s_ptr) do { \ printf("sizeof dereferenced pointer to struct %s: %lu\n", \ #s_ptr, sizeof *(s_ptr)); \ } while(0)
编辑:正如许多人在下面指出的那样,这两个示例并不相同:
/* How genlib uses the macro. */
New(struct MyStruct*)
/* How I was using my macro. */
struct MyStruct *ptr; New(ptr)
郑重声明,这不是家庭作业。我是一个试图提高 C 语言的业余爱好者。此外,据我所知,代码没有问题。也就是说,我不是在问如何用它做一些不同的事情。我只是想更好地理解 (1) 它是如何工作的以及 (2) 为什么它必须按原样编写。谢谢。
【问题讨论】:
-
如果
s_ptr不是表达式,则您的struct_size宏无效。如果您将struct MyStruct *传递为s_ptr,则代码将无法编译,因为sizeof *(struct MyStruct *)不是有效的C... 而且不,*(type)不是表达式,因为它没有意义——究竟是什么您是否期望*(type)评估为? -
@FilipeGonçalves 对于我的预期,我没有一个好的答案。我很困惑。这就是问题所在。
标签: c macros struct null expression