Здравствуйте, disasm, Вы писали:
А>>>над первым арументом(arg0) кроме тех действий что я описал выше в функции, не происходит.
А>>>тоесть он используеться именно два раза как конструктор и далее возращаеться на выходе из функции
К>>Примерно так должна работать функция, возвращающая объект по значению.
К>>Вызывающая сторона выделяет у себя на стеке память под временный объект и отдаёт указатель в функцию.
К>>Функция в точке return (либо, если сделана оптимизация NRVO, в точке создания локального объекта) делает placement new и вызывает конструктор для данного указателя.
D>не совсем понял...
Поясняю ещё раз
// в исходном коде
Some foo()
{
if(...)
return Some(xxxxx);
else
return Some(yyyyy);
}
void bar()
{
foo().buz(); // Some::buz
}
// как это на самом деле
Some* foo(void* buf)
{
if(...)
return new(buf) Some(xxxxx); // гуглить "placement new" !!!
else
return new(buf) Some(yyyyy);
}
void bar()
{
char buf[sizeof(Some)];
Some* tmp = foo(buf);
tmp->buz();
tmp->~Some();
}
К>>Ну и правильно. Сколько разных объектов функция возвращает, столько разных конструкторов и вызывается.
К>>Они же вызываются не вместе, а вместо друг друга. if-then-else.
D>да! но перед ними и после них есть определенные действия с разными переменными
Some foo()
{
if(...)
{
Another var;
.....
Some x(xxxxx); // гуглить NRVO
.....
return x; // var.~Another()
}
else { ..... }
}
К>>Я точно не смотрел, как у известных мне компиляторов выглядит конвенция вызова функций, возвращающих объект.
К>>Очень может быть, что они уподобляются всяким strcpy: указатель на буфер на входе, указатель на тот же буфер на выходе.
D>GNU C++
D>обьект возращаеться через EAX
Этого недостаточно. Нужно выяснить — в каком порядке передаются аргументы в конвенции thiscall у функции, возвращающей объект по значению.
Возможно, this идёт вторым, а не первым параметром (первым идёт указатель на буфер возвращаемого объекта).
D>временный обьект был нужен
D>вот пример использование sub_8
Для всех будет лучше, если ты перестанешь делать вид, что объекты передаются по ссылке. Если там указатели — значит указатели.
"Объект передаётся в EAX" — глупости или жесточайшая оптимизация (когда размер объекта равен 4 и у него тривиальные конструкторы-деструкторы).
И не забывай оборачивать код в тэги [c]-[/c].
D>D::somefunc()
D>{
D> B tmp2;// стековая переменная
// конструктор здесь вызывается? если нет - это не стековая переменная, а только буфер под неё
D> sub_8(tmp2, m_tmp1); // m_tmp1 это обьект A член класса D
D> // думаю очень похоже на оператор и тогда
D> //вместо sub_8(tmp2, m_tmp1); было бы tmp2 << m_tmp1;
// это очень похоже на tmp2 = sub_8(*m_tmp1);
D> printf("%s\n", tmp2.GetStr());
D> tmp2.~B();
D>}
D>это то, что можно понять при дизассемблировании
А>>>помогите идентифицировать функции, и если можно пример ее использования
К>>Варианты сигнатур
К>>class B { ..... };
К>>class A {
К>> .....
К>> static B sub8_v1(A* otherA) { return cond ? B(xxxxx) : B(yyyyy); }
К>> B sub8_v2(/*this*/) { return cond ? B(xxxxx) : B(yyyyy); }
К>> // для извращенцев
К>> static B* sub8_v3(char* raw, A* otherA) { return cond ? new(raw)B(xxxxx) : new(raw)B(yyyyy); }
К>> .....
К>>};
D>замысловато, но тоже сильно накручено
Это была иллюстрация
D>поскольку там нет ни одного оператора new
placement new не вызывает ::operator new(size_t).
А ::operator new(void*,size_t) тривиальный, и компилятор его мысленно сократил. И правильно сделал.
К>>Ещё есть подозрения на виртуальное наследование A от B. Тогда sub8 — это, возможно, конструктор: он там довольно хитро устроен.
D>нет, виртуального наследование точно нет
D>я все более полагаюсь на то что это какойто оператор<<
D>но констуркторы в теле меня очень смущают
Попробуй всё более полагаться на возврат объекта по значению.