2013-12-24 9 views
3

Есть ли определенный порядок, в котором функции вызывается в приведенном ниже выражении или отличается от компилятора от компилятора?Какие функции заказа будут называться

Применяется ли следующее правило: В C порядок, в котором аргументы функций и операндов для большинства операторов оцениваются, не указан. Найдено вышеуказанное правило в этом wiki page

a = (f1(10, 20) * f2(30, 40)) + f3() 
+0

@Mat - Спасибо, что указали это. Да, это действительно повторяющийся вопрос – rgk

ответ

8

правило не распространяется. f1, f2 и f3 могут быть оценены в любом порядке.

Чтобы расширить немного на некоторых из путаницы (потому что люди продолжают размещение неправильных ответов), оператор старшинство делает не влияет на порядок, в котором находятся оценивали. Возьмем такой пример:

f1() * f2() + f3() 

Теперь мы знаем, что да, результаты f1() и f2() умножаются, а затем добавляют к результату f3(), но мы не знаем порядок оценки. Дерево синтаксического анализа выглядит следующим образом:

 + 
    / \ 
    * f3() 
/ \ 
f1() f2() 

Но мы не знаем, если левая сторона или правая сторона + будет оцениваться в первую очередь. Это может быть так или иначе. То же самое с *: мы не знаем, будет ли сначала оценена его левая или правая сторона.

компилятор можно назвать f3(), а затем сохранить результат, а затем вызвать f2(), магазин, результат, а затем вызвать f1(), а затем использовать сохраненные результаты для выполнения фактического расчета.

Или, наоборот, он может позвонить f1(), сохранить результат, а затем вызвать f2(), а затем использовать эти два значения для умножения (а затем сохранить этот результат), а затем вызвать f3() и закончить вычисление.

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

В заключение: приоритет операторов определяет дерево разбора, не порядок оценки. Порядок, в котором оценивается дерево разбора, не определен.

+0

'приоритет оператора определяет дерево разбора, а не порядок оценки' Неважно, как формируется дерево разбора, компилятор все еще может оценивать функции f1(), f2() и f3() в Любой заказ. Unspecified означает * unspecified *. Дерево разбора не доказывает и не опровергает ничего. –

+0

@BlueMoon: А? Вот что я говорил. «Порядок, в котором оценивается дерево разбора, не указывается». Вся причина, по которой я пошла на «приоритет оператора, определяет дерево разбора», заключается в том, что люди продолжали публиковать неправильные ответы, предполагая, что приоритет оператора определяет порядок оценки. Я сообщал людям, что это неверно, приоритет оператора имеет другую причину существующего (определение дерева разбора), а не порядок оценки. – Cornstalks

+0

Вы говорите это. Но вы также говорите что-то о дереве разбора, которое не имеет отношения к вопросу. –

4

Компилятор может вызывать эти функции в любом порядке (то есть, единственная гарантия заключается в том, что перед умножением вызывается f1 и f2, а все три вызываются перед добавлением и что все три будут вызваны только после значение их аргументов известно).

С такими буквальными аргументами компилятор может называть их как можно раньше (например, строки и строки выше) или даже сделать их встроенными.

Самое главное, не путайте приоритет оператора с порядком оценки функции.

Все, что вы знаете, это то, что функция будет вызываться после того, как значение ее аргументов будет известно, но до того, как будет использовано его возвращаемое значение.

2

Эти функции могут быть оценены в любом порядке. Нет определенного правила. Либо f1 сначала вычисляется затем f2, а затем f3 или f3 сначала вычисляется затем f2, а затем f1 или f2 сначала вычисляется затем f1, а затем f3 или даже f1 сначала вычисляется затем f3, а затем f2 (всего шесть комбинаций здесь!).

Замечание: Приоритет оператора не имеет никакого отношения к порядку оценки.

Но имейте в виду, что когда-нибудь порядок вычисления этих функций арифметическая операция по выражению

a = (f1(10, 20) * f2(30, 40)) + f3() 

будет принимать дворец в соответствии с правилом приоритета оператора, т.е. f1*f2 происходит первый (в необходимо оценить время f1 и f2), а затем результат будет добавлен в f3 (все оценки f1, f2 и f2 должны быть оценены).

+0

См. Нижнюю часть ответа. –

+0

Теоретически «f3' может быть даже посередине, но я не вижу никакой полезной причины для этого. (Хорошо, в зависимости от использования платформы и регистра и других обстоятельств, даже это может быть актуально ...) – glglgl

+0

@FiddlingBits; Я не ответил на ваш ответ, но первая строка вашего ответа была неправильной, и я предположил, что соблазнил пользователей на понижение. – haccks