ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   Общие вопросы программирования (https://forum.antichat.xyz/forumdisplay.php?f=206)
-   -   Зачем нужно __cdecl? (https://forum.antichat.xyz/showthread.php?t=1405131)

Fdsiyhu 19.10.2021 05:08

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

#Northn 19.10.2021 09:13

Цитата:

Сообщение от Fdsiyhu

Кому и зачем это может понадобиться?

Компьютеру, чтобы стек не переполнился и приложение не вылетело.

Компьютеру, чтобы понимать, откуда что брать: из ecx, edx, или из локального стека

Например, методы классов используют thiscall, в таком режиме в первый невидимый аргумент (регистр ecx) пихается указатель на наш класс.

memir 19.10.2021 09:20

варарги

.deserve 19.10.2021 11:55

Вот зачем - старая добрая вики

Плюс, как выше написали, cdecl функция, по причине того, что стек чистит самостоятельно caller, может использовать вариадики - цппреф

Цитата:

Сообщение от #Northn

Компьютеру, чтобы стек не переполнился и приложение не вылетело.
Компьютеру, чтобы понимать, откуда что брать: из ecx, edx, или из локального стека
Например, методы классов используют thiscall, в таком режиме в первый невидимый аргумент (регистр ecx) пихается указатель на наш класс.

При чем здесь переполнение стека? Соглашение о вызовах к этому вообще ни малейшего отношения не имеет

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

"Например, методы классов используют thiscall" - а в POSIX? Правильно, __cdecl.

И аргумент вполне себе видимый

#Northn 19.10.2021 13:53

Цитата:

Сообщение от .deserve

При чем здесь переполнение стека?

C++:





Код:

void
__cdecl
a
(
int
b
,
int
c
,
int
d
,
int
e
)
{
}
int
main
(
)
{
while
(
1
)
reinterpret_cast
(
void
(
__thiscall
*
)
(
int
,
int
,
int
,
int
)
(
a
)
(
1
,
2
,
3
,
4
)
;
}



Давай.

.deserve 19.10.2021 15:10

Цитата:

Сообщение от #Northn

C++:





Код:

void
__cdecl
a
(
int
b
,
int
c
,
int
d
,
int
e
)
{
}
int
main
(
)
{
while
(
1
)
reinterpret_cast
(
void
(
__thiscall
*
)
(
int
,
int
,
int
,
int
)
(
a
)
(
1
,
2
,
3
,
4
)
;
}



Давай.

Ты делаешь вложенные вызовы функции, вызывающие переполнение стека. А происходит это из-за "бесконечного" добавления фрейма активации. Зачем ты сюда соглашения о вызовах приплёл одному тебе известно. (читай upd) К тому же на цланге ты варнинг получишь по вызову cdecl функции через thiscall с игнором параметров.

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


Время: 00:38