long l = (long)(pMyObject); warning C4312 ???
От: Чили Россия  
Дата: 21.05.04 04:33
Оценка:
У меня следующий код:
CMyObject *pObject;
...
long l = (long)pObject;
Здесь: warning C4312, conversion from 'long' to 'CMyObject *' of greater size
В Visual Studio 6.0 было без проблем, а в VS.NET — warnig !
Помогите избавится ! (Мне кажется что то в настройках, но найти не могу)
Re: long l = (long)(pMyObject); warning C4312 ???
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 21.05.04 04:47
Оценка: 49 (3) +1
Здравствуйте, Чили, Вы писали:

Ч>У меня следующий код:

Ч>CMyObject *pObject;
Ч>...
Ч>long l = (long)pObject;
Ч>Здесь: warning C4312, conversion from 'long' to 'CMyObject *' of greater size
Ч>В Visual Studio 6.0 было без проблем, а в VS.NET — warnig !
Ч>Помогите избавится ! (Мне кажется что то в настройках, но найти не могу)

Начиная с 7-ой студии M$ начали приучать программистов к грядущему приходу Win64, где размер указателей будет не 32 разряда (4 байта), а 64. Поэтому указатель уже не будет помещаться в переменную типа long. Приучают они очень просто — уже сейчас при попытке присвоить указатель в переменную типа long вылетает предупреждение. Эта фича, именуемая "Detect 64-bit Portability Issues", по-умолчанию включена ключом компилятора /Wp64. Если раздражает, можно выключить, но настоятельно не рекомендую — пусть раздражает, по крайней мере будете знать из-за чего ваша программа рухнет на Longhorn`е
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re: long l = (long)(pMyObject); warning C4312 ???
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 21.05.04 04:50
Оценка: +1
Здравствуйте, Чили, Вы писали:

Ч>Здесь: warning C4312, conversion from 'long' to 'CMyObject *' of greater size

Ч>В Visual Studio 6.0 было без проблем, а в VS.NET — warnig !
Ч>Помогите избавится ! (Мне кажется что то в настройках, но найти не могу)

Если он так тебе не нравиться :
#pragma warning(disable:4312)


В настройках — Configuration properties / C/C++ / General / Warning Level можно поставить другой.

А если серьезно. То здесь лучше использовать такую конструкцию:

#ifdef _MSC_VER
    #pragma warning(push)
    // 'variable' : pointer truncation from 'type' to 'type'
    #pragma warning(disable: 4311)
    // 'variable' : conversion from 'type' to 'type' of greater size
    #pragma warning(disable: 4312)
#endif

/// Safe reinterpret cast.
template<class T1, class T2>
T1 safe_reinterpret_cast(const T2 &X)
{
    BOOST_STATIC_ASSERT(sizeof(T1)==sizeof(T2));
    return reinterpret_cast<T1>(X);
}

#ifdef _MSC_VER
    #pragma warning(pop)
#endif

...

CMyObject *pObject;
...
long l = safe_reinterpret_cast<long>(pObject);


И здесь советую посмотреть: http://www.rsdn.ru/Forum/Message.aspx?mid=620622
Автор:
Дата: 27.04.04
.
getboost.codeplex.com
citylizard.codeplex.com
Re[2]: long l = (long)(pMyObject); warning C4312 ???
От: Андрей Россия  
Дата: 21.05.04 05:37
Оценка:
Здравствуйте, sergey_shandar, Вы писали:

skip

И нафига все эти извраты?

CMyObject* pObject;

...

LONG_PTR p = reinterpret_cast<LONG_PTR>(pObject);
Re[3]: long l = (long)(pMyObject); warning C4312 ???
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 21.05.04 06:42
Оценка:
Здравствуйте, Андрей, Вы писали:

А>И нафига все эти извраты?


Такие навороты нужны, потому что:
1) reinterpret_cast<LONG_PTR> все равно не спасет от варнинга (даже если размеры типов совпадают).
2) reinterpret_cast не очень безопасен на VC, например, на такое reinterpret_cast<char>(pObject) даже варнингом не заикнеться.
getboost.codeplex.com
citylizard.codeplex.com
Re[4]: long l = (long)(pMyObject); warning C4312 ???
От: Андрей Россия  
Дата: 21.05.04 06:57
Оценка: 1 (1)
Здравствуйте, sergey_shandar, Вы писали:

_>Здравствуйте, Андрей, Вы писали:


А>>И нафига все эти извраты?


_>Такие навороты нужны, потому что:

_>1) reinterpret_cast<LONG_PTR> все равно не спасет от варнинга (даже если размеры типов совпадают).

Вот здесь ты неправ — никакого варнинга не будет.

_>2) reinterpret_cast не очень безопасен на VC, например, на такое reinterpret_cast<char>(pObject) даже варнингом не заикнеться.


А здесь ты прав, НО: reinterpret_cast опасен в любой реализации C++, а не только в VC. Такова уж его природа
Re[5]: long l = (long)(pMyObject); warning C4312 ???
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 21.05.04 07:13
Оценка:
Здравствуйте, Андрей, Вы писали:

_>>Такие навороты нужны, потому что:

_>>1) reinterpret_cast<LONG_PTR> все равно не спасет от варнинга (даже если размеры типов совпадают).

А>Вот здесь ты неправ — никакого варнинга не будет.


Простите, был не прав.... Правда я все равно буду пользоваться safe_reinterpret_cast , хотя бы из за пункта 2. И не нравиться мне вся эта магия с объявлениями LONG_PTR:
#ifndef _WIN64
typedef __w64 long LONG_PTR;
#endif

__w64 только для того что бы варнинг не выдавался . Хотя я понимаю этих шаманов из MS, совместимость, blah blah blah...
getboost.codeplex.com
citylizard.codeplex.com
Re: long l = (long)(pMyObject); warning C4312 ???
От: Братец Кролик Россия  
Дата: 21.05.04 07:16
Оценка:
Здравствуйте, Чили, Вы писали:

Ч>У меня следующий код:

Ч>CMyObject *pObject;
Ч>...
Ч>long l = (long)pObject;
Ч>Здесь: warning C4312, conversion from 'long' to 'CMyObject *' of greater size
Ч>В Visual Studio 6.0 было без проблем, а в VS.NET — warnig !
Ч>Помогите избавится ! (Мне кажется что то в настройках, но найти не могу)


long l = (long)(LONG_PTR)pObject;

но не сработает в 6-й студии, так как она не знает LONG_PTR
Re[5]: long l = (long)(pMyObject); warning C4312 ???
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 21.05.04 07:18
Оценка:
Здравствуйте, Андрей, Вы писали:

_>>2) reinterpret_cast не очень безопасен на VC, например, на такое reinterpret_cast<char>(pObject) даже варнингом не заикнеться.


А>А здесь ты прав, НО: reinterpret_cast опасен в любой реализации C++, а не только в VC. Такова уж его природа


За всех не надо, comeau и GCC выдают ошибки.
getboost.codeplex.com
citylizard.codeplex.com
Re: long l = (long)(pMyObject); warning C4312 ???
От: Аноним  
Дата: 21.05.04 07:45
Оценка: 3 (1) +1
Здравствуйте, Чили, Вы писали:

Ч>У меня следующий код:

Ч>CMyObject *pObject;
Ч>...
Ч>long l = (long)pObject;
Ч>Здесь: warning C4312, conversion from 'long' to 'CMyObject *' of greater size
Ч>В Visual Studio 6.0 было без проблем, а в VS.NET — warnig !
Ч>Помогите избавится ! (Мне кажется что то в настройках, но найти не могу)

а не проще заюзать void*?
Re[5]: long l = (long)(pMyObject); warning C4312 ???
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 24.05.04 02:25
Оценка:
Здравствуйте, Андрей, Вы писали:

_>>1) reinterpret_cast<LONG_PTR> все равно не спасет от варнинга (даже если размеры типов совпадают).


А>Вот здесь ты неправ — никакого варнинга не будет.


Вот, вспомнил откуда у меня пошло такое заблуждение. Дело в том что если даже использовать LONG_PTR, то, например в таком случае:
SetWindowLongPtr(Wnd, 0, reinterpret_cast<LONG_PTR>(pObject));


Все равно выдаеться предупреждение, 4244: 'argument' : conversion from 'LONG_PTR' to 'LONG', possible loss data.

Так как SetWindowLongPtr объявлен в winuser.h для 32ух битной платформы как
#define SetWindowLongPtr SetWindowLong



Правда, если Вы используете ATL, то в atlwin.h есть нормальное объявление SetWindowLongPtr:
inline LONG_PTR SetWindowLongPtrA( HWND hWnd, int nIndex, LONG_PTR dwNewLong )
{
    return( ::SetWindowLongA( hWnd, nIndex, LONG( dwNewLong ) ) );
}


Так что safe_reinterpret_cast и только он.
getboost.codeplex.com
citylizard.codeplex.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.