SlideShare ist ein Scribd-Unternehmen logo
1 von 3
Downloaden Sie, um offline zu lesen
Урок 10. Паттерн 2. Функции с
переменным количеством аргументов
Классическими примерами, приводимыми во многих статьях по проблемам переноса программ
на 64-битные системы, является некорректное использование функций printf, scanf и их
разновидностей.

Пример 1:

const char *invalidFormat = "%u";

size_t value = SIZE_MAX;

printf(invalidFormat, value);

Пример 2:

char buf[9];

sprintf(buf, "%p", pointer);

В первом случае не учитывается, что тип size_t не эквивалентен типу unsigned на 64-битной
платформе. Это приведет к выводу на печать некорректного результата, в случае если value >
UINT_MAX.

Во втором случае автор кода не учел, что размер указателя в будущем может составить более 32
бит. В результате на 64-битной архитектуре данный код приведет к переполнению буфера.

Некорректное использование функций с перемененным количеством параметров является
распространенной ошибкой на всех архитектурах, а не только 64-битных. Это связано с
принципиальной опасностью использования данных конструкций языка Си++. Общепринятой
практикой является отказ от них и использование безопасных методик программирования. Мы
настоятельно рекомендуем модифицировать код и использовать безопасные методы. Например,
можно заменить printf на cout, а sprintf на boost::format или std::stringstream.

Данную рекомендацию часто критикуют разработчики под Linux, аргументируя тем, что gcc
проверяет соответствие строки форматирования фактическим параметрам, передаваемым в
функцию printf. Однако они забывают, что строка форматирования может передаваться из другой
части программы, загружаться из ресурсов. Другими словами, в реальной программе строка
форматирования редко присутствует в явном виде в коде, и, соответственно, компилятор не
может ее проверить. Если же разработчик использует Visual Studio 2005/2008, то он не сможет
получить предупреждение на код вида "void *p = 0; printf("%x", p);" даже используя ключи /W4 и
/Wall.

Для работы с memsize-типами в функциях вида sscanf, printf имеются спецификаторы размера.
Если вы разрабатываете Windows-приложение, то вы можете использовать спецификатор размера
"I". Пример использования:

size_t s = 1;
printf("%Iu", s);

Если вы разрабатываете приложение под Linux, то вам будет доступен спецификатор размера "z".
Пример использования:

size_t s = 1;

printf("%zu", s);

Спецификаторы хорошо описаны в статье Wikipedia "printf".

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

// PR_SIZET on Win64 = "I"

// PR_SIZET on Win32 = ""

// PR_SIZET on Linux64 = "z"

// ...

size_t u;

scanf("%" PR_SIZET "u", &u);

Рассмотрим еще один пример. Хотя этот пример выглядит наиболее странно, код, который
приведен здесь в упрощенном виде, использовался в реальном приложении в подсистеме
UNDO/REDO:

// Здесь указатели сохранялись в виде строки

int *p1, *p2;

....

char str[128];

sprintf(str, "%X %X", p1, p2);

// А в другой функции данная строка

// обрабатывалась следующим образом:

void foo(char *str)

{

    int *p1, *p2;

    sscanf(str, "%X %X", &p1, &p2);

    // Результат - некорректное значение указателей p1 и p2.

    ...
}

Результатом манипуляций указателями с использованием %X стало некорректное поведение
программы на 64-битной системе. Данный пример показывает, как опасны потаенные дебри
больших и сложных проектов, которые пишутся многими годами. Если проект достаточно велик и
стар, то в нем можно встретить очень интересные фрагменты, подобные этому.


Диагностика
Опасность для функций с переменным количеством аргументов, представляют типы, меняющие
свой размер на 64-битной системе, то есть memsize типы. Статический анализатор PVS-Studio
предупреждает об использовании таких типов диагностическим сообщением V111.

Если типы аргументов не изменили своей разрядности, то код считается корректным, и
предупреждающих сообщений выдано не будет. Пример корректного кода с точки зрения
анализатора:

printf("%d", 10*5);

CString str;

size_t n = sizeof(float);

str.Format(StrFormat, static_cast<int>(n));

Авторы курса: Андрей Карпов (karpov@viva64.com), Евгений Рыжков (evg@viva64.com).

Правообладателем курса "Уроки разработки 64-битных приложений на языке Си/Си++"
является ООО "Системы программной верификации". Компания занимается разработкой
программного обеспечения в области анализа исходного кода программ. Сайт компании:
http://www.viva64.com.

Контактная информация: e-mail: support@viva64.com, 300027, г. Тула, а/я 1800.

Weitere ähnliche Inhalte

Andere mochten auch

Loovus reaalainetes
Loovus reaalainetesLoovus reaalainetes
Loovus reaalainetesTKHK
 
Neil Gains and Happy Anggraini Festival of NewMR 2016
Neil Gains and Happy Anggraini   Festival of NewMR 2016Neil Gains and Happy Anggraini   Festival of NewMR 2016
Neil Gains and Happy Anggraini Festival of NewMR 2016Ray Poynter
 
Iblc Congres 2009 Presentatie Paul Bessems
Iblc Congres 2009 Presentatie  Paul  BessemsIblc Congres 2009 Presentatie  Paul  Bessems
Iblc Congres 2009 Presentatie Paul BessemsIBLC
 
Trabajo a entregar de historia
Trabajo a entregar de historiaTrabajo a entregar de historia
Trabajo a entregar de historiaKARICLAU
 
Kelmser poetryanthology
Kelmser poetryanthologyKelmser poetryanthology
Kelmser poetryanthologyjkmarie
 
Project Delta Communication Package - Dec 7 Final
Project Delta Communication Package  - Dec 7 FinalProject Delta Communication Package  - Dec 7 Final
Project Delta Communication Package - Dec 7 FinalDavid Donohue
 
Slide share social media introduction by oliver de leeuw and salmaan (for dow...
Slide share social media introduction by oliver de leeuw and salmaan (for dow...Slide share social media introduction by oliver de leeuw and salmaan (for dow...
Slide share social media introduction by oliver de leeuw and salmaan (for dow...Oliver de Leeuw
 
Social media marketing for small business
Social media marketing for small businessSocial media marketing for small business
Social media marketing for small businessCharmaine Xy-Za Yape
 
Millennialmedia Year in Review - 2012
Millennialmedia Year in Review - 2012Millennialmedia Year in Review - 2012
Millennialmedia Year in Review - 2012Can Bakir
 
Hilltopfarms
Hilltopfarms  Hilltopfarms
Hilltopfarms emmaivy84
 
Ignite For Ian Leslie
Ignite For Ian LeslieIgnite For Ian Leslie
Ignite For Ian Leslieil4818leslie
 

Andere mochten auch (19)

Loovus reaalainetes
Loovus reaalainetesLoovus reaalainetes
Loovus reaalainetes
 
Neil Gains and Happy Anggraini Festival of NewMR 2016
Neil Gains and Happy Anggraini   Festival of NewMR 2016Neil Gains and Happy Anggraini   Festival of NewMR 2016
Neil Gains and Happy Anggraini Festival of NewMR 2016
 
Booming Beijing
Booming BeijingBooming Beijing
Booming Beijing
 
Iblc Congres 2009 Presentatie Paul Bessems
Iblc Congres 2009 Presentatie  Paul  BessemsIblc Congres 2009 Presentatie  Paul  Bessems
Iblc Congres 2009 Presentatie Paul Bessems
 
Project idea savyuk
Project idea savyukProject idea savyuk
Project idea savyuk
 
Trabajo a entregar de historia
Trabajo a entregar de historiaTrabajo a entregar de historia
Trabajo a entregar de historia
 
Kelmser poetryanthology
Kelmser poetryanthologyKelmser poetryanthology
Kelmser poetryanthology
 
Project Delta Communication Package - Dec 7 Final
Project Delta Communication Package  - Dec 7 FinalProject Delta Communication Package  - Dec 7 Final
Project Delta Communication Package - Dec 7 Final
 
Slide share social media introduction by oliver de leeuw and salmaan (for dow...
Slide share social media introduction by oliver de leeuw and salmaan (for dow...Slide share social media introduction by oliver de leeuw and salmaan (for dow...
Slide share social media introduction by oliver de leeuw and salmaan (for dow...
 
bbnn
bbnnbbnn
bbnn
 
10 3 мalta_2014_25_03_2014
10 3 мalta_2014_25_03_201410 3 мalta_2014_25_03_2014
10 3 мalta_2014_25_03_2014
 
Asyse nuestros servicios
Asyse nuestros serviciosAsyse nuestros servicios
Asyse nuestros servicios
 
Social media marketing for small business
Social media marketing for small businessSocial media marketing for small business
Social media marketing for small business
 
Resume - Alejandro Mercado
Resume - Alejandro MercadoResume - Alejandro Mercado
Resume - Alejandro Mercado
 
Millennialmedia Year in Review - 2012
Millennialmedia Year in Review - 2012Millennialmedia Year in Review - 2012
Millennialmedia Year in Review - 2012
 
Home energy efficiency 101
Home energy efficiency 101Home energy efficiency 101
Home energy efficiency 101
 
Customer Loyalty Dps
Customer Loyalty DpsCustomer Loyalty Dps
Customer Loyalty Dps
 
Hilltopfarms
Hilltopfarms  Hilltopfarms
Hilltopfarms
 
Ignite For Ian Leslie
Ignite For Ian LeslieIgnite For Ian Leslie
Ignite For Ian Leslie
 

Ähnlich wie Урок 10. Паттерн 2. Функции с переменным количеством аргументов

Безопасность 64-битного кода
Безопасность 64-битного кодаБезопасность 64-битного кода
Безопасность 64-битного кодаTatyanazaxarova
 
Урок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаУрок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаTatyanazaxarova
 
Статический анализ кода для верификации 64-битных приложений
Статический анализ кода для верификации 64-битных приложенийСтатический анализ кода для верификации 64-битных приложений
Статический анализ кода для верификации 64-битных приложенийTatyanazaxarova
 
Что такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_tЧто такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_tTatyanazaxarova
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийTatyanazaxarova
 
20 ловушек переноса Си++ - кода на 64-битную платформу
20 ловушек переноса Си++ - кода на 64-битную платформу20 ловушек переноса Си++ - кода на 64-битную платформу
20 ловушек переноса Си++ - кода на 64-битную платформуTatyanazaxarova
 
Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...Sergey Vasilyev
 
32 подводных камня OpenMP при программировании на Си++
32 подводных камня OpenMP при программировании на Си++32 подводных камня OpenMP при программировании на Си++
32 подводных камня OpenMP при программировании на Си++Tatyanazaxarova
 
Урок 21. Паттерн 13. Выравнивание данных
Урок 21. Паттерн 13. Выравнивание данныхУрок 21. Паттерн 13. Выравнивание данных
Урок 21. Паттерн 13. Выравнивание данныхTatyanazaxarova
 
Поиск уязвимостей в программах с помощью анализаторов кода
Поиск уязвимостей в программах с помощью анализаторов кодаПоиск уязвимостей в программах с помощью анализаторов кода
Поиск уязвимостей в программах с помощью анализаторов кодаTatyanazaxarova
 
Что такое "Parallel Lint"?
Что такое "Parallel Lint"?Что такое "Parallel Lint"?
Что такое "Parallel Lint"?Tatyanazaxarova
 
Отладка и оптимизация многопоточных OpenMP-программ
Отладка и оптимизация многопоточных OpenMP-программОтладка и оптимизация многопоточных OpenMP-программ
Отладка и оптимизация многопоточных OpenMP-программTatyanazaxarova
 
Реклама PVS-Studio - статический анализ кода на языке Си и Си++
Реклама PVS-Studio - статический анализ кода на языке Си и Си++Реклама PVS-Studio - статический анализ кода на языке Си и Си++
Реклама PVS-Studio - статический анализ кода на языке Си и Си++Andrey Karpov
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeTatyanazaxarova
 
Разница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомРазница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомTatyanazaxarova
 
Урок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияУрок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияTatyanazaxarova
 
Разработка статического анализатора кода для обнаружения ошибок переноса прог...
Разработка статического анализатора кода для обнаружения ошибок переноса прог...Разработка статического анализатора кода для обнаружения ошибок переноса прог...
Разработка статического анализатора кода для обнаружения ошибок переноса прог...Tatyanazaxarova
 
Урок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметикаУрок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметикаTatyanazaxarova
 
VivaMP, система выявления ошибок в коде параллельных программ на языке С++, и...
VivaMP, система выявления ошибок в коде параллельных программ на языке С++, и...VivaMP, система выявления ошибок в коде параллельных программ на языке С++, и...
VivaMP, система выявления ошибок в коде параллельных программ на языке С++, и...Tatyanazaxarova
 

Ähnlich wie Урок 10. Паттерн 2. Функции с переменным количеством аргументов (20)

Безопасность 64-битного кода
Безопасность 64-битного кодаБезопасность 64-битного кода
Безопасность 64-битного кода
 
Урок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаУрок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметика
 
Статический анализ кода для верификации 64-битных приложений
Статический анализ кода для верификации 64-битных приложенийСтатический анализ кода для верификации 64-битных приложений
Статический анализ кода для верификации 64-битных приложений
 
Что такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_tЧто такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_t
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложений
 
20 ловушек переноса Си++ - кода на 64-битную платформу
20 ловушек переноса Си++ - кода на 64-битную платформу20 ловушек переноса Си++ - кода на 64-битную платформу
20 ловушек переноса Си++ - кода на 64-битную платформу
 
Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...
 
32 подводных камня OpenMP при программировании на Си++
32 подводных камня OpenMP при программировании на Си++32 подводных камня OpenMP при программировании на Си++
32 подводных камня OpenMP при программировании на Си++
 
Урок 21. Паттерн 13. Выравнивание данных
Урок 21. Паттерн 13. Выравнивание данныхУрок 21. Паттерн 13. Выравнивание данных
Урок 21. Паттерн 13. Выравнивание данных
 
Поиск уязвимостей в программах с помощью анализаторов кода
Поиск уязвимостей в программах с помощью анализаторов кодаПоиск уязвимостей в программах с помощью анализаторов кода
Поиск уязвимостей в программах с помощью анализаторов кода
 
Что такое "Parallel Lint"?
Что такое "Parallel Lint"?Что такое "Parallel Lint"?
Что такое "Parallel Lint"?
 
Отладка и оптимизация многопоточных OpenMP-программ
Отладка и оптимизация многопоточных OpenMP-программОтладка и оптимизация многопоточных OpenMP-программ
Отладка и оптимизация многопоточных OpenMP-программ
 
Реклама PVS-Studio - статический анализ кода на языке Си и Си++
Реклама PVS-Studio - статический анализ кода на языке Си и Си++Реклама PVS-Studio - статический анализ кода на языке Си и Си++
Реклама PVS-Studio - статический анализ кода на языке Си и Си++
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
 
Разница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомРазница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментом
 
Багдатов Методы автоматического выявления плагиата в текстах компьютерных про...
Багдатов Методы автоматического выявления плагиата в текстах компьютерных про...Багдатов Методы автоматического выявления плагиата в текстах компьютерных про...
Багдатов Методы автоматического выявления плагиата в текстах компьютерных про...
 
Урок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияУрок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложения
 
Разработка статического анализатора кода для обнаружения ошибок переноса прог...
Разработка статического анализатора кода для обнаружения ошибок переноса прог...Разработка статического анализатора кода для обнаружения ошибок переноса прог...
Разработка статического анализатора кода для обнаружения ошибок переноса прог...
 
Урок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметикаУрок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметика
 
VivaMP, система выявления ошибок в коде параллельных программ на языке С++, и...
VivaMP, система выявления ошибок в коде параллельных программ на языке С++, и...VivaMP, система выявления ошибок в коде параллельных программ на языке С++, и...
VivaMP, система выявления ошибок в коде параллельных программ на языке С++, и...
 

Mehr von Tatyanazaxarova

Урок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окруженияУрок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окруженияTatyanazaxarova
 
Урок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программУрок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программTatyanazaxarova
 
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибокУрок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибокTatyanazaxarova
 
Урок 24. Фантомные ошибки
Урок 24. Фантомные ошибкиУрок 24. Фантомные ошибки
Урок 24. Фантомные ошибкиTatyanazaxarova
 
Урок 23. Паттерн 15. Рост размеров структур
Урок 23. Паттерн 15. Рост размеров структурУрок 23. Паттерн 15. Рост размеров структур
Урок 23. Паттерн 15. Рост размеров структурTatyanazaxarova
 
Урок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. ИсключенияУрок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. ИсключенияTatyanazaxarova
 
Урок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен даннымиУрок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен даннымиTatyanazaxarova
 
Урок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединенияхУрок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединенияхTatyanazaxarova
 
Урок 11. Паттерн 3. Операции сдвига
Урок 11. Паттерн 3. Операции сдвигаУрок 11. Паттерн 3. Операции сдвига
Урок 11. Паттерн 3. Операции сдвигаTatyanazaxarova
 
Урок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибокУрок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибокTatyanazaxarova
 
Урок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибокУрок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибокTatyanazaxarova
 
Урок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном кодеУрок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном кодеTatyanazaxarova
 
Урок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурацииУрок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурацииTatyanazaxarova
 
Статический анализ Си++ кода
Статический анализ Си++ кодаСтатический анализ Си++ кода
Статический анализ Си++ кодаTatyanazaxarova
 
PVS-Studio научился следить за тем, как вы программируете
PVS-Studio научился следить за тем, как вы программируетеPVS-Studio научился следить за тем, как вы программируете
PVS-Studio научился следить за тем, как вы программируетеTatyanazaxarova
 
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteTatyanazaxarova
 
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...Tatyanazaxarova
 
Статический анализ и ROI
Статический анализ и ROIСтатический анализ и ROI
Статический анализ и ROITatyanazaxarova
 
Вечный вопрос измерения времени
Вечный вопрос измерения времениВечный вопрос измерения времени
Вечный вопрос измерения времениTatyanazaxarova
 

Mehr von Tatyanazaxarova (20)

Урок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окруженияУрок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окружения
 
Урок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программУрок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программ
 
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибокУрок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
 
Урок 24. Фантомные ошибки
Урок 24. Фантомные ошибкиУрок 24. Фантомные ошибки
Урок 24. Фантомные ошибки
 
Урок 23. Паттерн 15. Рост размеров структур
Урок 23. Паттерн 15. Рост размеров структурУрок 23. Паттерн 15. Рост размеров структур
Урок 23. Паттерн 15. Рост размеров структур
 
Урок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. ИсключенияУрок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. Исключения
 
Урок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен даннымиУрок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен данными
 
Урок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединенияхУрок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединениях
 
Урок 11. Паттерн 3. Операции сдвига
Урок 11. Паттерн 3. Операции сдвигаУрок 11. Паттерн 3. Операции сдвига
Урок 11. Паттерн 3. Операции сдвига
 
Урок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибокУрок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибок
 
Урок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибокУрок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибок
 
Урок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном кодеУрок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном коде
 
Урок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурацииУрок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурации
 
Статический анализ Си++ кода
Статический анализ Си++ кодаСтатический анализ Си++ кода
Статический анализ Си++ кода
 
PVS-Studio
PVS-Studio PVS-Studio
PVS-Studio
 
PVS-Studio научился следить за тем, как вы программируете
PVS-Studio научился следить за тем, как вы программируетеPVS-Studio научился следить за тем, как вы программируете
PVS-Studio научился следить за тем, как вы программируете
 
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-Paste
 
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
 
Статический анализ и ROI
Статический анализ и ROIСтатический анализ и ROI
Статический анализ и ROI
 
Вечный вопрос измерения времени
Вечный вопрос измерения времениВечный вопрос измерения времени
Вечный вопрос измерения времени
 

Урок 10. Паттерн 2. Функции с переменным количеством аргументов

  • 1. Урок 10. Паттерн 2. Функции с переменным количеством аргументов Классическими примерами, приводимыми во многих статьях по проблемам переноса программ на 64-битные системы, является некорректное использование функций printf, scanf и их разновидностей. Пример 1: const char *invalidFormat = "%u"; size_t value = SIZE_MAX; printf(invalidFormat, value); Пример 2: char buf[9]; sprintf(buf, "%p", pointer); В первом случае не учитывается, что тип size_t не эквивалентен типу unsigned на 64-битной платформе. Это приведет к выводу на печать некорректного результата, в случае если value > UINT_MAX. Во втором случае автор кода не учел, что размер указателя в будущем может составить более 32 бит. В результате на 64-битной архитектуре данный код приведет к переполнению буфера. Некорректное использование функций с перемененным количеством параметров является распространенной ошибкой на всех архитектурах, а не только 64-битных. Это связано с принципиальной опасностью использования данных конструкций языка Си++. Общепринятой практикой является отказ от них и использование безопасных методик программирования. Мы настоятельно рекомендуем модифицировать код и использовать безопасные методы. Например, можно заменить printf на cout, а sprintf на boost::format или std::stringstream. Данную рекомендацию часто критикуют разработчики под Linux, аргументируя тем, что gcc проверяет соответствие строки форматирования фактическим параметрам, передаваемым в функцию printf. Однако они забывают, что строка форматирования может передаваться из другой части программы, загружаться из ресурсов. Другими словами, в реальной программе строка форматирования редко присутствует в явном виде в коде, и, соответственно, компилятор не может ее проверить. Если же разработчик использует Visual Studio 2005/2008, то он не сможет получить предупреждение на код вида "void *p = 0; printf("%x", p);" даже используя ключи /W4 и /Wall. Для работы с memsize-типами в функциях вида sscanf, printf имеются спецификаторы размера. Если вы разрабатываете Windows-приложение, то вы можете использовать спецификатор размера "I". Пример использования: size_t s = 1;
  • 2. printf("%Iu", s); Если вы разрабатываете приложение под Linux, то вам будет доступен спецификатор размера "z". Пример использования: size_t s = 1; printf("%zu", s); Спецификаторы хорошо описаны в статье Wikipedia "printf". Если вы вынуждены поддерживать переносимый код, использующий функции типа sscanf, то в формате управляющих строк можно использовать специальные макросы, раскрывающиеся в необходимые спецификаторы размера. Пример макроса, помогающего создавать переносимый код для разных систем: // PR_SIZET on Win64 = "I" // PR_SIZET on Win32 = "" // PR_SIZET on Linux64 = "z" // ... size_t u; scanf("%" PR_SIZET "u", &u); Рассмотрим еще один пример. Хотя этот пример выглядит наиболее странно, код, который приведен здесь в упрощенном виде, использовался в реальном приложении в подсистеме UNDO/REDO: // Здесь указатели сохранялись в виде строки int *p1, *p2; .... char str[128]; sprintf(str, "%X %X", p1, p2); // А в другой функции данная строка // обрабатывалась следующим образом: void foo(char *str) { int *p1, *p2; sscanf(str, "%X %X", &p1, &p2); // Результат - некорректное значение указателей p1 и p2. ...
  • 3. } Результатом манипуляций указателями с использованием %X стало некорректное поведение программы на 64-битной системе. Данный пример показывает, как опасны потаенные дебри больших и сложных проектов, которые пишутся многими годами. Если проект достаточно велик и стар, то в нем можно встретить очень интересные фрагменты, подобные этому. Диагностика Опасность для функций с переменным количеством аргументов, представляют типы, меняющие свой размер на 64-битной системе, то есть memsize типы. Статический анализатор PVS-Studio предупреждает об использовании таких типов диагностическим сообщением V111. Если типы аргументов не изменили своей разрядности, то код считается корректным, и предупреждающих сообщений выдано не будет. Пример корректного кода с точки зрения анализатора: printf("%d", 10*5); CString str; size_t n = sizeof(float); str.Format(StrFormat, static_cast<int>(n)); Авторы курса: Андрей Карпов (karpov@viva64.com), Евгений Рыжков (evg@viva64.com). Правообладателем курса "Уроки разработки 64-битных приложений на языке Си/Си++" является ООО "Системы программной верификации". Компания занимается разработкой программного обеспечения в области анализа исходного кода программ. Сайт компании: http://www.viva64.com. Контактная информация: e-mail: support@viva64.com, 300027, г. Тула, а/я 1800.