Выходная оценка C++ заказывает со встроенными вызовами функции

Вы могли бы попробовать delete-indentation, моя любимая команда для присоединения к нескольким строкам в одну строку. В Вашем примере, помещенном курсор на строку со "вторым" и хитом M-^ дважды. Вот документы:

M-^ выполняет команду delete-indentation, которая является интерактивной скомпилированной функцией Lisp в simple.el.

Это связывается с M-^ .

(delete-indentation &optional arg)

Соединение эта строка к предыдущему и ремонтируют пробел в соединении. Если существует префикс заливки, удалите его с начала этой строки. С аргументом соедините эту строку со следующей строкой.

9
задан Eric Lifka 1 October 2009 в 15:53
поделиться

6 ответов

Стандарт C ++ не определяет, в каком порядке оцениваются подвыражения полного выражения, за исключением некоторых операторов, которые вводят порядок (оператор запятой, тернарный оператор, короткие логические операторы), и тот факт, что выражения, которые составляют аргументы / операнды функции / оператора, все оцениваются перед самой функцией / оператором.

GCC не обязан объяснять вам (или мне), почему он хочет упорядочить их как оно делает. Это может быть оптимизация производительности, это может быть потому, что код компилятора получился на несколько строк короче и проще, это может быть потому, что один из кодировщиков mingw лично вас ненавидит и хочет убедиться, что если вы делаете предположения, которые не t гарантировано стандартом, ваш код идет не так. Добро пожаловать в мир открытых стандартов: -)

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

std::cout << pow(x++,3) << endl << pow(x++,3) << endl << pow(x++,3) << endl;

, то это было бы неопределенным поведением. В этом коде компилятор может вычислить все три подвыражения «x ++», затем три вызова pow, а затем начать с различных вызовов operator << . Поскольку этот порядок действителен и не имеет точек последовательности, разделяющих модификацию x, результаты полностью не определены. В фрагменте кода не указан только порядок выполнения.

15
ответ дан 4 December 2019 в 08:01
поделиться

Недавно MySpace выпустила свой фреймворк .NET MapReduce, Qizmt с открытым исходным кодом, так что это также потенциальный соперник в этом пространстве.

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

Неопределенное поведение проявляется, потому что, хотя вызовы операторов должны быть упорядочены, такое требование не предъявляется к их аргументам . Следовательно, результирующий порядок может быть одним из:

f2()
f1()
cout.operator<<(f1())
cout.operator<<(f1()).operator<<(f2());

Или:

f1()
f2()
cout.operator<<(f1())
cout.operator<<(f1()).operator<<(f2());

Или, наконец:

f1()
cout.operator<<(f1())
f2()
cout.operator<<(f1()).operator<<(f2());
10
ответ дан 4 December 2019 в 08:01
поделиться

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

2
ответ дан 4 December 2019 в 08:01
поделиться

Да, порядок оценки функциональных аргументов в соответствии со Стандартами «Не указан».

Следовательно, выходные данные различаются на разных платформах

0
ответ дан 4 December 2019 в 08:01
поделиться

Как уже было сказано, вы забрели в призрачный лес неопределенного поведения. Чтобы каждый раз получать то, что ожидается, вы можете либо удалить побочные эффекты:

int myFunc(int &x) {
   int temp = x * x * x;
   return temp;
}

int main() {
   int x = 2;
   cout << myFunc(x) << endl << myFunc(x+1) << endl << myFunc(x+2) << endl;
   //Note that you can't use the increment operator (++) here.  It has
   //side-effects so it will have the same problem
}

, либо разбить вызовы функций на отдельные операторы:

int myFunc(int &x) {
   int temp = x * x * x;
   x += 1;
   return temp;
}

int main() {
   int x = 2;
   cout << myFunc(x) << endl;
   cout << myFunc(x) << endl;
   cout << myFunc(x) << endl;
}

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

0
ответ дан 4 December 2019 в 08:01
поделиться

Предположительно вы используете printf для вывода столбцов в первую очередь. Вы можете использовать дополнительные модификаторы в строке формата, чтобы убедиться, что все выровнено.

  • Чтобы напечатать столбец определенной ширины (с выравниванием по правому краю), добавьте ширину перед флагом форматирования, например, "% 10s" напечатает столбец шириной 10. Если ваша строка длиннее 10 символов, столбец будет длиннее, чем вы хотите, поэтому выберите максимальное значение. Если строка короче, она будет дополнена пробелами.
  • Чтобы выровнять столбец по левому краю, поставьте перед ним знак -, например, «% -10s». Лично мне нравится выравнивать строки по левому краю и выравнивать числа по правому краю.
0
ответ дан 4 December 2019 в 08:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: