LINUX.ORG.RU

Инициализация константных полей структур

 


0

2

Как вы инициализируете структуры с const-полями, выделяемые в куче?

А то я знаю только один рабочий способ, но он выглядит как-то... неестественно:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

struct foo {
        void *const ptr;
};

int main()
{
        struct foo *bar;

        bar = malloc(sizeof(*bar));

        memcpy(bar, &(struct foo) { bar }, sizeof(*bar));

        printf("%p", bar->ptr);
}

★★★

Как вы инициализируете структуры с const-полями, выделяемые в куче?

зачем это может быть нужно?

Harald ★★★★★
()
Ответ на: комментарий от Harald

Нее, тогда уж лучше отдельные поля при присваивании приводить к без const виду.

anonymous
()

Скорее всего нужно создавать static inline функции по изменению каждого из const полей. В описании назвать все это грязным хаком. Внутри производить присваивание с предварительным приведением к без const виду. Искать все изменения этих полей будет легко локализовать и по проекту они не будут разбегаться.

anonymous
()

структуры с const-полями

Ух, жестокая у тебя травища!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от niemand

Это GCC-экстеншн, можно вписывать произвольный код и значение «последнего выражения» будет результатом. Другое дело что тут обычные скобки подойдут...

intelfx ★★★★★
()

Явно приводи к не-const. в данном случае это разрешено.

intelfx ★★★★★
()

const существует, чтобы ты не лез своими руками в структуру, на которую, например, получил указатель. Ситуация, когда часть полей доступна на чтение/запись, а другая — только на чтение, возможна при работе с mmio. Поля const можно изменять с помощью хаков, как здесь указывали, но это — ССЗБ.

pS
()
Ответ на: комментарий от pS

Вот я-то и должен проинициализировать и отдать указатель на эту структуру. const стоит для её пользователей, что они потом не лезли туда своими руками.

Я пытаюсь узнать, есть ли какой-то другой способ это сделать нормально, без реверансов перед компилятором. Должен же он быть для кого-то очевиден, если вообще существует.

ilammy ★★★
() автор топика

В чём проблема прикастовать к non-const?

*((void **) &(bar->ptr)) = bar;
Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от ilammy

Старый метод — два хедера (один приватный, другой пользовательский). Конечно, несоответствие полей в структурах — источник ошибок.

pS
()
Ответ на: комментарий от ilammy

Вот я-то и должен проинициализировать и отдать указатель на эту структуру. const стоит для её пользователей, что они потом не лезли туда своими руками.

Определи одну такую константную структуру - образец, инициализируй как надо и делай memcpy с нее.

Pavval ★★★★★
()
Ответ на: комментарий от pS

Кроме того, можно

#if defined DEVEL
#define MY_CONST
#else
#define MY_CONST const
#endif
...
struct foo {
        void *MY_CONST ptr;
};
...

pS
()

Есть такое понятие - фабрика. Сделай функцию: struct foo * make_foo(), в которой все создавая и инициализируй.

BRE ★★
()

Я обычно скрываю поля в которые «пользователь» лезть не должен.

struct public
{
  int u1;
  char u2;
};

struct private
{
   struct public u;
   void *p1;
   int *p2;
}

struct public* create_public()
{
   return malloc(sizeof(private));
}

zaz ★★★★
()
Ответ на: комментарий от zaz

Тогда уж лучше вообще пользователю не давать никуда лезть и предоставлять геттеры-сеттеры для нужных полей, а пользователю возвращать void*. Заодно и другие языки смогут такой код легко использовать.

Legioner ★★★★★
()
18 февраля 2015 г.

Только что создал https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65106, должно быть интересно.

Это рабоает в Clang, но не в GCC:

#include<stdlib.h>

struct A {
  int x;
  const int y;
}

struct A* make() 
{
  struct A *ptr = malloc(sizeof(struct A));
  *ptr = (struct A) {10, 10};
  return ptr;
}

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.