【发布时间】:2014-10-21 16:41:57
【问题描述】:
我正在试验 C11 和 VLA,试图在堆栈上声明一个结构变量,但声明不完整。目标是提供一种机制来创建某种结构类型的变量,而不显示内部结构(如 PIMPL 习惯用法),但无需在堆上创建变量并返回指向它的指针。另外,如果结构布局发生变化,我不想重新编译每个使用该结构的文件。
我已经成功地编写了以下程序:
private.h:
#ifndef PRIVATE_H_
#define PRIVATE_H_
typedef struct A{
int value;
}A;
#endif /* PRIVATE_H_ */
public.h:
#ifndef PUBLIC_H_
#define PUBLIC_H_
typedef struct A A;
size_t A_getSizeOf(void);
void A_setValue(A * a, int value);
void A_printValue(A * a);
#endif /* PUBLIC_H_ */
implementation.c:
#include "private.h"
#include "stdio.h"
size_t A_getSizeOf(void)
{
return sizeof(A);
}
void A_setValue(A * a, int value)
{
a->value = value;
}
void A_printValue(A * a)
{
printf("%d\n", a->value);
}
main.c:
#include <stdalign.h>
#include <stddef.h>
#include "public.h"
#define createOnStack(type, variable) \
alignas(max_align_t) char variable ## _stack[type ## _getSizeOf()]; \
type * variable = (type *)&variable ## _stack
int main(int argc, char *argv[]) {
createOnStack(A, var);
A_setValue(var, 5335);
A_printValue(var);
}
我已经测试了这段代码,它似乎可以工作。但是我不确定我是否忽略了一些可能危险或不可移植或可能损害性能的东西(如混叠、对齐或类似的东西)。另外我想知道在 C 中是否有更好的(便携式)解决方案来解决这个问题。
【问题讨论】:
-
当结构布局发生变化时,如果你使用 VLA 或 alloca,sizeof 将被优化为编译时间常数,因此如果不重新编译,你将无法明智地做到这一点
-
@Vality:再看一下代码——那将是链接时优化;马布斯的推理应该是合理的
-
@Mabus 感谢您发布此信息。我没有想过使用字符的 VLA 来为其他类型提供存储。
标签: c c99 c11 pimpl-idiom variable-length-array