std::vector<unsigned int> vec;
unsigned int b = *(vec.begin());
I get a warning at the assignment of b of type:
warning C4267: 'initializing' : conversion from 'size_t'
to 'unsigned int', possible loss of data
It looks like somehow the compiler is
reinterpereting "unsigned int" into "size_t". I don't get
this error with any other types, just unsigned int. I
disabled the warning and it seems to work ok so far, but
it would be nice if someone could verify whether or not
this is a bug and whether or not I should be worried.
-tom
If your vector is empty, you are in the land of undefined
behavior.
True, but I don't think that is relevant to the warning he gets.
Ken
Just tried it on VC.NET 2003 - compiles with no errors and no warnings
for me. I've tried with /W4, with or without /Za, with or without /Wp64.
Can you show the command line you compile with?
--
With best wishes,
Igor Tandetnik
"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken
>It seems like there's some kind of bug with the STL
>implementation on VS.NET 2003. A friend said he tried
>this same code in VS6 SP5 and it didn't produce any
>warnings, which is odd. Anyway, if I do this:
>
>std::vector<unsigned int> vec;
>unsigned int b = *(vec.begin());
>
>I get a warning at the assignment of b of type:
>warning C4267: 'initializing' : conversion from 'size_t'
>to 'unsigned int', possible loss of data
I can't reproduce this warning.
>It looks like somehow the compiler is
>reinterpereting "unsigned int" into "size_t". I don't get
>this error with any other types, just unsigned int. I
>disabled the warning and it seems to work ok so far, but
>it would be nice if someone could verify whether or not
>this is a bug and whether or not I should be worried.
This program generated no errors or warnings for me on VS.NET 2003
with warning level 4 (the highest).
#include <vector>
#include <iostream>
int main()
{
std::vector<unsigned int> vec(1);
unsigned int b = *(vec.begin());
std::cout << b << '\n';
}
Can you post a short complete program that gives the warning?
Tom
#include <vector>
#include <map>
#include <windows.h>
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR
strCmdLine, INT )
{
std::multimap<size_t, int> somemap;
std::vector<unsigned int> vec;
unsigned int b = vec.front();
return 0;
}
>.
>
-tom
>.
>
warning C4189: 'b' : local variable is initialized but not referenced
if compiled as a console app. If I compile this exact code, I get a
couple more:
warning C4100: 'strCmdLine' : unreferenced formal parameter
warning C4100: 'hInst' : unreferenced formal parameter
Nothing unexpected.
--
With best wishes,
Igor Tandetnik
"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken
<anon...@discussions.microsoft.com> wrote in message
news:06fa01c3a980$4ad559b0$a301...@phx.gbl...
We get this as well. But it only happens with some of our modules despite
the fact that we are using /W4 and same compiler and linker options.
I will try and pin it down.
Stephen Howe
>Thank you for the responses. I looked into it, and you
>are both right, it does compile alone. The error seemed
>to be coming, oddly enough, from an unrelated multimap
>using size_t instantiated in the same project in a
>different file. This code will give the warning with a
>standard Win32 project setup:
>
>#include <vector>
>#include <map>
>#include <windows.h>
>
>INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR
>strCmdLine, INT )
>{
> std::multimap<size_t, int> somemap;
> std::vector<unsigned int> vec;
> unsigned int b = vec.front();
>
> return 0;
>}
Confirmed, I get it with W4 with this console program:
#include <vector>
#include <map>
int main()
{
std::map<size_t, int> somemap;
std::vector<unsigned int> vec(1);
unsigned int b = vec[0]; //<== line 8
}
c:\Dev\test\dotnettest\dotnettest\dotnettest.cpp(8): warning C4267:
'initializing' : conversion from 'size_t' to 'unsigned int', possible
loss of data
c:\Dev\test\dotnettest\dotnettest\dotnettest.cpp(8): warning C4189:
'b' : local variable is initialized but not referenced
The warning goes away if lines 6 or 8 are commented out. Strange...
Tom
>>-----Original Message-----
>>Thank you for the responses. I looked into it, and you
>>are both right, it does compile alone. The error seemed
>>to be coming, oddly enough, from an unrelated multimap
>>using size_t instantiated in the same project in a
>>different file. This code will give the warning with a
>>standard Win32 project setup:
>>
>>#include <vector>
>>#include <map>
>>#include <windows.h>
>>
>>INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR
>>strCmdLine, INT )
>>{
>> std::multimap<size_t, int> somemap;
>> std::vector<unsigned int> vec;
>> unsigned int b = vec.front();
>>
>> return 0;
>>}
>>
>Forgot to sign in... that was me posting above. Also, the
>warning still comes up with just a Win32 console app, so
>it's not related to the windows.h header. And the error
>only happens after an actual instantiation of a multimap
>using size_t; including <map> or putting a typedef without
>instantiating don't cause the warning. Weird.
To avoid the problem, go into Project Settings | C/C++ | General and turn
off "Detect 64-bit portability issues". The type size_t widens to 64 bits in
Win64, hence the warning when compiling with this option. Here's a small
fragment which demonstrates the problem:
unsigned f(size_t x)
{
return x;
}
E>cl -c -W3 -Wp64 b.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
b.cpp
b.cpp(3) : warning C4267: 'return' : conversion from 'size_t' to 'unsigned
int', possible loss of data
*****
Note that I had to compile at -W3 or above in addition to using -Wp64 to get
the warning.
P.S. Not that I'm complaining or anything, but anyone know when size_t
became a built-in type? :)
--
Doug Harrison
Microsoft MVP - Visual C++
That's right, but the last statement above, the one causing the problem,
assigns unsigned to unsigned. size_t is only mentioned in a completely
unrelated statement.
-tom
>.
>
>"Doug Harrison [MVP]" <d...@mvps.org> wrote in message
>news:egl7rv8crvgra3qnc...@4ax.com...
>> >> std::multimap<size_t, int> somemap;
>> >> std::vector<unsigned int> vec;
>> >> unsigned int b = vec.front();
>>
>> To avoid the problem, go into Project Settings | C/C++ | General and
>turn
>> off "Detect 64-bit portability issues". The type size_t widens to 64
>bits in
>> Win64, hence the warning when compiling with this option.
>
>That's right, but the last statement above, the one causing the problem,
>assigns unsigned to unsigned. size_t is only mentioned in a completely
>unrelated statement.
Yep, that's weird. In any event, the workaround is the same.
This may shed some light:
**********
// Compile with cl -c -GX -W3 -Wp64 b.cpp
#include <list>
#include <map>
#include <set>
#include <vector>
template<class T>
struct X
{
};
void g()
{
// X<size_t> x;
// std::pair<const size_t, int> x;
// std::vector<size_t> x;
// std::list<size_t> x;
// std::set<size_t> x;
// std::map<size_t, int> x;
std::allocator<size_t> x;
}
unsigned f()
{
std::vector<unsigned> x(1);
return x.front();
}
**********
Neither the X<size_t> nor std::pair x declarations cause the spurious
warning. Enabling any one of the std::container x variables causes the
warning. What do all the containers have in common? std::allocator. It does
cause the warning. So anyone who wants to look into this further can
simplify it at least to this:
**********
#include <vector>
void g()
{
std::allocator<size_t> x;
}
unsigned f()
{
std::vector<unsigned> x(1);
return x.front();
}
E>cl -c -GX -W3 -Wp64 b.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
b.cpp
b.cpp(11) : warning C4267: 'return' : conversion from 'size_t' to 'unsigned
int' , possible loss of data
--
> Confirmed, I get it with W4 with this console program:
>
> #include <vector>
> #include <map>
>
> int main()
> {
> std::map<size_t, int> somemap;
> std::vector<unsigned int> vec(1);
> unsigned int b = vec[0]; //<== line 8
> }
>
> c:\Dev\test\dotnettest\dotnettest\dotnettest.cpp(8):
warning C4267:
> 'initializing' : conversion from 'size_t' to 'unsigned
int', possible
> loss of data
> c:\Dev\test\dotnettest\dotnettest\dotnettest.cpp(8):
warning C4189:
> 'b' : local variable is initialized but not referenced
>
> The warning goes away if lines 6 or 8 are commented out.
Strange...
>
> Tom
I get a warning with your code, but the following isn't
giving a warning for me (VC++ 7.1).
#include <vector>
#include <map>
int main()
{
std::map<size_t, int> somemap;
std::vector<unsigned int> vec(1);
vec.push_back(35);
unsigned int b = vec[0]; //<== line 8
return 0;
}
- -
Best regards, John E.
>Neither the X<size_t> nor std::pair x declarations cause the spurious
>warning. Enabling any one of the std::container x variables causes the
>warning. What do all the containers have in common? std::allocator. It does
>cause the warning. So anyone who wants to look into this further can
>simplify it at least to this:
>
>**********
>
>#include <vector>
>
>void g()
>{
> std::allocator<size_t> x;
>}
>
>unsigned f()
>{
> std::vector<unsigned> x(1);
> return x.front();
>}
>
>E>cl -c -GX -W3 -Wp64 b.cpp
>Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
>Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
>
>b.cpp
>b.cpp(11) : warning C4267: 'return' : conversion from 'size_t' to 'unsigned
>int' , possible loss of data
Interestingly reversing the order of f and g gets rid of the warning.
We can conclude that:
1) size_t == unsigned int on VC7.1 (32-bit)
2) hence vector<unsigned> shares the instantiation of
allocator<size_t>
3) hence VC gets confused about whether vector<unsigned> is actually
vector<unsigned, allocator<size_t> > and the spurious warning is
generated.
It looks like MS were trying to be a bit too clever with the
generation of this warning from something that is actually the same
type (on Win32) as something that shouldn't generate the warning.
Tom
JE>
JE> I get a warning with your code, but the following isn't
JE> giving a warning for me (VC++ 7.1).
>
> #include <vector>
> #include <map>
>
> int main()
> {
> std::map<size_t, int> somemap;
> std::vector<unsigned int> vec(1);
> vec.push_back(35);
> unsigned int b = vec[0]; //<== line 8
> return 0;
> }
>
Scratch that, the warning's still there - I must be going
blind. Best regards, JE
size_t, I believe, is the datetype "returned" (if that's the proper
word) by the sizeof operator, so it must be intrinsically known by the
compiler.
--
Truth,
James Curran
Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.aurora-inc.com
>Doug Harrison [MVP] wrote:
>> P.S. Not that I'm complaining or anything, but anyone know when size_t
>> became a built-in type? :)
>
> size_t, I believe, is the datetype "returned" (if that's the proper
>word) by the sizeof operator, so it must be intrinsically known by the
>compiler.
Actually, size_t is a typedef declared in <stddef.h>. Ditto for ptrdiff_t,
and in C, wchar_t. I know that in Standard C++, wchar_t became intrinsic,
but size_t and ptrdiff_t remain typedefs. So it would be more correct to say
that the compiler knows the types returned by sizeof and pointer
subtraction, and the headers are required to get the typedefs right. But the
following fragment should not compile:
size_t x;
ptrdiff_t y;
>Doug Harrison [MVP] wrote:
>> P.S. Not that I'm complaining or anything, but anyone know when size_t
>> became a built-in type? :)
>
> size_t, I believe, is the datetype "returned" (if that's the proper
>word) by the sizeof operator, so it must be intrinsically known by the
>compiler.
size_t is just a typedef for one of the unsigned integral types:
namespace std
{
typedef some_unsigned_type size_t;
}
//in stddef.h
using std::size_t;
(although I think Microsoft has it backwards:
namespace std{
using ::size_t;
})
Usually it's either unsigned int or unsigned long. e.g.
template <class T, class U>
struct is_same
{
static bool const value = false;
};
template <class T>
struct is_same<T, T>
{
static bool const value = true;
};
#include <cstddef>
#include <iostream>
int main()
{
if (is_same<std::size_t, unsigned>::value)
std::cout << "unsigned\n";
else if (is_same<std::size_t, unsigned long>::value)
std::cout << "unsigned long\n";
else
std::cout << "Some other type\n";
}
I get "unsigned" on VC7.1, gcc and Comeau C++.
Tom
-tom
>.
>