Расшифровка (* (void (*) ()) 0) () - PullRequest
6 голосов
/ 09 апреля 2010

Они сказали, что это выражение допустимо в C, и что это означает вызов функции:

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

Может кто-нибудь ясно объяснить, что означает это выражение?

Я попытался скомпилировать это и был удивлен, что это не привело к ошибке.

Ответы [ 5 ]

18 голосов
/ 09 апреля 2010

Шаг за шагом:

   void(*)()        // a pointer-to-function type, taking unspecified parameters
                    // and returning nothing.
  (void(*)())0      // a null pointer of that pointer-to-function type
(*(void(*)())0)     // dereference that pointer
(*(void(*)())0)();  // and call it with no parameters

Код имеет неопределенное поведение, он, вероятно, завершится с каким-то недопустимым доступом / segfault.

6 голосов
/ 09 апреля 2010

Вы создаете указатель на функцию и затем вызываете ее. Я бы не назвал это скрытой функцией, но неопределенным поведением.

Обычно вы делаете это, но вместо этого с адресом 0:

void test() { }

void(*pfn)() = test;
(*pfn)();
3 голосов
/ 09 апреля 2010

Это указатель на функцию в NULL.

void(*)() - это определение указателя на функцию без аргументов, которая ничего не возвращает; Вы можете назвать это:

typedef void(*my_func)();

, тогда в вашем примере вы получили приведение:

(my_func)0 возвращает указатель на функцию my_func, то есть функцию, которая ничего не берет и ничего не возвращает.

Затем вы разыменовываете его с помощью ведущей звездочки (что ненужно, афаик), а затем вызываете его.

Таким образом, вы вызываете функцию, не принимающую аргументов и не возвращающую ничего, что происходит с нулевым адресом.

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

2 голосов
/ 09 апреля 2010

Разбить на скобки.

Последний () обозначает функцию без параметров.

Строка (void(*)()) означает функцию, которая возвращает void.

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

Так что, по сути, вы вызываете все, что, черт возьми, лежит по адресу 0 без параметров. Обычно не очень безопасно. :)

0 голосов
/ 09 сентября 2011

во встроенной среде может быть способом вызова процедуры сброса системы.

...