Подтвердить что ты не робот

Порядок оценки параметров функции

В C/C++, существует ли фиксированный порядок оценки параметра функции? Я имею в виду, что говорят стандарты? Это left-to-right или right-to-left? Я получаю путаную информацию из книг.

Необходимо ли, чтобы function call был реализован с помощью stack only. Что говорят об этом стандарты C/C++?

4b9b3361

Ответ 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));