Дешифровка (* (пусто (*) ()) 0) ()

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

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

Кто-то может ясно объяснить, что означает это выражение?

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

6
задан NguyenDat 19 April 2010 в 01:41
поделиться

4 ответа

Шаг за шагом:

   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.

18
ответ дан 8 December 2019 в 03:26
поделиться

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

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

typedef void(*my_func)();

, тогда в вашем примере у вас есть приведение:

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

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

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

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

3
ответ дан 8 December 2019 в 03:26
поделиться

Разбейте его на скобки.

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

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

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

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

2
ответ дан 8 December 2019 в 03:26
поделиться

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

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

void test() { }

void(*pfn)() = test;
(*pfn)();
6
ответ дан 8 December 2019 в 03:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: