int l = strlen (s);
предупреждение C4244: '=': преобразование из '__w64 int' в 'int', возможная потеря данных
Мне нужно заменить strlen встроенной функцией int l = new_strlen (s);
Но как мне переносимо получить результат strlen в int без предупреждения и без использования прагм? Я могу гарантировать, что в моей строке не более 2 миллиардов символов!
Все очевидные вещи, такие как reinterpret_cast, static_cast, также вызывают ошибки или предупреждения.
Обновлено: Аргх. приведение в стиле c: (int) действительно работает. Я был убежден, что это не так.





Бросьте это:
int i = (int) strlen(s);
Или не используйте подписанный int. Возвращаемое значение strlen () беззнаковое.
const char * str = "Hello";
int len = static_cast< int >( strlen( str ) );
return len;
Этот код не выдает никаких ошибок или предупреждений даже на уровне предупреждения 4 (VS2005). Какой компилятор вы используете?
I need to replace strlen with an inline function int l = new_strlen(s);
Обратите внимание, что в VC++ strlen автоматически заменяется встроенной версией при создании оптимизированной версии.
Также обратите внимание, что / Wp64 устарел в VS2008; видимо это ненадежный.
/ Wp64, вероятно, является пустой тратой времени для 32-битных сборок, но он действительно полезен для 64-битных сборок, поскольку позволяет выводить предупреждения, которые вы не получили бы в противном случае.
Если вы строите для x64, вы все равно получите предупреждения. / Wp64 предназначен для 32-разрядной сборки, но вы хотите, чтобы вас предупредили о потенциальных проблемах с 64-разрядной версией. Но, тем не менее, он сломан: blogs.msdn.com/vcblog/archive/2007/08/10/…
Я понимаю, что / Wp64 был разработан, чтобы выдавать предупреждения о совместимости с 64-разрядной версией в 32-разрядных сборках. Однако, если я открою командную строку кросс-инструментов Visual C++ x64 и запускаю cl.exe с / Wp64 и без него, я получаю предупреждения о неверном указателе <=> целочисленных приведениях только тогда, когда я указываю / Wp64 или / Wall, а не / W4.
В случаях, когда у вас действительно есть веская причина для усечения указателей, вы можете заставить /Wp64 принять ваш код, сложив несколько приведений. Эти случаи редки. Один пример: драйверы устройств для устаревших устройств PCI, выполняющих DMA, с выделенной памятью ниже предела 4 ГБ. (Примечание: есть также макрос PtrToUlong(), который прояснит ваши намерения.)
Это одиночное приведение выдаст предупреждение:
const char* p = "abc";
unsigned int u = reinterpret_cast<unsigned int>(p);
wp64.cpp (10): предупреждение C4311: 'reinterpret_cast': усечение указателя с 'const char *' до 'unsigned int'
Но эти составные броски не будут:
const char* p = "abc";
unsigned int u = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p));
Я не могу воспроизвести ваше предупреждение с версией компилятора, который я установил, но подозреваю, что ваша проблема связана с тем, что вы преобразуете 64-битный беззнаковый size_t в 32-битный подписанный int.
Возможно, вам повезет больше, если вы сложите несколько приведений для преобразования 64-битного в 32-битное и преобразования без знака в знак:
const char* s = "abcdef";
int l = static_cast<int>(static_cast<intptr_t>(strlen(s)));
Кроме того, если вы собираете двоичные файлы как x86, так и x64, вы можете отключить /Wp64 для своих 32-разрядных сборок, чтобы вам не приходилось аннотировать какие-либо типы с помощью __w64. Использование /Wp64 для ваших 64-битных сборок приведет к обнаружению множества ошибок.
если вы понимаете предупреждение, вполне допустимо отключить предупреждение вместо того, чтобы складывать приведение или какой-либо другой запутанный беспорядок в качестве обходного пути.
A pragma warning directive with the suppress specifier suppresses the warning only for the line of code that immediately follows the #pragma warning statement.
#pragma warning( suppress : 6001 ) arr[i+1] = 0; // Warning 6001 is suppressed j++; // Warning 6001 is reported
В этом случае ничего. Это просто создаст временный int и инициализирует его значением, возвращаемым из strlen (). В других случаях приведение типов в стиле C может быть опасным, если есть более безопасные альтернативы, такие как static_cast или dynamic_cast.