复合语句中的 alloca

Posted

技术标签:

【中文标题】复合语句中的 alloca【英文标题】:alloca inside compound statement 【发布时间】:2015-09-30 08:29:50 【问题描述】:

可以在复合语句中使用 alloca 吗? 示例:

typedef struct

    size_t len;
    char* data;
 string_t;

#define str_to_cstr(str) \
( \
    char* v = alloca(str.len + 1); \
    v[len] = 0; \
    memcpy(v, str.data, str.len); \
)

// ... and somewhere in deep space
int main()

    string_t s = 4, "test";
    printf("%s\n", str_to_cstr(s));
    return 0;

根据我的经验,它运作良好,但我不确定它是否安全。 顺便说一句,它是用 gcc 4.8.4 编译的

【问题讨论】:

... 或者,memcpy(v, str.data, str.len+1); 虽然您的建议应该可行,但为什么不在.data 的末尾保留一个空字符并使用它(可能转换为const char *)? 虽然没关系,但您应该考虑使用variable length array (VLA)。它们是随 C99 引入的。 为什么使用宏而不是inline 函数?该宏会破坏您的代码并不必要地使用 gcc 扩展。 是的,我知道 VLA,但我试图找到“单行解决方案”。内联在这里不适合,因为 alloca 使用调用 alloca 的函数堆栈 【参考方案1】:

在您的示例中不安全:

 printf("%s\n", str_to_cstr(s));

来自alloca的glibc documentation:

不要在函数调用的参数中使用 alloca——你会得到不可预知的结果,因为 alloca 的堆栈空间会出现在函数参数空间的中间。一个要避免的例子是 foo (x, alloca (4), y)。

请注意,() 不是复合语句,而是 GNU C statement expression

【讨论】:

嗯,我发现“man alloca”的弱点:On many systems alloca() cannot be used inside the list of arguments of a function call, because the stack space reserved by alloca() would appear on the stack in the middle of the space for the function arguments 那么,这是否意味着某些系统允许在参数中使用 alloca? @user939407 这意味着你不应该这样做。

以上是关于复合语句中的 alloca的主要内容,如果未能解决你的问题,请参考以下文章

如何正确格式化 Coffeescript 中的长复合 if 语句

流程控制语句

在 C 中使用 ?: 运算符的复合 if 语句 [重复]

Pytho基础要点:7种复合语句在编写时要遵循的语法风格

循环选择要注意的复合语句

JavaScript(第五天)