Jenter Алекс
Шрифт:
Если floating-point вычисления необходимы, попробуйте обмануть компилятор с помощью _fltused
Встретив в программе объявление float-переменной (или double), компилятор автоматически вставляет в генерируемый код внешнюю ссылку на переменную _fltused, находящуюся в одном из файлов CRT. Это делается для того, чтобы прилинковать к программе код обработчика ошибок вычислений с плавающей точкой.
В случае, когда нельзя обойтись без плавающей арифметики, но код заведомо не вызовет ошибок, можно попытаться отключить стартовый код CRT для плавающих вычислений с помощью примерно такого объявления:
Переменная оказывается определенной внутри модуля, и линкеру незачем искать ее где-нибудь еще.
Но фокус не сработает, если произойдет вызов функции CRT. Это может случиться неявно, например, при преобразовании между целочисленными и плавающими типами:
Правда, _ftol - это как раз пример функции CRT, которая может быть безболезненно использована в минимальной программе. Просто укажите в списке библиотек LIBC.LIB и позаботьтесь о том, чтобы обеспечить компоновщик своей версией стартового кода (при использовании _ATL_MIN_CRT ничего дополнительно делать не нужно).
Если же вызываемая неявно функция требует инициализации, есть два пути: отказаться от борьбы или реализовать ее иным способом, о чем сейчас и пойдет речь.
Напоследок дам несколько советов, которые помогут обойтись без стартового кода CRT во многих случаях. Но помните, что это достигается за счет отказа от использования исключений, и работает не всегда. Как правило, начиная с какого-то объема кода, выигрыш от всех этих ухищрений сходит на нет, а неудобства отказ от CRT доставляет по-прежнему немалые.
Библиотека MFC требует наличия кода инициализации, и тут уж ничего не поделаешь. Если очень хочется использовать библиотеку оконных классов в сверхмалых проектах, посмотрите в сторону ATL/WTL и их расширений (например, Attila).
Обработка исключений в стиле C++ неизбежно потребует стартового кода CRT. Если исключения использовать необходимо, попробуйте воспользоваться структурными исключениями Win32 с помощью ключевых слов __try, __except, __finally и т.д. Для их использования нужно подключить библиотеку импорта kernel32.lib.
Visual C++ поставляется с большим набором исходных файлов, в число которых входит и реализация CRT. Их изучение, кстати, приносит и еще одну выгоду – это поможет разобраться, как именно устроена поддержка стандартной библиотеки. В общем, "Use the source, Luke"!
Некоторые функции, требующие инициализации CRT, могут быть попросту вставлены компилятором в точку вызова. К ним относятся cos, strlen и многие другие. Изучите документацию на #pragma intrinsic и опцию компилятора /Oi.
Это мощнейшее средство преобразования данных разных типов ничего не будет стоить – кроме, разве что, лишних тактов процессора.
Можно использовать как функции высокого уровня VariantChangeType/VariantChangeTypeEx, так и вспомогательные функции преобразования вида VarXXXFromYYY. В приведенном выше блоке кода, например, поможет функция VarI4FromR8:
Использование Automation API позволит не только решить проблему преобразования, описанную выше, но и учесть при этом региональные настройки – например, получить локализованную строку даты. Кроме того, функция VarBstrCmp поможет при сравнении строк unicode (но будьте осторожны с ней – в старых версиях Windows она отличается от новых реализаций, также нужно иметь установленный Service Pack 4 или выше для VC, иначе заголовочный файл будет содержать некорректное описание этой функции).
Для использования этих функций необходимо подключить библиотеку импорта oleaut32.lib.
До следующей встречи!
Алекс Jenter jenter@rsdn.ru Duisburg, 2001. Публикуемые в рассылке материалы принадлежат сайту RSDN.Программирование на Visual C++
Выпуск №62 от 3 февраля 2002 г.
Здравствуйте, уважаемые подписчики!