метод abort() реализации


Здесь вы идете:

#define abort(msg) (fprintf(stderr, msg) && *((char*)0))


929
2
задан 2 февраля 2011 в 02:02 Источник Поделиться
Комментарии
2 ответа

Номера-стандартный интерфейс стандартная функция

Очевидная критика этого осуществления заключается в том, что он имеет другой интерфейс, что стандарт C не требует:


§7.20.4.1 функцию прерывания

Синопсис

#include <stdlib.h>
void abort(void);


Описание

В прерывание функции обуславливает анормальный программа расторжения произойти, если сигнал
По сигналу sigabrt - это быть пойманным и обработчик сигнала не возвращается. Открытых потоков
с неписанным буферизованные данные сбрасываются, открытые потоки закрываются, или временные файлы
удален определяется реализацией. Реализация-определено в виде статуса
неудачной прекращения возвращается к хозяину среды с помощью функции
призыв поднять(по сигналу sigabrt).

Возвращает

Функция abort не возвращает управление вызвавшему его коду.

Ненадежная реализация 'аварии'

Существуют системы, как известно, с декабря воск, когда доступ к памяти по адресу 0 не вызывает проблем (пока программ, которые были написаны на VAX были портированы на другие платформы, которые делали аборт).

Разыменование нулевого указателя-это неопределенное поведение - это означает, что может произойти что угодно, в том числе 'нет места'.

Что доставит некоторое неудобство в осуществлении

Если, по какой-то причине, fprintf() возвращает 0, ваша программа не будет прервана. Например:

abort("");

не прервать. Это также опасно, чтобы использовать строку в качестве строки формата; вы должны использовать:

#define abort(msg) (fprintf(stderr, "%s\n", msg) && *((char*)0))

Было бы лучше использовать запятую вместо оператора &&:

#define abort(msg) (fprintf(stderr, "%s\n", msg), raise(SIGABRT))

Поскольку стандартная библиотека может быть определен макрос прервать(), вы должны #фдоон его, прежде чем определять его самостоятельно.

16
ответ дан 2 февраля 2011 в 04:02 Источник Поделиться

Моя критика вы пытаетесь прерывание по аварии:

*((char*)0))

Это вызывает неопределенное поведение. Для этого не обязательно вызывать аварии (или прекращения).

Если вы хотите поднять прервать сигнал не так явно:

raise(SIGABRT)

Также вы повторно defing метод системы с помощью #define (я относительно уверен, что это не допускается и приводит к неопределенному поведению, хотя я не могу процитировать главу и стих).

#define abort(msg) 

Также при этом нужно перерыть все, чтобы найти любое текущее использование прерывания. Как это может конфликтовать с новой использование (или препроцессор быть умным об этом. Тот факт, что я задаю вопрос должен заставить вас волноваться не говоря уже об ответе).

Почему бы не определить собственные функции с немного другим именем (это также позволит вам называть систему прерывания).

#define abortWithMsg(msg) do { fprintf(stderr, msg); abort(); } while (false)

5
ответ дан 2 февраля 2011 в 05:02 Источник Поделиться