Добавил:
github.com Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Технология программирования / 2_1_otladka_v_konsoli_30_08_19_-_2_Chasa.doc
Скачиваний:
4
Добавлен:
30.09.2023
Размер:
3.56 Mб
Скачать

/Gd, /Gr, /Gz (соглашения о вызовах)

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

  • /Gd (параметр по умолчанию) указывает соглашение о вызовах __cdecl для всех функций за исключением функций-членов C++ и функций, помеченных как __stdcall или __fastcall.

  • /Gr указывает соглашение о вызовах __fastcall для всех функций за исключением функций-членов C++ и функций, помеченных как __cdecl или __stdcall. Все функции __fastcall должны иметь прототипы.

  • /Gz указывает соглашение о вызовах __stdcall для всех функций за исключением функций-членов C++ и функций, помеченных как __cdecl или __fastcall. Все функции __stdcall должны иметь прототипы.

Функция, принимающая переменное число аргументов, должна быть помечена как __cdecl.

Параметры оптимизации кода

Параметры /O обеспечивают управление различными способами оптимизации, предназначенными для создания кода максимальной производительности или минимального размера.

  • /O1 — оптимизация для получения минимального размера кода.

  • /O2 — оптимизация кода для получения максимальной скорости его выполнения.

  • /Ob — контроль над расширением встроенных функций.

  • /Od — отключение оптимизации для ускорения компиляции и упрощения отладки.

  • /Og — включение глобальной оптимизации.

  • /Oi — создание встроенных функций для соответствующих вызовов функций.

  • /Os — задание для компилятора приоритетности оптимизации для уменьшения размера кода над оптимизацией для увеличения скорости его выполнения.

  • /Ot (настройка по умолчанию) — задание для компилятора приоритетности оптимизации для уменьшения размера кода над оптимизацией для увеличения скорости его выполнения.

  • /Ox — выбор полной оптимизации.

  • /Oy — отключение создания указателей фреймов для стека вызовов, что позволяет повысить скорость вызова функций.

Проверка стека вызовов указателей

Проверка стека вызовов указателей означает, что указатель стека проверя­ется до и после вызова функции через указатель для удостоверения того, что они равны друг другу.

Это позволяет перехватить ошибки несоответствия соглашений о вызове:

  • _cdecl с очисткой вызывающим вызовом (по умолчанию для программ на языках C и C++ используется соглашение о вызовах __cdecl. Поскольку стек очищается вызывающим вызовом, оно может реализовывать функции с переменным числом аргументов. Соглашение о вызовах __cdecl создает исполняемые файлы большего размера, чем __stdcall, так как для него необходимо, чтобы вызов функции содержал код очистки стека)

  • _fastcall (соглашение о вызовах __fastcall указывает, что аргументы для функций должны по возможности передаваться в регистрах. Это соглашение о вызовах применяется только к архитектуре x86. В следующем списке показана реализация этого соглашения о вызове.)

  • _stdcall с очисткой вызываемым, — когда вызов функции производится че­рез указатель.( Соглашение __stdcall используется для вызова функций API Win32. Стек очищается вызываемой функцией, поэтому компилятор применяет для функций vararg соглашение __cdecl. Для функций, использующих данное соглашение о вызовах, требуется прототип.)

return-type __stdcall function-name[(argument-list)]

Следующий пример работает с /Od, отказывает при /Ох и генерирует ис­ключение при /GZ. Вы получите сообщение о прерывании по ошибке стека, если компилируете его с рабочей версией библиотеки, и более осмысленное со­общение, если пример компилируется с отладочной библиотекой.

void stdcall myFuncA(char *p)

{

puts(p) ;

}

typedef void (*function__pointer) (char *);

void main( void )

{

function^pointer pmyFuncA = (function_pointer)myFuncA;

pmyFuncA("This is just a test.") ;

}

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

Проверка стека вызовов

Когда эта проверка включена, Visual C++ проверяет стек в конце функции, чтобы убедиться, что он не изменился. Тем самым перехватываются случаи, когда указатель стека оказывается нарушенным встроенными инструкциями ассемблера или из-за несовпадения соглашений при обычном (не через указа­тель) вызове.