Что означает макрос ((void (*) ()) 0) ()? - PullRequest
4 голосов
/ 22 марта 2012

Результат следующего макроса ясен:

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

Мой вопрос: на что ломается строка

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

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

Ответы [ 9 ]

14 голосов
/ 22 марта 2012

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

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

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

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

РЕДАКТ. 1 : отредактировано в ответ на комментарий Кристофа.

2 голосов
/ 22 марта 2012

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

Нет необходимости говорить, что он вылетает, поэтому имя CRASH ему подходиточень хорошо.

2 голосов
/ 22 марта 2012

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

0 голосов
/ 22 марта 2012

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

0 голосов
/ 22 марта 2012

Для меня проще перевести на другой 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 голосов
/ 22 марта 2012

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

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

0 голосов
/ 22 марта 2012

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

0 голосов
/ 22 марта 2012

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

Изменить: слишком много конкуренции для этих вопросов. Проголосую повсюду, и я иду спать :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...