首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >alsa中的alloca而不是局部变量

alsa中的alloca而不是局部变量
EN

Stack Overflow用户
提问于 2018-10-16 07:54:06
回答 1查看 111关注 0票数 0

我使用了一个示例C ALSA程序作为参考,并运行了以下代码:

代码语言:javascript
复制
...
snd_ctl_event_t *event;
snd_ctl_event_alloca(&event);
...

基于ALSA源代码,snd_ctl_event_alloca是一个调用__snd_alloca的宏,它最终扩展为snd_ctl_event_alloca(&event);的以下等效行(经过一些简单的简化):

代码语言:javascript
复制
event = (snd_ctl_event_t *) alloca(snd_ctl_event_sizeof());
memset(event, 0, snd_ctl_event_sizeof());

其中snd_ctl_event_sizeof()在整个库中只实现一次:

代码语言:javascript
复制
size_t snd_ctl_event_sizeof()
{
    return sizeof(snd_ctl_event_t);
}

所以我的问题是,整个过程是不是等同于简单地做:

代码语言:javascript
复制
snd_ctl_event_t event = {0};

作为参考,以下是宏:

代码语言:javascript
复制
#define snd_ctl_event_alloca(ptr) __snd_alloca(ptr, snd_ctl_event)
#define __snd_alloca(ptr,type) do { *ptr = (type##_t *) alloca(type##_sizeof()); memset(*ptr, 0, type##_sizeof()); } while (0)

澄清:

  • 上面的第一个代码块位于函数体的开头,而不是嵌套块

编辑

事实证明(根据我的理解),做:

代码语言:javascript
复制
snd_ctl_event_t event;

因为snd_ctl_event_t显然是一个私下定义的不透明结构,所以会产生一个storage size of 'event' isn't known错误。因此,唯一的选择就是动态分配。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-16 07:59:55

由于它是一个不透明的结构,所有这些操作的目的显然是实现一个不透明的数据类型,同时保存所有的“优点”,并至少击败它们的一些“缺点”。

不透明数据类型的一个突出问题是,在标准C中,你必须在一个不透明的库函数中动态地分配它们。不可能在本地隐式声明不透明对象。这会对效率产生负面影响,并经常迫使客户端实现额外的资源管理(即,记住在不再需要对象时将其释放)。公开不透明对象的确切大小(在本例中是通过一个函数),并依靠alloca来分配存储空间,这与更高效、更无忧无虑的本地声明是最接近的。

如果不需要函数范围的生命周期,可以用VLA替换alloca,但作者可能不想/不能使用VLA。(我想说的是,使用VLA更接近于模仿真正的本地声明。)

通常,为了实现相同的技术,不透明的对象大小可能在头文件中公开为编译时常量。然而,使用函数有一个额外的好处,即如果此隔离库中的对象大小发生变化,则不必重新编译整个项目(正如@R在注释中所指出的那样)。

之前版本的答案(下面的几点仍然适用,但显然是次要的):

它并不完全等价,因为alloca违反了基于作用域的生命周期规则。alloca-ed内存的生存期延长到函数的末尾,而本地对象的生存期仅延长到块的末尾。这可能是一件坏事,也可能是件好事,这取决于你如何使用它。

在像这样的情况下

代码语言:javascript
复制
some_type *ptr;

if (some condition)
{
  ...
  ptr = /* alloca one object */;
  ...
}
else
{
  ...
  ptr = /* alloca another object */;
  ...
}

语义上的区别可能是至关重要的。不管这是不是你的案例--我不能从你到目前为止发布的内容中说出来。

语义上另一个不相关的区别是,memset将清零对象的所有字节,而= { 0 }不能保证清零填充字节(如果有的话)。如果对象随后与一些基于二进制的API一起使用(如发送到压缩的I/O流),这可能很重要。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52826194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档