size_t в unsigned int (из функции API) - PullRequest
8 голосов
/ 19 апреля 2011

Я использую Oracle API для доступа к базе данных, и у этого API есть функция readBuffer(char * buffer, unsigned int size);, в которую я не могу вносить какие-либо изменения.

У меня есть класс, который использует этот API и подпись моей функциив настоящее время принимает std::string и unsigned int для размера, проблема в том, что когда я передаю std::string.size() аргументу размера моей функции, я получаю предупреждение от моего компилятора, что преобразование из size_t в unsigned intможет привести к потере данных.

Интересно, существует ли действительный способ для преобразования size_t в unsigned int, чтобы я мог передать его в свой API и не получить предупреждение от компилятора?

Я понимаю назначение size_t, и поиск в Google для этого преобразования приводит к большому количеству результатов, в которых говорится: "Измените функцию на аргумент size_t", но я НЕ МОГУТ * изменить сигнатуру моего API вэто дело.

Есть предложения?

Ответы [ 5 ]

18 голосов
/ 19 апреля 2011

Да, напишите вспомогательную функцию, которая проверит, является ли такое преобразование допустимым, и в противном случае выдаст исключение.Что-то вроде:

unsigned int convert( size_t what )
{
    if( what > UINT_MAX ) {
       throw SomeReasonableException();
    }
    return static_cast<unsigned int>( what );
}
5 голосов
/ 19 апреля 2011

Ну, сделай static_cast<unsigned int>(mystring.size()).

Причина в том, что std::size_t обычно имеет размер указателя, но есть 64-битные платформы, на которых int по-прежнему 32 бита. В этом случае единственной причиной потери данных может быть длина рассматриваемой строки более 2 ^ 32 байт.

Если вы знаете, что этого не произойдет, поместите assert где-нибудь, чтобы поймать этот случай, и static_cast, чтобы компилятор замолчал.

4 голосов
/ 19 апреля 2011
static_cast<unsigned int>(str.size());

Если вы хотите быть параноиком:

if (static_cast<unsigned int>(str.size()) != str.size()) 
  throw ...
1 голос
/ 19 апреля 2011

Здесь риск состоит в том, что size_t может быть больше (unsigned) int, и поэтому вы не можете безопасно конвертировать, если это так.

Например, возможно, что int - это 32 бита, а size_t - 64 бита. Я не знаю такой системы / конфигурации на макушке, но это может произойти.

Для большинства "разумных" систем оба будут иметь размер не менее 32 бит, и единственная строка 4 ГБ все еще (возможно) вряд ли будет иметь место.

Так что тогда вы могли бы просто разыграть, это было бы допустимо, но не было бы "безопасно" для всех возможных систем и угловых случаев.

1 голос
/ 19 апреля 2011

Вы можете форсировать преобразование с помощью конструкции

static_cast<unsigned int>(your_variable)

.Конечно, правильный путь для API - принять size_t ...

...