Порядок вычисления аргументов
От: Воронков Василий Россия  
Дата: 11.10.10 08:33
Оценка:
Предположим, что в энергичном языке при вызове foo(x, y, z) аргументы вычисляются не слева направо, а наоборот, т.е. сначала вычисляется z, потом y, потом x. При остальных вычислениях порядок стандартный.

Вопросы:
— Чем это может быть плохо/чревато, кроме того, что в случаях "невычисляемости" списка аргументов вылет будет происходить не "в том месте".
— Есть ли какие-нибудь языки с подобными извращениями? Как по реализации, так и — что интересней — по стандарту. Может, это типичный прикол?
Re: >Я там был
От: Qbit86 Кипр
Дата: 11.10.10 08:38
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>



А теперь где?
Глаза у меня добрые, но рубашка — смирительная!
Re[2]: >Я там был
От: Воронков Василий Россия  
Дата: 11.10.10 08:41
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>А теперь где?


Здесь
Re: Порядок вычисления аргументов
От: Socrat Россия  
Дата: 11.10.10 08:51
Оценка: 6 (1) -1
Здравствуйте, Воронков Василий, Вы писали:

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


ВВ>Вопросы:

ВВ>- Чем это может быть плохо/чревато, кроме того, что в случаях "невычисляемости" списка аргументов вылет будет происходить не "в том месте".
ВВ>- Есть ли какие-нибудь языки с подобными извращениями? Как по реализации, так и — что интересней — по стандарту. Может, это типичный прикол?

В сях аргументы заталкиваются в стек, начиная с последнего. Вычисляются они тоже чаще всего соответственно.
Re[2]: Порядок вычисления аргументов
От: Воронков Василий Россия  
Дата: 11.10.10 08:53
Оценка:
Здравствуйте, Socrat, Вы писали:

S>В сях аргументы заталкиваются в стек, начиная с последнего. Вычисляются они тоже чаще всего соответственно.


Интересно, а это особенность реализации или стандарт? Студии у меня под рукой нет, я так понимаю, что — положим, в VC — вызов функции вида foo(x, y), где оба аргумента являются невычисляемыми (приводят к ошибке), вылетит на вычислении именно у?
Re[3]: Порядок вычисления аргументов
От: Socrat Россия  
Дата: 11.10.10 09:01
Оценка: 6 (1)
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Интересно, а это особенность реализации или стандарт?


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

ВВ>Студии у меня под рукой нет, я так понимаю, что — положим, в VC — вызов функции вида foo(x, y), где оба аргумента являются невычисляемыми (приводят к ошибке), вылетит на вычислении именно у?


Не знаю, вполне возможно, что порядок вычисления параметров может меняться. Особенно, если используется быстрый вызов функций, когда параметры кладутся в регистры.
Re: Порядок вычисления аргументов
От: samius Япония http://sams-tricks.blogspot.com
Дата: 11.10.10 09:09
Оценка: 12 (1)
Здравствуйте, Воронков Василий, Вы писали:

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


ВВ>Вопросы:

ВВ>- Чем это может быть плохо/чревато, кроме того, что в случаях "невычисляемости" списка аргументов вылет будет происходить не "в том месте".
может быть чревато разным поведением побочных эффектов.

ВВ>- Есть ли какие-нибудь языки с подобными извращениями? Как по реализации, так и — что интересней — по стандарту. Может, это типичный прикол?

http://msdn.microsoft.com/en-us/library/984x0h58%28VS.80%29.aspx
Re[3]: Порядок вычисления аргументов
От: 0x7be СССР  
Дата: 11.10.10 09:33
Оценка: 6 (1) +3
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Здравствуйте, Socrat, Вы писали:


ВВ>Интересно, а это особенность реализации или стандарт?

Стандарт явно указывает, что порядок вычисления параметров может быть любым.
Re: Порядок вычисления аргументов
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 11.10.10 10:57
Оценка: 6 (1)
вызов функций справа налево нарушает укоренившуюся привычку программиста писать код слева направо.

допустим есть функции:
bool print(string text) // которая выводит текст, и возвращает ошибку через результат: true - ok, false - error
bool and(params bool[] vals) //обычный and от нескольких параметров


тогда естественно будет написать:
if (and(print("Hello"), print(" "), print("World"), print("!")))
{
  //ok
}
else
{
  //error
}

что при обратном вызове функций приведет к странному результату.
Re[3]: Порядок вычисления аргументов
От: MasterZiv СССР  
Дата: 11.10.10 11:33
Оценка:
On 11.10.2010 12:53, Воронков Василий wrote:

> Интересно, а это особенность реализации или стандарт? Студии у меня под рукой


Особенности реализации. Стандарт порядок вычисления аргументов не определяет.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Порядок вычисления аргументов
От: Воронков Василий Россия  
Дата: 11.10.10 11:36
Оценка:
Здравствуйте, DarkGray, Вы писали:

Это интересная проблема, побочные эффекты я, конечно, вообще упустил из вида
С другой стороны даже если __stdcall вычисляет параметры справа налево, то, видимо, указанное поведение не будет таким уж непривычным для программиста?
Re[3]: Порядок вычисления аргументов
От: Юрий Жмеренецкий ICQ 380412032
Дата: 11.10.10 12:48
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Здравствуйте, DarkGray, Вы писали:


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

ВВ>С другой стороны даже если __stdcall вычисляет параметры справа налево, то, видимо, указанное поведение не будет таким уж непривычным для программиста?

В С++ неважно слева направо или наоборот, т.к. в общем случае неопределен порядок вычисления подвыражений. Поэтому, например, в таком коде:

typedef std::auto_ptr<T> ptr;
void foo(ptr a, ptr b);
//...
foo( ptr(new T), ptr(new T) );


присутствует потенциальная утечка.
Re[4]: Порядок вычисления аргументов
От: Воронков Василий Россия  
Дата: 11.10.10 13:09
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>В С++ неважно слева направо или наоборот, т.к. в общем случае неопределен порядок вычисления подвыражений. Поэтому, например, в таком коде:

ЮЖ>
ЮЖ>typedef std::auto_ptr<T> ptr;
ЮЖ>void foo(ptr a, ptr b);
ЮЖ>//...
ЮЖ>foo( ptr(new T), ptr(new T) );

ЮЖ>присутствует потенциальная утечка.

Ну тут ссылку приводили на MS-specific. Хз, как там с этим. Если б помнил, не спрашивал.
По стандарту я так понял, нельзя вообще закладываться на то, что сайд эффекты будут происходить в определенном порядке — т.е. пример, приведенный DarkGray, с этой точки зрения просто адское зло.
Re: Порядок вычисления аргументов
От: Gaperton http://gaperton.livejournal.com
Дата: 11.10.10 13:22
Оценка: -1
Здравствуйте, Воронков Василий, Вы писали:

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


Стандарты подавляющего большинства языков не определяют этот порядок.

То, в каком порядке это происходит — это относится не к языку, а к так называемому calling convention.
http://en.wikipedia.org/wiki/X86_calling_conventions

ВВ>Вопросы:

ВВ>- Есть ли какие-нибудь языки с подобными извращениями?

Конечно. Например, так происходит при "pascal calling convention".

Ты можешь указать тип convention в своей программе на C++ при определении функции, так что язык тут не причем.

И это не самый странный convention. Вот, например, fastcall, при котором возможна ситуация, когда стек вообще не задействуется. Более того, компилятор имеет полное право воткнуть fastcall автоматически, если решит, что так лучше.

fastcall
Conventions entitled fastcall have not been standardized, and have been implemented differently, depending on the compiler vendor[1]. Typically fastcall calling conventions pass one or more arguments in registers which reduces the number of memory accesses required for the call.
Microsoft fastcall
Microsoft or GCC [2] __fastcall[3] convention (aka __msfastcall) passes the first two arguments (evaluated left to right) that fit into ECX and EDX. Remaining arguments are pushed onto the stack from right to left.
Borland fastcall
Evaluating arguments from left to right, it passes three arguments via EAX, EDX, ECX. Remaining arguments are pushed onto the stack, also left to right [4].
It is the default calling convention of Borland Delphi, where it is known as register.

Re[2]: Вот еще пример
От: Gaperton http://gaperton.livejournal.com
Дата: 11.10.10 13:28
Оценка:
Более современный — так сейчас происходит в 64-х битном Linux. Для функций с небольшим количеством аргументов ничего на стек не кладется, ни в каком порядке.

AMD64 ABI convention

The calling convention of the AMD64 application binary interface[8] is followed on Linux and other non-Microsoft operating systems. The registers RDI, RSI, RDX, RCX, R8 and R9 are used for integer and pointer arguments while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for floating point arguments. As in the Microsoft x64 calling convention, additional arguments are pushed onto the stack and the return value is stored in RAX.

Re[2]: Порядок вычисления аргументов
От: Воронков Василий Россия  
Дата: 11.10.10 13:43
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Стандарты подавляющего большинства языков не определяют этот порядок.

G>То, в каком порядке это происходит — это относится не к языку, а к так называемому calling convention.
G>http://en.wikipedia.org/wiki/X86_calling_conventions

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

ВВ>>Вопросы:

ВВ>>- Есть ли какие-нибудь языки с подобными извращениями?
G>Конечно. Например, так происходит при "pascal calling convention".
G>Ты можешь указать тип convention в своей программе на C++ при определении функции, так что язык тут не причем.

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

Вопрос можно поставить по-другому — есть ли энергичные языки, в которых порядок вычисления аргументов справа налево определен в стандарте — при том, что порядок вычисления остальных операций стандартный?
Re[3]: Порядок вычисления аргументов
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 11.10.10 14:19
Оценка:
ВВ>С другой стороны даже если __stdcall вычисляет параметры справа налево, то, видимо, указанное поведение не будет таким уж непривычным для программиста?

вы здесь говорите про __stdcall, fastcall и т.д.
но порядок передачи аргументов в функцию не имеет никакого отношения к порядку вызова функций.
Re[3]: Порядок вычисления аргументов
От: Gaperton http://gaperton.livejournal.com
Дата: 11.10.10 14:39
Оценка: 6 (1)
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Вопрос можно поставить по-другому — есть ли энергичные языки, в которых порядок вычисления аргументов справа налево определен в стандарте — при том, что порядок вычисления остальных операций стандартный?


А. В такой постановке — черт его знает.

Но я лично сильно в этом сомневаюсь. Причины две.
1) Нижележащие API (в частности, ОС) и библиотеки (включая динамические) могут быть написаны на разных языках, отличных от целевого, и уже поэтому convention неразумно делать частью стандарта конкретного языка. Создаст лишние сложности.
2) Закладка в программе на порядок вычисления аргументов функции — сама по себе очень плохая практика. Это неочевидно, и хрен поймешь.

Поэтому, включать порядок вычисления аргументов в стандарт — никакой пользы кроме вреда. Не думаю, что удастся найти такой язык. Разве что поискать среди ранних, вроде Fortran-ов. Он крив как турецкая сабля. Но в те времена и стандартов-то на языки не было .
Re[4]: Порядок вычисления аргументов
От: Gaperton http://gaperton.livejournal.com
Дата: 11.10.10 14:57
Оценка:
Здравствуйте, DarkGray, Вы писали:

ВВ>>С другой стороны даже если __stdcall вычисляет параметры справа налево, то, видимо, указанное поведение не будет таким уж непривычным для программиста?


DG>вы здесь говорите про __stdcall, fastcall и т.д.

DG>но порядок передачи аргументов в функцию не имеет никакого отношения к порядку вызова функций.

На регистрово-ограниченных архитектурах имеет самое прямое отношение.
Re[4]: Порядок вычисления аргументов
От: Gaperton http://gaperton.livejournal.com
Дата: 11.10.10 15:05
Оценка: +2
G>Но я лично сильно в этом сомневаюсь. Причины две.
G>1) Нижележащие API (в частности, ОС) и библиотеки (включая динамические) могут быть написаны на разных языках, отличных от целевого, и уже поэтому convention неразумно делать частью стандарта конкретного языка. Создаст лишние сложности.
G>2) Закладка в программе на порядок вычисления аргументов функции — сама по себе очень плохая практика. Это неочевидно, и хрен поймешь.

И стоит добавить третью причину. Если конвеншн определяет порядок вычисления — это сильно ограничивает современные оптимизаторы для компилируемых языков.

К примеру, компилятор может решить устроить замес из вычисления выражений в аргументах, с целью оптимально нагрузить конвейер. И если регистров дофига, и проц суперскалярно-конвейерный, то хороший компилятор так и поступит.

А если вызовы функций стоят в аргументах — он до кучи может решить их проинлайнить. Так может и JIT поступить в динамике.

А вот во времена Win 3.11 было все четко. Как в конвеншне указано положение в стеке — в таком порядке и считается. Ибо регистров мало, и один хрен не более одной инструкции за такт.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.