Я пытаюсь выяснить, что делает следующий код в C?Сложный C-литье объяснение
((void(*)())buf)();
где 'ЬиЙ' является char
массивом.
Я пытаюсь выяснить, что делает следующий код в C?Сложный C-литье объяснение
((void(*)())buf)();
где 'ЬиЙ' является char
массивом.
Давайте это один шаг за один раз.
void(*)()
Это указатель на функцию, которая принимает неопределенные аргументы и не имеет возвращаемого значения.
(void(*)())buf
просто бросает buf в эту функцию указателя функции. Наконец,
((void(*)())buf)();
вызывает эту функцию.
Таким образом, весь оператор «интерпретирует buf
как указатель на функцию void
без аргументов и вызывает эту функцию».
Кастинг символьного буфера в функцию и вызов его злом. Это либо попытка самомодифицирующего кода, либо злонамеренное намерение сделать какой-то эксплойт. В любом случае, избегайте его любой ценой. –
Исправить меня, если я ошибаюсь, но разве это не значение указателя (адрес массива), которое рассматривается как функция, а не содержимое массива? «интерпретировать * значение * в buf» звучит немного похоже на то, что вы говорите, что содержимое интерпретируется как указатель на функцию. –
-1 (не совсем): принимает неопределенные аргументы в C – pmg
Он отличает buf
к указателю функции типа void(*)()
(функция, возвращающая ничего/пустое и принимающая неуказанные аргументы) и вызывает его.
Стандарт ANSI на самом деле не позволяет отличать нормальные указатели данных к указателям функций, но ваша платформа может это позволить.
Почему вы можете использовать массив для указателя функции? Есть ли статья, которая объясняет это? –
Указатель - это всего лишь набор байтов, как и любое другое значение (которое может быть представлено на C как массив символов). Вероятно, вы обнаружите, что в другом месте программы обратное это было сделано: 'char * buf = (char *) function;' или что-то подобное. – Wernsey
Вы можете сделать это, потому что это C - вы можете делать все, что хотите. Это ужасная идея, но вы можете это сделать. – Clyde
Я бы предположил, что во многих случаях он сбой машины. В противном случае он рассматривает массив как указатель на функцию, которая возвращает void и вызывает ее.
Вставляет buf
в указатель функции, который принимает неопределенные аргументы и вызывает его.
-1 (не совсем): принимает неуказанные аргументы в C – pmg
@pmg, спасибо. Я отредактировал ответ. –
Приводит buf
к типу void (*)()
, указателю на функцию, которая принимает неопределенные параметры и ничего не возвращает. Затем он вызывает функцию по этому адресу (две самые правые скобки).
-1 (не совсем): принимает неуказанные аргументы в C – pmg
@pmg, хорошая точка. –
вызывает указатель на функцию. функция не имеет аргументов.
((void(*)())buf)(); \------------/ cast `buf` to \---------/ type: pointer to function accepting a fixed but unspecified number of arguments and returning void \----------------/ and call that "function"
+1 Вы правы относительно неопределенного количества параметров. Если бы вы разъяснили пример, вы, вероятно, получили бы больше признательности за свое понимание :) – Andomar
Возможно, вы найдете «экспертное программирование», хорошее чтение - распаковка такого рода в одной из глав, если я правильно помню. Прошло много времени с тех пор, как я прочитал его, но я помню, что в то время это стоило усилий. http://www.amazon.com/Expert-Programming-Peter-van-Linden/dp/0131774298
Как правило, я использую команду «cdecl», когда я сталкиваюсь с объявлением ума. Пример:
[[email protected]]$ cdecl
Type `help' or `?' for help
cdecl> explain (void(*)())buf
cast buf into pointer to function returning void
Хотя есть случаи, когда я желаю, что есть инструмент там, что объясняет выход «Cdecl»:/
Существует интернет версия «Cdecl» инструмент, который LSC что вы можете найти полезным: http://www.cdecl.org/
Ищите программу под названием «cdecl». Загрузить. Вставьте в него объявление. Будьте просветлены. –
@Paul: Я попробую это и надеюсь, что он не убьет мою машину! –
Этот код может обоснованно отображаться в JIT или в ОС в динамическом компоновщике/загрузчике. Как говорили другие, это страшно, но только если вы столкнулись с ним в типичном приложении. На своем месте, это не страшно, просто сложный материал. –