Функция должна удовлетворять соглашениям по вызову для языка С++.
Соглашения по вызову различаются по следующим параметрам:
· Правила формирования внутреннего имени функции;
· Правилами передачи параметров;
· Правилами очистки стека.
При формировании имени возможен регистро – чувствительный или регистро нечувствительный режим, возможно формирование дополнительных символов для обеспечения свойства перегрузки функции.
Для обеспечения возможности использования переменного списка параметров параметры могут записываться в стек, начиная с конца списка, для обеспечения максимальной скорости работы – для передачи параметров используются регистры
Очистку стека может выполнять вызывающая программа или функция.
В табл. 11.4 представлены соглашения по вызову и свойства этих соглашений.
Если файл с программой имеет расширение CPP, то по умолчанию используется режим 1, если файл с расширением С++ - режим 2. Если в программе с расширением СPP необходимо использовать функцию с соглашением С, заголовок этой функции имеет вид:
Extern “C” заголовок;
Если необходимо задать заголовочный файл, который можно использовать в программе на С и СРР, то применяют директивы
#ifdef __cplusplus
extern “C” {
#endif
заголовок 1;
заголовок 2;
…
#ifdef __cplusplus
}
#endif
Пример. Составить вызывающую программу и функции вычисления разности для двух чисел, используя все возможные соглашения по вызову.
Таблица 11.4. Соглашения по вызову, принятые в С++
№ п/п |
Тип соглашения |
Как задается |
Внутреннее имя функции |
Порядок передачи параметров |
Очистка стека |
Переменный список параметров |
1. |
Cpp |
- |
@имя$q[17]… |
¬ |
Вызывающая программа |
Да |
2. |
С |
Extern “C”… |
_имя |
¬ |
Вызывающая программа |
Да |
3. |
Fastcall |
Тип __fastcall … |
@имя$qqr… |
EAX, EDX, ECX |
Вызывающая программа |
Нет |
4. |
Stdcall |
Тип __stdcall … |
@имя$qqs… |
¬ |
Функция |
Нет |
5. |
Pascal |
Тип __pascal … |
@ИМЯ$Q… |
® |
Функция |
Нет |