Порядок оценки параметров функции
В C/C++
, существует ли фиксированный порядок оценки параметра функции? Я имею в виду, что говорят стандарты? Это left-to-right
или right-to-left
?
Я получаю путаную информацию из книг.
Необходимо ли, чтобы function call
был реализован с помощью stack only
. Что говорят об этом стандарты C/C++
?
Ответы
Ответ 1
C и С++ - два совершенно разных языка; не предполагайте, что одни и те же правила всегда применяются к обоим. Однако в случае порядка оценки параметров:
C99:
6.5.2.2 Функциональные вызовы
...
10 Порядок оценки указателя функции, фактических аргументов и подвыражения в действительных аргументах не определены, но есть точка последовательности перед фактическим вызовом.
[Изменить]
C11 (черновик):
6.5.2.2 Функциональные вызовы
...
10 После оценки указателя функции и фактического
аргументов, но до фактического вызова. Каждая оценка в вызывающей функции (включая
другие вызовы функций), которые иначе не секвентируются до или после
выполнение тела вызываемой функции неопределенно упорядочено по отношению к
выполнение вызываемой функции. 94)
...
94) Иными словами, выполнение функций не "чередуется друг с другом".
С++:
5.2.2 Вызов функции
...
8 Порядок оценки аргументов неуточнен. Все побочные эффекты оценок выражения аргументов вступают в силу
перед вводом функции. Порядок оценки постфиксного выражения и списка выражений аргумента неопределенные.
Ни один стандарт не предусматривает использование аппаратного стека для передачи параметров функции; это деталь реализации. Стандарт С++ использует термин "раскручивание стека" для описания вызова деструкторов для автоматически создаваемых объектов на пути от блока try
к выражению throw, но это. Самые популярные архитектуры передают параметры через аппаратный стек, но не универсальны.
[изменить]
Я получаю путаную информацию из книг.
Это ничуть не удивительно, так как легко 90% книг, написанных о C, просто дерьмо.
Хотя языковой стандарт не является отличным ресурсом для изучения C или С++, полезно иметь такие вопросы. Официальный и торговый; Стандартные документы стоят реальных денег, но есть проекты, которые свободно доступны в Интернете, и должны быть достаточно хорошими для большинства целей.
Последний проект C99 (с обновлениями с момента публикации) доступен здесь. Последний предварительный проект C11 (который официально был ратифицирован в прошлом году) доступен здесь. И публично доступный проект языка С++ доступен здесь, хотя в нем есть явное оговорка о том, что некоторая информация является неполной или неправильной.
Ответ 2
Сохранение безопасности: стандарт оставляет его компилятору для определения порядка, в котором оцениваются аргументы. Поэтому вы не должны полагаться на определенный порядок хранения.
Ответ 3
В C/С++ существует фиксированный порядок оценки параметра функции. Я имею в виду, что стандарты говорят, это слева направо или справа налево. Я получаю путаную информацию из книг.
Нет, порядок оценки параметров функции (и двух подвыражений в любом выражении) является неопределенным поведением в C и С++. В простом английском языке это означает, что сначала можно оценить самый левый параметр, или он может быть самым правильным, и вы не можете знать, какой порядок применяется для конкретного компилятора.
Пример:
static int x = 0;
int* func (int val)
{
x = val;
return &x;
}
void print (int val1, int val2)
{
cout << val1 << " " << val2 << endl;
}
print(*func(1), *func(2));
Этот код очень плохой. Он полагается на порядок оценки параметров печати. Он будет печатать либо "1 1" (справа налево), либо "2 2" (слева направо), и мы не можем знать, что. Единственное, что гарантируется стандартом, это то, что оба вызова функции func() завершены до вызова print().
Решение этого - знать, что порядок не указан, и писать программы, которые не зависят от порядка оценки. Например:
int val1 = *func(1);
int val2 = *func(2);
print(val1, val2); // Will always print "1 2" on any compiler.
Необходимо ли, чтобы вызов функции выполнялся только с использованием стека. что говорят об этом стандарты C/С++.
Это называется "конвенция о вызове" и ничего, что стандарт указывает вообще. Как передаются параметры (и возвращаемые значения), полностью зависит от реализации. Они могут передаваться в регистры процессора или в стек или каким-либо другим способом. Вызывающим может быть тот, кто отвечает за нажатие/всплывающие параметры в стеке, или функция может быть ответственна.
Порядок оценки функциональных параметров лишь несколько связан с вызывающим соглашением, так как оценка происходит до вызова функции. Но, с другой стороны, некоторые компиляторы могут выбрать один из самых важных параметров в регистре CPU, а остальные - в стеке.
Ответ 4
Только для языка C, порядок оценки внутри параметров функции зависит от компилятора. от Язык программирования C Брайан Керниган и Деннис Ричи;
Аналогично, порядок, в котором вычисляются аргументы функции, не указано, поэтому утверждение
printf("%d %d\n", ++n, power(2, n)); /*WRONG */
может давать разные результаты с разными компиляторами, в зависимости от того, увеличивается ли значение n до выключения питания. решение, конечно, состоит в том, чтобы написать
++n;
printf("%d %d\n", n, power(2, n));