И Java, и C #, и, возможно, многие другие языки также имеют предопределенный класс исключений, который выдается, когда нулевой параметр используется там, где он не должен. Есть ли что-нибудь подобное в C ++? Если нет, есть ли другое предопределенное исключение, которое я могу использовать, или я должен определить свое собственное?
Разыменование NULL-указателя — неопределенное поведение в C ++ — это означает, что код может работать. Исключение не гарантируется. Вы можете использовать
исключение (предоставить значимое значение для него — "p is NULL"
), но вы должны будете сделать проверку самостоятельно.
Обычно в C ++ (или C в этом отношении) вы никогда разыменовывать нулевой указатель. Делать это имеет неопределенное поведение (вероятно, это ошибка в любой реализации, о которой я знаю, но все может произойти в соответствии со стандартом). Наверное, это плохо на других языках, но я не знаю, достаточно ли этого, чтобы утверждать это.
Лучше предотвратить ситуацию, чем пытаться восстановиться после нее (что в любом случае невозможно сделать на C или C ++).
Обычная схема предотвращения некоторых связанных ошибок программиста заключается в использовании assert()
внутри функциональных органов, таких как:
int foo(int* myint)
{
// Ensure myint is not NULL
assert(myint);
// Do something with myint
(*myint)++;
return *myint;
}
такие assert()
вызовы полностью игнорируются при сборке релизов и, следовательно, не требуют затрат при производстве. Они просто помогают развитию. При отладочных сборках, и если условие не выполняется, программа немедленно прерывается с очень явным сообщением об ошибке. Запустив его через отладчик, вы можете легко проверить стек вызовов, чтобы выяснить точную причину.
В C ++ нет стандартного исключения для разыменования пустого указателя.
Если вы хотите, вы можете реализовать это самостоятельно. В UNIX установите обработчик сигнала SIGSEGV и сгенерируйте исключение из обработчика. В Windows используйте API _set_se_translator () для установки обработчика «Структурное исключение».
FTR, в C # вы не используете NullReferenceException
за что угодно, если только вы не хотите получить удар от своих товарищей по команде. Eсть ArgumentNullException
вместо того, чтобы отклонить нулевые аргументы. NRE предназначены для запуска во время выполнения, а не для вас.
Но обратите внимание, что на самом деле это не преимущество перед утверждением, потому что вы не должны ловить одно из них: если они выброшены, они указывают на ошибку. Это то, что Эрик Липперт называет исключения с глупыми головами и они — твоя собственная ошибка, и твой код ничего не должен делать конкретно с ними.
В C ++ разыменование нулевого указателя приведет к неопределенному поведению, что в основном завершает приложение ошибкой сегментации. В Visual Studio вы можете использовать такие расширения, как Структурная обработка исключений (SEH), которые позволяют перехватывать нулевой указатель.
Почти во всех случаях, когда неправильно используется нулевой указатель (особенно разыменование), стандарт C ++ просто оставляет поведение неопределенным. Для конкретного типа исключения не предусмотрено (и исключение не будет выдано).
Однако на ум приходит одно возможное исключение из этого правила. std::function
, который является шаблоном стандартной библиотеки C ++ 11, который может использоваться для переноса функций, может быть назначен нулевой указатель:
std::function<void(int)> func = nullptr;
И если вы затем попытаетесь вызвать обернутую ею функцию, выполнив func(arg);
для некоторого аргумента arg
Кидает std::bad_function_call
исключение.
Это, конечно, не полностью эквивалентно исключениям нулевого указателя в других языках, потому что оно гораздо менее применимо.