2012-03-22 4 views
4

Исход следующего макроса ясно:Что означает макрос ((void (*)()) 0)()?

#define CRASH() do {\ 
    *(int *)(uintptr_t)0xbbadbeef = 0;\ 
    ((void(*)())0)();\ 
} while (false) 

Мой вопрос, что делает линию

((void(*)())0)(); 

перерыв до, на английском языке? Например, «это функция, которая возвращает указатель на a».

+6

Eeeeewwwwwwwwww –

+0

привести к аварии. что еще? –

+0

Примечание: на третьей строке отсутствует обратная косая черта. – wildplasser

ответ

14

Похоже, что он отличает 0 как указатель на функцию (с сигнатурой, которая не принимает параметры и имеет тип возвращаемого типа), а затем вызывает его.

( (   void(*)()     ) 0  )  (); 
    /* cast..*/ /* fn pointer signature */ /*..cast 0 */ /* invocation */ 

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

3
  • В ролях 0 указателя на void функции, которая принимает может быть вызван без параметров ((void(*)())0 части выражения)
  • вызова этой функции через указатель с пустым списком параметра (() часть после этого).

EDIT 1: Отредактировано в ответ на комментарий Кристофа.

+2

C vs C + + удары снова: на C++ пустой список параметров означает, что функция не принимает аргументов; в C, это только случай для определений - в общем, пустой список параметров означает, что функция принимает неопределенное количество невариантных аргументов, подверженных раскрутке аргументов по умолчанию – Christoph

+0

@ Christoph Darn it! Ну, по крайней мере, в этом случае для фиксации ответа требуется значительно меньше усилий. – dasblinkenlight

2

Он отличает 0 от указателя функции, где функция не принимает аргумент и возвращает void, а затем пытается вызвать эту функцию. Это в основном разыгрывает нулевой указатель.

0

Приводит 0 к указателю на функцию, затем пытается вызвать эту функцию. Это вызовет segfault и crash.

Редактировать: слишком много соревнований по этим вопросам. Наклонения со всех сторон, и я ложась спать :)

0

Это означает «обработка указателя NULL в качестве указателя на void function(), вызов function()».

2

Указывает NULL указатель на метод, не содержащий параметров и возвращающий void, и пытается вызвать этот метод.

Излишне говорить, что он падает, поэтому имя CRASH подходит для него очень хорошо.

0

Он принимает значение 0 и передает его указателю на функцию, который ничего не возвращает (void).

Предположительно, целью является то, что когда вы вызываете эту «функцию», она вызывает нулевой адрес, что действительно должно привести к сбою приложения.

0

Для меня это проще перевести на другой C++, а не непосредственно на английский:

typedef void (void_func_t)();  // type of a function taking no arguments 
            // and returning void 
typedef void_fnct_t* void_func_ptr; // pointer to such a function 
static_cast<void_func_ptr>(0)(); // call that function 
// ((void_func_ptr)0)();   // pure C equivalent cast 
+0

Не будет ли статический бросок исключать и предотвратит сбой программы? – Lundin

+0

@ Lundin: 'static_cast' ** никогда ** исключает исключения. ** dynamic_cast ** может генерировать исключения, но не может использоваться с указателями функций, и он будет * * * бросать только при цитировании ссылок. –

0

если FP является указателем на функцию, * FP является сама функция, так (FP)() - способ вызвать его. ANSI C разрешает это сокращать как fp(), bu имейте в виду, что это только аббревиатура. ------- C ловушки ловушки. ((недействительное ()()) 0)() является avvreviation из ((пустот ()()) 0)()

Смежные вопросы