Сложное объяснение приведения C
Вопрос
Я пытаюсь выяснить, что делает следующий код на C?
((void(*)())buf)();
где "buf" - это char
массив.
Решение
Давайте делать это шаг за шагом.
void(*)()
Это указатель на функцию, которая принимает неопределенные аргументы и не имеет возвращаемого значения.
(void(*)())buf
просто приводит buf к этому типу указателя функции.Наконец - то,
((void(*)())buf)();
вызывает эту функцию.
Таким образом, все утверждение звучит так: "интерпретировать buf
в качестве указателя на void
выполняйте функцию без аргументов и вызывайте эту функцию ".
Другие советы
Это отбрасывает buf
к указателю на функцию типа void(*)()
(Функция, возвращающая nothing / void и принимающая неопределенные аргументы) и вызывает ее.
Стандарт ANSI на самом деле не разрешает преобразование обычных указателей данных в указатели функций, но ваша платформа может это разрешить.
Я обычно использую команду "cdecl", когда сталкиваюсь с ошеломляющим объявлением.Пример:
[me@machine]$ cdecl
Type `help' or `?' for help
cdecl> explain (void(*)())buf
cast buf into pointer to function returning void
Хотя есть случаи, когда я действительно хотел бы, чтобы существовал инструмент, объясняющий вывод "cdecl". :/
Это отбрасывает buf
к типу void (*)()
, указатель на функцию, которая принимает неопределенные параметры и ничего не возвращает.Затем он вызывает функцию по этому адресу (две крайние правые круглые скобки).
((void(*)())buf)(); \------------/ cast `buf` to \---------/ type: pointer to function accepting a fixed but unspecified number of arguments and returning void \----------------/ and call that "function"
Это отбрасывает buf
в указатель на функцию, которая принимает неопределенные аргументы, и вызывает ее.
Я бы предположил, что во многих обстоятельствах это приводит к сбою работы машины.В противном случае он обрабатывает массив как указатель на функцию, которая возвращает void, и вызывает ее.
Возможно, вы сочтете "экспертное программирование на c" хорошим чтением - распаковка такого рода вещей находится в одной из глав, если я правильно помню.Прошло много времени с тех пор, как я ее читал, но, помню, в то время я думал, что это стоило затраченных усилий.http://www.amazon.com/Expert-Programming-Peter-van-Linden/dp/0131774298
Существует онлайн-версия инструмента 'cdecl', о котором упоминал lsc и который может оказаться вам полезным : http://www.cdecl.org/
вызывает указатель на функцию.функция не имеет аргументов.