g++ и цепочка вызовов.
От: e-Xecutor Россия  
Дата: 15.06.11 09:21
Оценка:
Обнаружил такое вот странное поведение кода генерируемого g++.
obj.method(arg1).method(arg2).method(arg3);

все аргументы считаются ДО вызова method, причём в таком порядке arg3->arg2->arg1.
Я понимаю, что порядок вычисления нескольких аргументов одной функции не специфицирован.
Но тут то вызовы разные, и порядок вызовов железобетонен, с какого перепугу считать arg3 первым?
Курители стандарта, что скажут?
Re: g++ и цепочка вызовов.
От: jazzer Россия Skype: enerjazzer
Дата: 15.06.11 09:31
Оценка:
Здравствуйте, e-Xecutor, Вы писали:

EX>Но тут то вызовы разные, и порядок вызовов железобетонен, с какого перепугу считать arg3 первым?


порядок вызовов железобетонен, это так, а вот порядок вычисления аргументов для этих вызовов — нет.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: g++ и цепочка вызовов.
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 15.06.11 11:31
Оценка:
Здравствуйте, e-Xecutor, Вы писали:

EX>Обнаружил такое вот странное поведение кода генерируемого g++.

EX>
EX>obj.method(arg1).method(arg2).method(arg3);
EX>

EX>все аргументы считаются ДО вызова method, причём в таком порядке arg3->arg2->arg1.
EX>Я понимаю, что порядок вычисления нескольких аргументов одной функции не специфицирован.
EX>Но тут то вызовы разные, и порядок вызовов железобетонен, с какого перепугу считать arg3 первым?
EX>Курители стандарта, что скажут?

эквивалентный код:

method(method(method(obj, arg1), arg2)/*X*/, arg3/*Y*/);

порядок вычисления аргументов функций -- не задан в стандарте.
что вычислять раньше -- X или Y -- решать компилятору.
Re: g++ и цепочка вызовов.
От: e-Xecutor Россия  
Дата: 15.06.11 15:31
Оценка:
Здравствуйте, e-Xecutor, Вы писали:

Чё-то мозг от жары видимо чуток оплавился.
Это же одно выражение, а аргументы — подвыражения.
А порядок вычисления подвыражений в выражении не специфицирован.

Пол часа дебажил чужой код, где вычисление этих самых аргументов
было с побочным эффектом, ну и результат менялся в зависимости от порядка.
Но не сильно. А ровно на столько, что б в воздухе повис вопрос "чё за хрень???".
Re[2]: g++ и цепочка вызовов.
От: BulatZiganshin  
Дата: 16.06.11 20:08
Оценка:
Здравствуйте, BitField, Вы писали:

BF>method(method(method(obj, arg1), arg2)/*X*/, arg3/*Y*/);


... и добавим к этому что при методе вызова ccall аргументы в стек суются с конца
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: g++ и цепочка вызовов.
От: jyuyjiyuijyu  
Дата: 17.06.11 00:00
Оценка:
для полного профита надо сказать почему слева направо
дело в том что если бы было наоборот то функция с переменным числом
аргументов не знала бы где лежит ее первый пварметр
пример printf("%d%s", digit, string);

при парсинге находит %d и знает где лежит первый параметр (хоть и не знает их кол-во)
если бы было наоборот (справа налево) то дополнительно пришлось бы передавать
количество аргументов это убило бы всю идею сишного f(int,....);


__stdcall гибрид параметры слева направо но стек чистит сам
вот ему то точно не обязательно слева направо аргументы передавать
он всегда знает их количество и дотянутся к первому нет никакой проблемы
почему так сделали остается только гадать
Re[4]: g++ и цепочка вызовов.
От: BulatZiganshin  
Дата: 17.06.11 11:22
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>__stdcall гибрид параметры слева направо но стек чистит сам

J>вот ему то точно не обязательно слева направо аргументы передавать
J>он всегда знает их количество и дотянутся к первому нет никакой проблемы
J>почему так сделали остается только гадать

потому что в паскале нет функций с переменным числом аргументов. вообще в С они появились только потому что стёк позволяет это сделать, не знаю ни одного другого ЯВУ, где были бы нетипизированные функции с переменным числом аргументов
Люди, я люблю вас! Будьте бдительны!!!
Re[5]: g++ и цепочка вызовов.
От: jyuyjiyuijyu  
Дата: 17.06.11 21:03
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

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


J>>__stdcall гибрид параметры слева направо но стек чистит сам

J>>вот ему то точно не обязательно слева направо аргументы передавать
J>>он всегда знает их количество и дотянутся к первому нет никакой проблемы
J>>почему так сделали остается только гадать

BZ>потому что в паскале нет функций с переменным числом аргументов. вообще в С они появились только потому что стёк позволяет это сделать, не знаю ни одного другого ЯВУ, где были бы нетипизированные функции с переменным числом аргументов

да нет почему стек чистит вызываемая как раз понятно корректировка
стека в одном месте а не растаскивается по всем вызовам в итоге прога
меньше а вот почему передаютс справа налево интересно могли бы и слева направо
Re[6]: g++ и цепочка вызовов.
От: BulatZiganshin  
Дата: 18.06.11 05:21
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>меньше а вот почему передаютс справа налево интересно могли бы и слева направо


потому что нужен доступ к первому аргументу (например в printf) по фиксированной похиции относительно текущего указателя стека
Люди, я люблю вас! Будьте бдительны!!!
Re[7]: g++ и цепочка вызовов.
От: jyuyjiyuijyu  
Дата: 18.06.11 06:01
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

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


J>>меньше а вот почему передаютс справа налево интересно могли бы и слева направо


BZ>потому что нужен доступ к первому аргументу (например в printf) по фиксированной похиции относительно текущего указателя стека

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

вот и мой вопрос был почему при __stdcall аргументы передаются
справа налево хотя можно и слева направо она в любом случае знает
где первый аргумент так как знает их количество
Re[8]: g++ и цепочка вызовов.
От: BulatZiganshin  
Дата: 18.06.11 06:13
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>вот и мой вопрос был почему при __stdcall аргументы передаются

J>справа налево

имхо они передаются как раз слева направо, в естественном порядке
Люди, я люблю вас! Будьте бдительны!!!
Re[9]: g++ и цепочка вызовов.
От: jyuyjiyuijyu  
Дата: 18.06.11 06:23
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

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


J>>вот и мой вопрос был почему при __stdcall аргументы передаются

J>>справа налево

BZ>имхо они передаются как раз слева направо, в естественном порядке

ну это смотря что считать естественным порядком а так
сначала последний последним первый (тоесть справа налево)
Re: g++ и цепочка вызовов.
От: kvser  
Дата: 22.06.11 11:43
Оценка:
Здравствуйте, e-Xecutor, Вы писали:

EX>Я понимаю, что порядок вычисления нескольких аргументов одной функции не специфицирован.

Не аргументов одной функции, а порядок вычисления выражений, находящихся между двумя точками следования абстрактной машины C++. Например, ";" — точка следования в C+++
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.