Сначала: если мы видим что-то, квалифицированное как const
, мы должны относиться к этому серьезно и избегать выбрасывать постоянство. Если вы отбрасываете константный квалификатор глобальных или статических данных, то вы получаете неопределенное поведение, и в Linux вы получите ошибку сегментации.
В общем, правильный путь - тот, который указал Сувен Пандей в другом ответе.
Тем не менее, есть действительные случаи, чтобы отбросить const. Ваш случай может квалифицироваться как одно из исключений в https://wiki.sei.cmu.edu/confluence/display/c/EXP05-C.+Do+not+cast+away+a+const+qualification
EXP05-C-EX3: поскольку const означает «только для чтения», а не «константа», иногда полезно объявить членов структуры как (указатель на) объекты const для получения диагностики, когда пользователь пытается изменить их в каким-то иным способом, кроме как через функции, специально разработанные для поддержки этого типа данных. Однако в рамках этих функций может потребоваться снять квалификацию const для обновления этих членов.
Мы можем отказаться от const, когда ваши данные находятся в изменяемой области памяти, такой как стек или куча. В любом случае, мы должны быть осторожны, так как это может привести к непредвиденному поведению, если код использует эти данные как неизменяемые, и мы изменяем их.
Итак, это то, что вы просили:
typedef enum {A1, A2} enum_A;
typedef struct { const enum_A G; } struct_B;
typedef struct { const struct_B * F; } struct_C;
typedef struct { const struct_C *E; } struct_D;
int main() {
const struct_B b = {A1};
const struct_C c = {&b};
const struct_D temp = {&c};
enum_A *pointer_to_non_const_A = &temp.E[0].F[0].G;
*pointer_to_non_const_A = A2;
}
Но это зависит от того, где temp
определен и будет вызывать предупреждение компиляции. Если temp
- глобал, который может потерпеть крах. Вот случаи, когда он работает, но не должен использоваться, и когда он падает:
#include <stdlib.h>
const int global_in_data_segment = 0;
int main() {
const int in_stack = 0;
static const int static_in_data_segment = 0;
const int *in_heap = malloc(sizeof(int));
int *works;
works = &in_stack; *works = 1;
works = in_heap; *works = 2;
int *crashes;
crashes = &global_in_data_segment; *crashes = 3;
crashes = &static_in_data_segment; *crashes = 4;
}
Для полноты, c ++ имеет const_cast: https://en.cppreference.com/w/cpp/language/const_cast