Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Мне интересно попробовать плагин на:
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
Поиск явного приведения указателя к 32-…

Поиск явного приведения указателя к 32-битному типу

19 Окт 2010

В компиляторе Visual Studio C++ имеется warning C4311 ('variable' : pointer truncation from 'type' to 'type') предназначенный для выявления ошибок приведения указателя к 32-битным типам данных. В Intel C++ этому предупреждению соответствует warning #810.

Пример обнаруживаемого дефекта:

void *ptr = x;
int y = (int)ptr;

В Win64 размер указателя стал 64-битным, а размер int остался по-прежнему 32 бита. Явное приведение типа обрежет значение указателя, что приведет к ошибке, если указатель ссылается на объект находящимся за пределами младших 4 Гбайт памяти (0x00000000FFFFFFFF).

Подобные ошибки коварны тем, что могут проявляться нерегулярно. Однако их можно легко обнаружить, просмотрев все предупреждения компилятора с номером C4311. Но вот с использованием самой этой проверки есть некоторый неприятный нюанс.

Если вы просто создадите 64-битный проект в Visual Studio 2008/2010, и напишите приведенный выше код, то вы не получите предупреждения C4311. Разберемся в причинах этой неожиданной ситуации.

В Visual Studio 2003/2005 имеется ключ /Wp64 предназначенный для выявления некоторых проблем, с которыми столкнется программист при сборке своего кода в 64-битном варианте. К группе этих предупреждений относится и предупреждение C4311. Если, создать проект в Visual Studio 2005, то даже в 32-битной конфигурации для строки int y = (int)ptr; будет сгенерировано предупреждение:

warning C4311: 'type cast' : 
pointer truncation from 'void *' to 'int'.

Ключ /Wp64 был предназначен, чтобы хоть как-то подготовить приложения к 64-битной платформе без необходимости создания 64-битной конфигурации. Однако, время "подготавливаться" прошло. Начиная с Visual Studio 2005, имеется 64-битный компилятор. Если есть желание поддерживать Win32 и Win64 платформу, то необходимо иметь две конфигурации проекта. В конфигурации x64 использовать ключ /Wp64 бессмысленно, и именно поэтому в Visual Studio 2008/2010 он объявлен устаревшим.

Все было бы хорошо, но как мне кажется разработчики Visual Studio допустили логическую ошибку. Если вы создадите новый проект в Visual Studio 2008/2010 или конвертируете старый проект в новый, то ключ /Wp64 будет не установлен. Это правильно. Если даже специально в "Additional Options" проекта прописать /Wp64, то будет выдано сообщение:

Command line warning D9035: 
option 'Wp64' has been deprecated 
and will be removed in a future release.

Юмор ситуации в том, что такие предупреждения как C4311, C4312, C4313 почему-то по-прежнему связаны с ключом /Wp64. И если его нет, то и нет этих предупреждений, хотя уровень их опасности Level 1.

Эти предупреждения вернутся, если включить /Wp64 и получить предупреждения D9035 об устаревшей опции. Другой вариант - включить /Wall. Сообщения будут выданы, но это путь, как вы понимаете, только для отважных. Видимо наиболее разумным вариантом является использование #pragma warning в stdafx.h.

Теперь перейдем к Intel C++. Начиная изучение вопроса, я ожидал, что в своем поведении относительно /Wp64 он эквивалентен Visual C++. Оказалось, что у него все по-своему. Ошибку приведения вида int y = (int)ptr; он обнаружил и без ключа /Wp64, выдав warning #810. А вот warning #967 (эквивалентный C4312) уже требует /Wp64. Получается, что в компиляторе Intel C++ также есть набор предупреждений связанный с /Wp64, но сам этот набор другой. Поскольку исторически сложилось, что с документацией по экзотическим особенностям Intel C++ туго, то я не нашел что именно включает /Wp64.

После всего этого потока мыслей у читателя может возникнуть вопрос:

А в чем все-таки заковырка то? Прошу еще раз кратко.

Ответ. Если вы имеете проект для Visual Studio 2008/2010 и создадите 64-битную конфигурацию, то вы не увидите предупреждения для таких банальных ошибок как:

void *ptr = x;
int y = (int)ptr; // C4311

int i = x;
return (void*)i; // C4312

int * pI = 0;
printf("%d", pI); // C4313

И видимо некоторых других. Собирая этот же проект с помощью Intel C++, вы не увидите другой набор ошибок.

Чтобы получить все эти благотворные предупреждения вы должны явно самостоятельно включить их! Это не сложно сделать, при условии, что вы знаете про это. Я вот долгое время не знал, хотя интересуюсь тематикой разработки 64-битных приложений.

Подчеркну, что победа над этими предупреждениями вовсе не означает корректность 64-битной программы. Это только означает, что были исправлены наиболее очевидные дефекты. Так сказать "кто не спрятался, я не виноват". А вот для обнаружения "тех, кто спрятался" в большом проекте есть смысл использовать специализированные инструменты (Viva64).

Я конечно не первый заметил эту недоделку касательно 64-битных предупреждений. Совсем недавно здесь оставили комментарий на эту тему. Обратите внимание, что критика совсем свежая.

Из всего этого я могу сделать вывод, что люди только начинают интересоваться созданием Win64-приложений. Эту фразу я писал год назад, и сейчас опять повторил ее. Это очень странно. Я не верю, что можно разрабатывать нормальные программы, не интересуясь даже тем, где указатель запихивается в int. Отсутствие массовых обсуждений в интернете подобных вопросов меня крайне смущает. Я не понимаю, как устроен мир.

Последние статьи:

Опрос:

Популярные статьи по теме
Простая ошибка при кодировании - не значит нестрашная ошибка

Дата: 19 Апр 2017

Автор: Андрей Карпов

Популяризируя статический анализатор кода PVS-Studio, мы обычно пишем статьи для программистов. Однако, на некоторые вещи программисты смотрят одностороннее. Именно поэтому и существуют менеджеры про…
Как обнаружить переполнение 32-битных переменных в длинных циклах в 64-битной программе?

Дата: 22 Мар 2016

Автор: Андрей Карпов

Одна из проблем, с которой сталкиваются разработчики 64-битных приложений, это переполнение 32-битных переменных в очень длинных циклах. С этой задачей хорошо справляется анализатор кода PVS-Studio (…
64-битный код в 2015 году: что нового в диагностике возможных проблем?

Дата: 21 Май 2015

Автор: Сергей Васильев

64-битные ошибки достаточно тяжело обнаружить, так как они сродни бомбе замедленного действия: могут дать о себе знать далеко не сразу. Статический анализатор PVS-Studio облегчает задачу поиска и исп…
C++11 и 64-битные ошибки

Дата: 29 Апр 2014

Автор: Андрей Карпов

64-битные компьютеры давно и успешно используются. Большинство приложений стали 64-битными. Это позволяет им использовать больший объем памяти, а также получить прирост производительности за счёт арх…
Отличие %p от %x

Дата: 05 Апр 2013

Автор: Андрей Карпов

В функциях семейства printf существуют спецификаторы типа "%p" и "%x".

Комментарии (0)

Следующие комментарии
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо