tags:

views:

528

answers:

7

int l = strlen(s);

warning C4244: '=' : conversion from '__w64 int' to 'int', possible loss of data

I need to replace strlen with an inline function int l = new_strlen(s);

But how do I portably get the result of the strlen into the int without a warning, and without using pragmas? I can guarantee there aren't more than 2 billion characters in my string!

All the obvious things like reinterpret_cast, static_cast also produce errors or warnings.

EDIT: Argh. a c-style cast: (int) does work. I had been convinced that it did not.

+1  A: 

Cast it:

int i = (int) strlen(s);
John Dibling
What's wrong with the C++ cast operators?
Martin York
In this case, nothing. This will simply construct a temporary int and initialize it with the value returned from strlen(). In other cases C-style casts can be dangerous, where there are safer alternatives such as static_cast or dynamic_cast.
John Dibling
A: 

Or don't use a signed int. The return value of strlen() is unsigned.

Andy Lester
+4  A: 
const char * str = "Hello";
int len = static_cast< int >( strlen( str ) );
return len;

This code doesn't produce any error or warning even on Warning Level 4 (VS2005). What compiler do you use?

Igor Semenov
A: 

I need to replace strlen with an inline function int l = new_strlen(s);

Note that in VC++, strlen is automatically replaced by a inline version when you build an optimized version.

James Curran
+3  A: 

Also note that /Wp64 is deprecated in VS2008; apparently it's not reliable.

Roger Lipscombe
/Wp64 is probably a waste of time for 32-bit builds, but it's really helpful for 64-bit builds because it enables warnings you would not get otherwise.
bk1e
If you're building for x64, you'll get the warnings anyway. /Wp64 is for when you're building for 32-bit, but want to be warned about potential 64-bit problems. But, regardless, it's broken: http://blogs.msdn.com/vcblog/archive/2007/08/10/the-future-of-the-c-language.aspx#4421146
Roger Lipscombe
I understand that /Wp64 was designed to give 64-bit compatibility warnings in 32-bit builds. However, if I open Visual C++ x64 cross tools command prompt and run cl.exe with and without /Wp64, I only get warnings about bad pointer<=>integer casts when I specify /Wp64 or /Wall, not /W4.
bk1e
+1  A: 

In cases where you really have a good reason to truncate pointers, you can make /Wp64 accept your code by stacking multiple casts. These cases are rare. One example: device drivers for legacy PCI devices, doing DMA, with memory allocated below the 4GB limit. (Note: there is also the PtrToUlong() macro, which will make your intentions clearer.)

This single cast will produce a warning:

const char* p = "abc";
unsigned int u = reinterpret_cast<unsigned int>(p);

wp64.cpp(10) : warning C4311: 'reinterpret_cast' : pointer truncation from 'const char *' to 'unsigned int'

But these stacked casts will not:

const char* p = "abc";
unsigned int u = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p));

I'm not able to reproduce your warning with the version of the compiler that I have installed, but I suspect that your problem is related to the fact that you're casting a 64-bit unsigned size_t into a 32-bit signed int.

You might have better luck if you stack multiple casts to do the 64-bit to 32-bit conversion and the unsigned-to-signed conversion:

const char* s = "abcdef";
int l = static_cast<int>(static_cast<intptr_t>(strlen(s)));

Also, if you build both x86 and x64 binaries, you can disable /Wp64 for your 32-bit builds so that you don't have to annotate any types with __w64. Using /Wp64 for your 64-bit builds will catch a lot of bugs.

bk1e
+1  A: 

if you understand a warning, its perfectly acceptable to disable the warning instead of stacking casts or whatever other confusing mess as a workaround.

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

(msvc specific)

Dustin Getz