Здравствуйте, tonykent, Вы писали:
J>>Наверное, человек не знает о существовании функции abort()... T>Сам видел подобные примеры у Саттера (помоему). Чтобы не париться и кинуть Exception
какой еще Exception?
Это неопределенное поведение.
Для кидания Exception есть конструкция throw, гораздо более прямолинейная.
Здравствуйте, alzt, Вы писали:
A>Добрый день.
A>Какой может быть смысл в намеренном разименовании указателя:
A>
A>*(int *) 0 = 1; //здесь
A>*(volatile int *) 0 = 2; //и здесь
A>
A>?
В некоторых маргинальных С-like библиотеках типа используется в качестве попытки бросить исключение. Под Win им это даже может удастся.
Вроде в первой OpenCV иммено такой механизм был (а может и есть).
Здравствуйте, ononim, Вы писали:
O>в винде обращение к виртуальным адресам 0..0xffff вызывает гарантированное SEH/AV
А в досе — вызывает перезапись таблицы прерываний. И откладывание феерверка до момента прерывания...
Говорите, дос — старьё? Возьмите любую другую ОС без защиты памяти — ту же VxWorks, например.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, ononim, Вы писали:
O>>в винде обращение к виртуальным адресам 0..0xffff вызывает гарантированное SEH/AV
К>А в досе — вызывает перезапись таблицы прерываний. И откладывание феерверка до момента прерывания... К>Говорите, дос — старьё? Возьмите любую другую ОС без защиты памяти — ту же VxWorks, например.
Перед (а если быть совсем честным вместо) перезаписью, она вызовет GP, по крайней мере в защищенном режиме.
Здравствуйте, jazzer, Вы писали:
J>Наверное, человек не знает о существовании функции abort()...
J>Это сферический код в вакууме или все-таки есть какой-то контекст?
Это я нашёл в проекте gawk, файл stackoverflow2.c (насколько я понял это тест):
/* Provoke two stack overflows in a row. */switch (setjmp (mainloop))
{
case -1:
printf ("emergency exit\n"); exit (1);
case 0: case 1:
printf ("Starting recursion pass %d.\n", pass + 1);
recurse (0);
printf ("no endless recursion?!\n"); exit (1);
case 2:
*(volatile int *) (page + 0x678) = 42;
break;
case 3:
*(volatile int *) 0 = 42;
break;
case 4:
break;
default:
abort ();
}
Здравствуйте, alzt, Вы писали:
A>Здравствуйте, jazzer, Вы писали:
J>>Наверное, человек не знает о существовании функции abort()...
J>>Это сферический код в вакууме или все-таки есть какой-то контекст?
A>Это я нашёл в проекте gawk, файл stackoverflow2.c (насколько я понял это тест): A>
A>/* Provoke two stack overflows in a row. */
A> switch (setjmp (mainloop))
A> {
A> case -1:
A> printf ("emergency exit\n"); exit (1);
A> case 0: case 1:
A> printf ("Starting recursion pass %d.\n", pass + 1);
A> recurse (0);
A> printf ("no endless recursion?!\n"); exit (1);
A> case 2:
A> *(volatile int *) (page + 0x678) = 42;
A> break;
A> case 3:
A> *(volatile int *) 0 = 42;
A> break;
A> case 4:
A> break;
A> default:
A> abort ();
A> }
A>
конкретно здесь разыменовывание нулевого указателя нужно для генерации SIGSEGV.
в обработчике, видимо, вызывается longjmp на выход 4, и получается корректный выход
из программы, а не abort().
alzt wrote:
> Какой может быть смысл в намеренном разименовании указателя: > > *(int *) 0 = 1; //здесь > *(volatile int *) 0 = 2; //и здесь
Грохнуться в корку. Т.е. вызвать ошибку приложения,
гарантированно приводящую к снятию приложения с выполнения
на данной платформе (потому как это непереносимо).
tonykent wrote:
> J>Наверное, человек не знает о существовании функции abort()... > Сам видел подобные примеры у Саттера (помоему). Чтобы не париться и > кинуть Exception
Некоторые на С пишут. А вот abort не знаю, чем им не понравился.
Ну, кто его знает, возможно на каких=то платформах он как-то не
так себя ведёт и не нравится.