Я экспериментировал с C11 и VLAs, пытаясь объявить структурную переменную в стек только с неполным объявлением. Цель состоит в том, чтобы создать механизм для создания переменной какого-либо типа структуры без отображения внутренних элементов (например, идиомы PIMPL), но без необходимости создавать переменную в куче и возвращать указатель на нее. Кроме того, если макет структуры изменяется, я не хочу перекомпилировать каждый файл, который использует структуру.Полная инкапсуляция без malloc
мне удалось запрограммировать следующие:
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);
}
магистральный .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.
Вы не можете сделать это без перекомпиляции, когда макет структуры изменится, поскольку sizeof будет оптимизирован для постоянной времени компиляции, если вы используете VLA или alloca – Vality
@Vality: посмотрите еще раз на код - это будет оптимизация времени ссылки ; Разум Mabus должен звучать – Christoph
@Mabus благодарит за публикацию этого. Я не думал использовать VLA символов для хранения других типов. –