SlideShare a Scribd company logo
1 of 5
Download to read offline
Как стандарт C++0x поможет в борьбе
с 64-битными ошибками
Автор: Андрей Карпов

Дата: 28.02.2010

Программисты видят в стандарте C++0x возможность использовать лямбда-функции и прочие
мало понятные для меня сущности :). Я увидел в нем удобные средства, позволяющие исключить
многие 64-битные ошибки.

Рассмотрим функцию, которая возвращает true, если хотя бы в одной из строк встречается
последовательность "ABC".

typedef vector<string> ArrayOfStrings;

bool Find_Incorrect(const ArrayOfStrings &arrStr)

{

    ArrayOfStrings::const_iterator it;

    for (it = arrStr.begin(); it != arrStr.end(); ++it)

    {

        unsigned n = it->find("ABC");

        if (n != string::npos)

         return true;

    }

    return false;

};

Эта функция корректно ведет себя при компиляции Win32 версии и дает сбой при сборке в
режиме Win64. Рассмотрим пример использования функции:

#ifdef IS_64

    const char WinXX[] = "Win64";

#else

    const char WinXX[] = "Win32";

#endif

int _tmain(int argc, _TCHAR* argv[])

{
ArrayOfStrings array;

    array.push_back(string("123456"));

    array.push_back(string("QWERTY"));

    if (Find_Incorrect(array))

        printf("Find_Incorrect (%s): ERROR!n", WinXX);

    else

        printf("Find_Incorrect (%s): OK!n", WinXX);

    return 0;

}

Find_Incorrect (Win32): OK!

Find_Incorrect (Win64): ERROR!

Ошибка заключается в использовании типа unsigned для переменной "n", хотя функция find()
возвращает значение типа string::size_type. В 32-битной программе тип string::size_type и unsigned
совпадают, и мы получаем верный результат.

В 64-битной программе string::size_type и unsigned перестают совпадать. Так как подстрока не
находится, функция find() возвращает значение string::npos, которое равно
0xFFFFFFFFFFFFFFFFui64. Это значение урезается до величины 0xFFFFFFFFu и помещается в 32-
битную переменную. В результате условие 0xFFFFFFFFu == 0xFFFFFFFFFFFFFFFFui64 всегда false и
мы получаем сообщение "Find_Incorrect (Win64): ERROR!".

Исправим код, используя тип string::size_type.

bool Find_Correct(const ArrayOfStrings &arrStr)

{

    ArrayOfStrings::const_iterator it;

    for (it = arrStr.begin(); it != arrStr.end(); ++it)

    {

        string::size_type n = it->find("ABC");

        if (n != string::npos)

         return true;

    }

    return false;

};
Теперь код работает корректно, хотя постоянно писать тип string::size_type длинно и не красиво.
Можно переопределить его через typedef, но все равно это выглядит как-то сложно. Используя
C++0x, мы можем сделать код гораздо изящней надежней.

Для этого мы воспользуемся ключевым словом auto. Ранее auto означало, что переменная
создается на стеке, и подразумевалось неявно в случае, если вы не указали что-либо другое,
например register. Теперь тип переменной, объявленной как auto, определяется компилятором
самостоятельно на основе того, чем эта переменная инициализируется.

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

Воспользуемся ключевым словом auto в нашем коде. Проект был создан в Visual Studio 2005, а
поддержка C++0x реализована только начиная с версии Visual Studio 2010. Поэтому для
компиляции я воспользовался компилятором Intel C++, входящим в состав Intel Parallel Studio 11.1
и поддерживающим стандарт C++0x. Поддержка C++0x включается в разделе Language и носит
название "Enable C++0x Support". Как видно из рисунка 1, эта опция является Intel Specific.




Рисунок 1 - Поддержка стандарта C++0x

Модифицированный код выглядит следующим образом:

bool Find_Cpp0X(const ArrayOfStrings &arrStr)

{

    for (auto it = arrStr.begin(); it != arrStr.end(); ++it)
{

        auto n = it->find("ABC");

        if (n != string::npos)

         return true;

    }

    return false;

};

Обратите внимание, как теперь объявлена переменная "n". Неправда ли, элегантно и устраняет от
ряд ошибок, в том числе и 64-битных. Переменная "n" будет иметь ровно тот тип, который
возвращает функция find(), то-есть string::size_type. Также обратите внимание, что исчезла строчка
объявления итератора:

ArrayOfStrings::const_iterator it;

Объявлять переменную it внутри цикла было некрасиво (длинно). И поэтому объявление было
вынесено отдельно. Теперь проблемы длины нет:

for (auto it = arrStr.begin(); ......)

Рассмотрим еще одно ключевое слово - decltype. Оно позволяет задать тип на основании типа
другой переменной. Если бы в нашем коде, мы должны были объявить все переменные заранее,
то можно было бы написать так:

bool Find_Cpp0X_2(const ArrayOfStrings &arrStr)

{

    decltype(arrStr.begin()) it;

    decltype(it->find("")) n;

    for (it = arrStr.begin(); it != arrStr.end(); ++it)

    {

        n = it->find("ABC");

        if (n != string::npos)

         return true;

    }

    return false;

};

Конечно, в данном случае это бессмысленно, но может быть весьма удобно во многих ситуациях.
К сожалению (или к счастью для нас :-), хотя новый стандарт облегчает написание безопасного 64-
битного кода, он не помогает в устранении уже существующих дефектов. Для того чтобы
использовать memsize-тип или auto для устранений ошибки, эту ошибку нужно в начале
обнаружить. Следовательно, актуальность использования инструмента Viva64 с приходом
стандарта C++0x не изменится.

P.S.
Проект с кодом можно скачать здесь.

More Related Content

What's hot

стандартная библиотека с++: введение
стандартная библиотека с++: введениестандартная библиотека с++: введение
стандартная библиотека с++: введениеmcroitor
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 
Урок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаУрок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаTatyanazaxarova
 
Cpp/cli particularities
Cpp/cli particularitiesCpp/cli particularities
Cpp/cli particularitiesmcroitor
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++mcroitor
 
Rust: абстракции и безопасность, совершенно бесплатно
Rust: абстракции и безопасность, совершенно бесплатноRust: абстракции и безопасность, совершенно бесплатно
Rust: абстракции и безопасность, совершенно бесплатноOpen-IT
 
Cpp/cli types
Cpp/cli typesCpp/cli types
Cpp/cli typesmcroitor
 
указатель на функцию
указатель на функциюуказатель на функцию
указатель на функциюAleksandr Pavlenko
 
5.4 Ключевые слова static и inline
5.4 Ключевые слова static и inline5.4 Ключевые слова static и inline
5.4 Ключевые слова static и inlineDEVTYPE
 
контейнеры STL
контейнеры STLконтейнеры STL
контейнеры STLmcroitor
 
359.краткое введение в систему octave
359.краткое введение в систему octave359.краткое введение в систему octave
359.краткое введение в систему octaveivanov1566359955
 
5.1 Перегрузка операторов
5.1 Перегрузка операторов5.1 Перегрузка операторов
5.1 Перегрузка операторовDEVTYPE
 
Урок 9. Паттерн 1. Магические числа
Урок 9. Паттерн 1. Магические числаУрок 9. Паттерн 1. Магические числа
Урок 9. Паттерн 1. Магические числаTatyanazaxarova
 
алгоритмы stl
алгоритмы stlалгоритмы stl
алгоритмы stlmcroitor
 
scanf(). Операторы ветвления. Тернарный оператор. switch
scanf(). Операторы ветвления. Тернарный оператор. switchscanf(). Операторы ветвления. Тернарный оператор. switch
scanf(). Операторы ветвления. Тернарный оператор. switchIhor Porotikov
 
указатель на указатель 1
указатель на указатель 1указатель на указатель 1
указатель на указатель 1Aleksandr Pavlenko
 
2.6 Динамическая память
2.6 Динамическая память2.6 Динамическая память
2.6 Динамическая памятьDEVTYPE
 

What's hot (20)

стандартная библиотека с++: введение
стандартная библиотека с++: введениестандартная библиотека с++: введение
стандартная библиотека с++: введение
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Урок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаУрок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметика
 
Cpp/cli particularities
Cpp/cli particularitiesCpp/cli particularities
Cpp/cli particularities
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
 
Rust: абстракции и безопасность, совершенно бесплатно
Rust: абстракции и безопасность, совершенно бесплатноRust: абстракции и безопасность, совершенно бесплатно
Rust: абстракции и безопасность, совершенно бесплатно
 
Cpp/cli types
Cpp/cli typesCpp/cli types
Cpp/cli types
 
указатель на функцию
указатель на функциюуказатель на функцию
указатель на функцию
 
5.4 Ключевые слова static и inline
5.4 Ключевые слова static и inline5.4 Ключевые слова static и inline
5.4 Ключевые слова static и inline
 
контейнеры STL
контейнеры STLконтейнеры STL
контейнеры STL
 
359.краткое введение в систему octave
359.краткое введение в систему octave359.краткое введение в систему octave
359.краткое введение в систему octave
 
5.1 Перегрузка операторов
5.1 Перегрузка операторов5.1 Перегрузка операторов
5.1 Перегрузка операторов
 
Урок 9. Паттерн 1. Магические числа
Урок 9. Паттерн 1. Магические числаУрок 9. Паттерн 1. Магические числа
Урок 9. Паттерн 1. Магические числа
 
Javascript functions
Javascript functionsJavascript functions
Javascript functions
 
алгоритмы stl
алгоритмы stlалгоритмы stl
алгоритмы stl
 
scanf(). Операторы ветвления. Тернарный оператор. switch
scanf(). Операторы ветвления. Тернарный оператор. switchscanf(). Операторы ветвления. Тернарный оператор. switch
scanf(). Операторы ветвления. Тернарный оператор. switch
 
указатель на указатель 1
указатель на указатель 1указатель на указатель 1
указатель на указатель 1
 
Assert c
Assert cAssert c
Assert c
 
2.6 Динамическая память
2.6 Динамическая память2.6 Динамическая память
2.6 Динамическая память
 

Similar to Как стандарт C++0x поможет в борьбе с 64-битными ошибками

Урок 24. Фантомные ошибки
Урок 24. Фантомные ошибкиУрок 24. Фантомные ошибки
Урок 24. Фантомные ошибкиTatyanazaxarova
 
Урок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияУрок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияTatyanazaxarova
 
Коллекция примеров 64-битных ошибок в реальных программах
Коллекция примеров 64-битных ошибок в реальных программахКоллекция примеров 64-битных ошибок в реальных программах
Коллекция примеров 64-битных ошибок в реальных программахTatyanazaxarova
 
Что такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_tЧто такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_tTatyanazaxarova
 
Статический анализ и регулярные выражения
Статический анализ и регулярные выраженияСтатический анализ и регулярные выражения
Статический анализ и регулярные выраженияTatyanazaxarova
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeTatyanazaxarova
 
64-битный конь, который умеет считать
64-битный конь, который умеет считать64-битный конь, который умеет считать
64-битный конь, который умеет считатьTatyanazaxarova
 
Большой брат помогает тебе
Большой брат помогает тебеБольшой брат помогает тебе
Большой брат помогает тебеTatyanazaxarova
 
Разработка статического анализатора кода для обнаружения ошибок переноса прог...
Разработка статического анализатора кода для обнаружения ошибок переноса прог...Разработка статического анализатора кода для обнаружения ошибок переноса прог...
Разработка статического анализатора кода для обнаружения ошибок переноса прог...Tatyanazaxarova
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
20 ловушек переноса Си++ - кода на 64-битную платформу
20 ловушек переноса Си++ - кода на 64-битную платформу20 ловушек переноса Си++ - кода на 64-битную платформу
20 ловушек переноса Си++ - кода на 64-битную платформуTatyanazaxarova
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийTatyanazaxarova
 
Разница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомРазница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомTatyanazaxarova
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода Pavel Tsukanov
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийOOO "Program Verification Systems"
 
Сравнение диагностических возможностей анализаторов при проверке 64-битного кода
Сравнение диагностических возможностей анализаторов при проверке 64-битного кодаСравнение диагностических возможностей анализаторов при проверке 64-битного кода
Сравнение диагностических возможностей анализаторов при проверке 64-битного кодаTatyanazaxarova
 
Intel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиIntel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиTatyanazaxarova
 

Similar to Как стандарт C++0x поможет в борьбе с 64-битными ошибками (20)

Урок 24. Фантомные ошибки
Урок 24. Фантомные ошибкиУрок 24. Фантомные ошибки
Урок 24. Фантомные ошибки
 
Урок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияУрок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложения
 
Коллекция примеров 64-битных ошибок в реальных программах
Коллекция примеров 64-битных ошибок в реальных программахКоллекция примеров 64-битных ошибок в реальных программах
Коллекция примеров 64-битных ошибок в реальных программах
 
Что такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_tЧто такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_t
 
Статический анализ и регулярные выражения
Статический анализ и регулярные выраженияСтатический анализ и регулярные выражения
Статический анализ и регулярные выражения
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
 
64-битный конь, который умеет считать
64-битный конь, который умеет считать64-битный конь, который умеет считать
64-битный конь, который умеет считать
 
Большой брат помогает тебе
Большой брат помогает тебеБольшой брат помогает тебе
Большой брат помогает тебе
 
Разработка статического анализатора кода для обнаружения ошибок переноса прог...
Разработка статического анализатора кода для обнаружения ошибок переноса прог...Разработка статического анализатора кода для обнаружения ошибок переноса прог...
Разработка статического анализатора кода для обнаружения ошибок переноса прог...
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
Step cpp0201
Step cpp0201Step cpp0201
Step cpp0201
 
20 ловушек переноса Си++ - кода на 64-битную платформу
20 ловушек переноса Си++ - кода на 64-битную платформу20 ловушек переноса Си++ - кода на 64-битную платформу
20 ловушек переноса Си++ - кода на 64-битную платформу
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложений
 
Разница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомРазница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментом
 
паскаль 10кл 14
паскаль 10кл 14паскаль 10кл 14
паскаль 10кл 14
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложений
 
Сравнение диагностических возможностей анализаторов при проверке 64-битного кода
Сравнение диагностических возможностей анализаторов при проверке 64-битного кодаСравнение диагностических возможностей анализаторов при проверке 64-битного кода
Сравнение диагностических возможностей анализаторов при проверке 64-битного кода
 
Intel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиIntel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибками
 

More from 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
 
Урок 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
 
Урок 15. Паттерн 7. Упаковка указателей
Урок 15. Паттерн 7. Упаковка указателейУрок 15. Паттерн 7. Упаковка указателей
Урок 15. Паттерн 7. Упаковка указателейTatyanazaxarova
 
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументовУрок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументов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
 

More from 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-битных ошибок
 
Урок 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-типы в объединениях
 
Урок 15. Паттерн 7. Упаковка указателей
Урок 15. Паттерн 7. Упаковка указателейУрок 15. Паттерн 7. Упаковка указателей
Урок 15. Паттерн 7. Упаковка указателей
 
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументовУрок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
 
Урок 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
 
Вечный вопрос измерения времени
Вечный вопрос измерения времениВечный вопрос измерения времени
Вечный вопрос измерения времени
 

Как стандарт C++0x поможет в борьбе с 64-битными ошибками

  • 1. Как стандарт C++0x поможет в борьбе с 64-битными ошибками Автор: Андрей Карпов Дата: 28.02.2010 Программисты видят в стандарте C++0x возможность использовать лямбда-функции и прочие мало понятные для меня сущности :). Я увидел в нем удобные средства, позволяющие исключить многие 64-битные ошибки. Рассмотрим функцию, которая возвращает true, если хотя бы в одной из строк встречается последовательность "ABC". typedef vector<string> ArrayOfStrings; bool Find_Incorrect(const ArrayOfStrings &arrStr) { ArrayOfStrings::const_iterator it; for (it = arrStr.begin(); it != arrStr.end(); ++it) { unsigned n = it->find("ABC"); if (n != string::npos) return true; } return false; }; Эта функция корректно ведет себя при компиляции Win32 версии и дает сбой при сборке в режиме Win64. Рассмотрим пример использования функции: #ifdef IS_64 const char WinXX[] = "Win64"; #else const char WinXX[] = "Win32"; #endif int _tmain(int argc, _TCHAR* argv[]) {
  • 2. ArrayOfStrings array; array.push_back(string("123456")); array.push_back(string("QWERTY")); if (Find_Incorrect(array)) printf("Find_Incorrect (%s): ERROR!n", WinXX); else printf("Find_Incorrect (%s): OK!n", WinXX); return 0; } Find_Incorrect (Win32): OK! Find_Incorrect (Win64): ERROR! Ошибка заключается в использовании типа unsigned для переменной "n", хотя функция find() возвращает значение типа string::size_type. В 32-битной программе тип string::size_type и unsigned совпадают, и мы получаем верный результат. В 64-битной программе string::size_type и unsigned перестают совпадать. Так как подстрока не находится, функция find() возвращает значение string::npos, которое равно 0xFFFFFFFFFFFFFFFFui64. Это значение урезается до величины 0xFFFFFFFFu и помещается в 32- битную переменную. В результате условие 0xFFFFFFFFu == 0xFFFFFFFFFFFFFFFFui64 всегда false и мы получаем сообщение "Find_Incorrect (Win64): ERROR!". Исправим код, используя тип string::size_type. bool Find_Correct(const ArrayOfStrings &arrStr) { ArrayOfStrings::const_iterator it; for (it = arrStr.begin(); it != arrStr.end(); ++it) { string::size_type n = it->find("ABC"); if (n != string::npos) return true; } return false; };
  • 3. Теперь код работает корректно, хотя постоянно писать тип string::size_type длинно и не красиво. Можно переопределить его через typedef, но все равно это выглядит как-то сложно. Используя C++0x, мы можем сделать код гораздо изящней надежней. Для этого мы воспользуемся ключевым словом auto. Ранее auto означало, что переменная создается на стеке, и подразумевалось неявно в случае, если вы не указали что-либо другое, например register. Теперь тип переменной, объявленной как auto, определяется компилятором самостоятельно на основе того, чем эта переменная инициализируется. Следует заметить, что auto-переменная не сможет хранить значения разных типов в течение одного запуска программы. Си++ остается статически типизированным языком, и указание auto лишь говорит компилятору самостоятельно позаботиться об определении типа: после инициализации сменить тип переменной будет уже нельзя. Воспользуемся ключевым словом auto в нашем коде. Проект был создан в Visual Studio 2005, а поддержка C++0x реализована только начиная с версии Visual Studio 2010. Поэтому для компиляции я воспользовался компилятором Intel C++, входящим в состав Intel Parallel Studio 11.1 и поддерживающим стандарт C++0x. Поддержка C++0x включается в разделе Language и носит название "Enable C++0x Support". Как видно из рисунка 1, эта опция является Intel Specific. Рисунок 1 - Поддержка стандарта C++0x Модифицированный код выглядит следующим образом: bool Find_Cpp0X(const ArrayOfStrings &arrStr) { for (auto it = arrStr.begin(); it != arrStr.end(); ++it)
  • 4. { auto n = it->find("ABC"); if (n != string::npos) return true; } return false; }; Обратите внимание, как теперь объявлена переменная "n". Неправда ли, элегантно и устраняет от ряд ошибок, в том числе и 64-битных. Переменная "n" будет иметь ровно тот тип, который возвращает функция find(), то-есть string::size_type. Также обратите внимание, что исчезла строчка объявления итератора: ArrayOfStrings::const_iterator it; Объявлять переменную it внутри цикла было некрасиво (длинно). И поэтому объявление было вынесено отдельно. Теперь проблемы длины нет: for (auto it = arrStr.begin(); ......) Рассмотрим еще одно ключевое слово - decltype. Оно позволяет задать тип на основании типа другой переменной. Если бы в нашем коде, мы должны были объявить все переменные заранее, то можно было бы написать так: bool Find_Cpp0X_2(const ArrayOfStrings &arrStr) { decltype(arrStr.begin()) it; decltype(it->find("")) n; for (it = arrStr.begin(); it != arrStr.end(); ++it) { n = it->find("ABC"); if (n != string::npos) return true; } return false; }; Конечно, в данном случае это бессмысленно, но может быть весьма удобно во многих ситуациях.
  • 5. К сожалению (или к счастью для нас :-), хотя новый стандарт облегчает написание безопасного 64- битного кода, он не помогает в устранении уже существующих дефектов. Для того чтобы использовать memsize-тип или auto для устранений ошибки, эту ошибку нужно в начале обнаружить. Следовательно, актуальность использования инструмента Viva64 с приходом стандарта C++0x не изменится. P.S. Проект с кодом можно скачать здесь.