在 C99 中组合指定的初始值设定项和 malloc?
有没有一种好的方法可以将 C99 中的指定初始值设定项与 malloc
的结果结合起来?
以下似乎有不必要的重复:
typedef struct {
int a, b, c;
} Type;
Type *t = malloc(sizeof *t);
*t = (Type) {
.a = 2,
.b = 3,
.c = 5,
};
可以从上面的代码中删除 Type
和 *t
的使用吗?
Is there a nice way to combine designated initializers from C99, with the result of a malloc
?
The following seems to have needless duplication:
typedef struct {
int a, b, c;
} Type;
Type *t = malloc(sizeof *t);
*t = (Type) {
.a = 2,
.b = 3,
.c = 5,
};
Can the use of Type
, and *t
be removed from the above code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
既然你问了;)C 中有一种工具可以避免显式重复代码,即宏。也就是说,我看不出有什么方法可以不重复至少类型的名称。但在 C++ 中它们也不能,所以 C 至少同样好:)
我看到的最简单的是
这将给
它带来几个优点。
浮点类型或指针的
0
的标准表示。注意:观察宏中的 const,如果编译器认为这是相关的,则这允许折叠复合文字的多个实例。还有一些方法可以有一个变体,其中指示符列表是可选的,请参见下面的 P99。
缺点是
memcpy
,我会对作业更满意。其次,在使用结果之前不会检查 malloc 是否失败,但人们可能会遇到一些奇怪的情况,让代码正常退出。在 P99 中,我采取了稍微不同的方式。我们总是有一个类型的初始化函数,
通过宏魔法可以为
a
、b
和c
提供默认参数。 > 如果它们被省略。 使用类似的内容然后您可以简单地在应用程序代码中 。这更好,因为它可以避免在调用
malloc
失败时取消引用指针。另一方面,这重新向初始化器引入了顺序,因此也不完美。Since you asked ;) there is one tool in C to avoid explicit duplication of code, macros. That said I don't see a way not to repeat at least the name of the type. But in C++ they can't either, so C is at least as good :)
The easiest I see is
which would give
this has several advantages.
standard representations of the
0
for float types or pointers.NB: Observe the
const
in the macro, this allows several instances of the compound literal to be folded, if the compiler decides this to be relevant. Also there are means to have a variant where the list of designators is optional, see P99 below.The disadvantage is the
memcpy
and I would be happier with an assignment. Second there is no check for failure ofmalloc
before using the result, but one could probably come across with some weirdness to have the code exit nicely.In P99 I go a slightly different way. There we always have an initialization function for a type, something like
which by macro magic can be made to provide default arguments for
a
,b
andc
if they are omitted. Then you can simply use something likein your application code. This is better, since it avoids dereferrencing the pointer when the call to
malloc
failed. On the other hand this reintroduces an order to the initializers, so not perfect either.您可以使用可变参数宏。我不会说这是一个好主意,但它确实有效:
请注意,我无法使用通常的
do { ... } while (0)
宏定义技巧 (它会创建一个新的作用域,并且t
将不可见),因此您必须小心使用它的上下文。就我个人而言,我认为我对不必要的重复更满意。
You can with a variadic macro. I'm not going to claim that this is a good idea, but it works:
Note that I wasn't able to use the usual
do { ... } while (0)
macro definition trick (it would create a new scope, andt
wouldn't be visible), so you'd have to be careful about the context in which you use this.Personally, I think I'm happier with the needless duplication.
不,这是使用指定初始值设定项的唯一方法。如果没有 (Type){},编译器将不知道如何验证内容。
No, that's the only way to use designated initializers. Without the (Type){}, the compiler doesn't know how to validate the contents.