"size_t" as a type parameter, the throw warning does not play

I am trying to get rid of warnings in some older code (I must use MSVC 2005, currently working with a 32-bit build), but tried to get rid of size_t to an unsigned int conversion warning . We have our own implementation of Array<T> growing array that implements

template<typename I> const T& at(const I i) const {return atImpl(i);}

method. When called as

size_t i = 10; myArray.at(i);

I get a conversion from 'size_t' to 'const unsigned int', possible loss of data warning conversion from 'size_t' to 'const unsigned int', possible loss of data . A working theory was that I means unsigned int , which forces the compiler to convert size_t to unsigned int when passing I to at (which would be inconvenient, but acceptable). However, I was not able to reproduce this warning in either the minimal working example (at the bottom of this post) or the more complex minimal examples. Just setting the unsigned int parameter causes the warning to disappear and will be enough for our needs (by contract, the number corresponds to unsigned int )

  • As far as I understand, I unsigned int in such a correct call (spec says: β€œtypedef-name is thus a synonym for another type. Typedef-name does not introduce a new type”, typeid(size_t(1)).name() says that unsigned int and size_t seems to be typedef filed). In other words, should or should not be a minimal example for warning? The build configuration is the same as and as far as I can tell.
  • As our code gives us warnings, but the minimum example is not, there is something that I should ignore. Despite my best efforts, I cannot understand that. Ideas?

thanks

Minimal example:

  template<typename T> class A { int t; public: template<typename I> T& at(const I i) { return t;} }; int main() { size_t i = 10; A<int> a; a.at(i) = 5; // no warning, why? return 0; } 
+4
source share
1 answer

The at at feature is also included. C ++ will try to infer a template type argument. This is what happens in your code since you are not specifying a type in the call, such as a.at <size_t> (1);

This code will generate a warning because it inferred the type as unsigned int, and then we will try to pass size_t

 template <typename T> class A { int t; public: template<typename I> T& at(const I i) { return t;} }; int main() { unsigned int j = 5; size_t i = 10; A<int> a; a.at(j) = 4; // deduce template type as unsigned int a.at(i) = 5; // generate warning return 0; } 

EDIT: I really tried this code in VS and generated a warning.

Edit2: In the code I tried, size_t and unsigned int are both 4 bytes too. So I did the digging. In older versions of VS, size_t is defined as typedef __w64 unsigned int size_t Now "__w64" is outdated, but was used to indicate types that would have a different size (for example, 64 vs 32) when switching to a 64-bit platform. __w64 causes the compiler to see size_t as another type.

As an experiment, I typed my own unsigned int myint and changed the line size_t i = 10 to myint i = 10 .

using typedef __w64 unsigned int myint generates a warning, where "typedef unsigned int myint" does not generate a warning.

+1
source

Source: https://habr.com/ru/post/1402420/


All Articles