Приведение указателя функции к типу, который принимает больше аргументов - PullRequest
3 голосов
/ 07 июня 2011

Насколько я знаю, приведение между несовместимыми указателями функций, например:

void aUnaryFunction(int a1)
{
    /* .... */
}

void doSomethingWithFn()
{
    typedef void(*BinaryFn)(int, const char*);
    BinaryFn aBinaryFunction = (BinaryFn) &aUnaryFunction;
    aBinaryFunction (3, "!!!");
}

, никогда не должно выполняться, как и "неопределенное поведение" в соответствии со стандартом C.

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

Если предположить, что обработка первого аргумента int последовательна, все, что произойдет, это то, что const char * будет помещен в регистр, когда doSomethingWithFn() вызывает aBinaryFunction, aUnaryFunction будет работать как положено, и const char * может быть перезаписан во время aUnaryFunction, но это нормально, потому что ничто другое не будет его использовать в любом случае.

Я что-то здесь упустил, или этона самом деле безопасно?(Или что-то среднее между двумя или оба?)

Ответы [ 3 ]

6 голосов
/ 07 июня 2011

Проблема в том, что в C не существует единственного "способа, которым вызовы функций работают" - есть только способ, которым вызовы функций работают в конкретной реализации C.

КакВ конкретном примере соглашения о вызове «очистки вызываемого абонента» (например, x86 stdcall) требуют, чтобы вызываемый объект знал, сколько параметров было помещено в стек для выполнения правильной очистки, что в вашем примере будет подорвано.

5 голосов
/ 07 июня 2011

Это сводится к соглашениям о вызовах. Что, если аргументы «отправлены» в обратном порядке, например? Или, если есть стандартная процедура, которая должна быть выполнена после вызова функции, которая основана на правильном количестве аргументов?

То, что вы предлагаете, может сработать, но вы не должны полагаться на это, и Стандарт приписывает это как неопределенное поведение по причине.

0 голосов
/ 07 июня 2011

Кстати, «неопределенное поведение» - это секретный код для «не делай этого, это НЕ безопасно!».

Это означает, что он не будет работать на разных машинах или даже в разных версияходин и тот же компилятор на той же машине.

...