Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > comparison between size_t and ptr_diff_t


Автор: Gwendolen 17.12.2011, 14:02
Мне надо преобразовать массив байт в конкретный тип, при необзодимости заменив порядок байт.
Собственно с изменением порядка байт и преобразованием проблемы нет, она возникла при проверке влезет ли в конкретный тип пришедший диапазон байт:

Код

if(sizeof(T) > (last - first))
{
...
} else ...



Где last и first - итераторы .

Получается сравнение знакового ptr_diff_t и беззнакового size_t, на что компилятор, собственно, и ругается:
Код

comparison between signed and unsigned integer expressions


Как правильно исправить код для того чтобы убрать это предупреждение?

Автор: boostcoder 17.12.2011, 14:12
Цитата(Gwendolen @  17.12.2011,  14:02 Найти цитируемый пост)
(last - first)

арифметические операции над указателями/итераторами, дают знаковый тип. sizeof() возвращает беззнаковый.
способ решения - какой-то из операндов привести к типу второго.

Автор: Gwendolen 17.12.2011, 14:34
Цитата(boostcoder @ 17.12.2011,  14:12)
арифметические операции над указателями/итераторами, дают знаковый тип. sizeof() возвращает беззнаковый.

Об этом я и написал, вопрос в том к какому типу приводить(склоняюсь приводить к знаковому). На всех ли платформах корректно преобразование  size_t к ptr_diff_t?

Автор: rumit7 17.12.2011, 15:23
Цитата(Gwendolen @ 17.12.2011,  14:02)
Мне надо преобразовать массив байт в конкретный тип, при необзодимости заменив порядок байт.
Собственно с изменением порядка байт и преобразованием проблемы нет, она возникла при проверке влезет ли в конкретный тип пришедший диапазон байт:

Код

if(sizeof(T) > (last - first))
{
...
} else ...



Где last и first - итераторы .

...

Как правильно исправить код для того чтобы убрать это предупреждение?

Может попробовать так?!

Код

if(first + sizeof(T) > last)
{
...
} else ...


Автор: Gwendolen 17.12.2011, 16:43
Цитата(rumit7 @ 17.12.2011,  15:23)
Может попробовать так?!

Код

if(first + sizeof(T) > last)
{
...
} else ...


Некрасиво, неочевидно, что именно проверяется.

Я думал про другой вариант:

Код

if((last - first) - static_cast<std::ptrdiff_t>(sizeof(T)) < 0)
{
...
} else ...



Похоже проще просто кастануть тип, ибо размер контейнера никогда не будет соизмерим с размером почти всей доступной памяти, так что можно и не бояться приводить беззнаковый к знаковому(size_t и ptrdiff_t имеют одинаковый размер в байтах):

Код

if((last - first)  < static_cast<std::ptrdiff_t>(sizeof(T)) )
{
...
} else ...


Автор: rumit7 17.12.2011, 16:57
Цитата(Gwendolen @ 17.12.2011,  16:43)
Цитата(rumit7 @ 17.12.2011,  15:23)
Может попробовать так?!

Код

if(first + sizeof(T) > last)
{
...
} else ...


Некрасиво, неочевидно, что именно проверяется.


Тогда можно так:
Код

template<class T>
bool can_store(iterator begin, iterator end)
{
    return (first + sizeof(T) >= last);
}

// используется так
//
if( can_store<int>(first, last) )
{
    ...
}else{
    ...
}


Конечно на вкус и цвет, как говорится.. но вот со static_cast, код совсем монстрообразный какой-то, хотя может мне так кажется.

Update: Все-таки для данного решения нужно указать, что "iterator" должен относиться к http://www.cplusplus.com/reference/std/iterator/, так так именно они поддерживают операцию ">=".

Автор: volatile 18.12.2011, 01:08
Код

size_t size = last - first;
if(sizeof(T) > size)
{ ...

 smile

Добавлено через 6 минут и 12 секунд
или даже так:
size_t size = abs(last - first);
чтоб случайно не перепутать местами.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)