Изменение const
, согласно спецификации, является «неопределенным поведением», поэтому компилятор может делать все что угодно.На практике многие реализации иногда генерируют ошибки времени выполнения для такого кода, но многие этого не делают.Это часто зависит от характера программы.Вот иллюстрация:
#include <stdio.h>
#include <string.h>
typedef int (*fn)(const char *);
extern const fn global_fn_ptr;
extern const char global_string[];
const fn global_fn_ptr = puts;
const char global_string[] = "hello";
int main(int argc, char *argv[])
{
puts("Setting global_fn_ptr to NULL");
*(fn *)&global_fn_ptr = NULL;
puts("Setting string to \"bye\"");
strcpy((char *)global_string, "bye");
return 0;
}
В моей системе я получаю SIGBUS от изменения строки, но изменение функции работает нормально.Это связано со специфической природой указателей на функции, значение которых не всегда определяется во время выполнения, поэтому значение должно храниться в доступной для записи памяти.
Обычно небезопасно перехватывать SIGBUS или SIGSEGV в C ++ и поворачиватьэто в исключение.Также очень трудно правильно longjmp
из обработчика сигнала - половина кода, который использует этот шаблон в C, вероятно, неверна.Самый безопасный вариант - позволить программе немедленно завершиться, или, если вам действительно нужна такая помощь из среды выполнения, работать очень осторожно с кодом C, чтобы вы могли освободить соответствующие ресурсы при нелокальном выходе - C ++ не будет делать, потому что longjmp
не будет вызывать деструкторы.
Или вы можете просто перейти на C # или Java, обе из которых имеют среды выполнения, которые делают это для вас, и сборщики мусора, которые впоследствии очищаются.