"size_t" как параметр типа, предупреждение о приведении не воспроизводится - PullRequest
4 голосов
/ 20 марта 2012

Я пытался избавиться от предупреждений в более старом коде (должен использовать MSVC 2005, в настоящее время работающий с 32-битной сборкой), но изо всех сил пытался избавиться от size_t до unsigned int преобразование предупреждение . У нас есть собственная Array<T> реализация растущего массива, которая реализует

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

Метод. Когда называется

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

Я получаю conversion from 'size_t' to 'const unsigned int', possible loss of data предупреждение. Рабочей теорией было , что I понимается как unsigned int, что заставляет компилятор преобразовывать size_t в unsigned int при передаче i в at (что было бы неудобно, но приемлемо). Однако я не смог воспроизвести это предупреждение ни в минимальном рабочем примере (внизу этого поста), ни в более сложных минимальных примерах. Простое приведение параметра к unsigned int приводит к тому, что предупреждение исчезает, и этого будет достаточно для наших нужд (согласно контракту число соответствует unsigned int)

  1. Правильно ли мое понимание того, что I означает unsigned int в таком вызове правильно (спецификация говорит: " typedef-name, таким образом, является синонимом для другого типа. Typedef-name делает не вводить новый тип", typeid(size_t(1)).name() говорит, что unsigned int и size_t, кажется, typedef питаются). Другими словами, должен или не должен минимальный пример выдавать предупреждение? так же, насколько я могу сказать.
  2. Поскольку наш код дает нам предупреждения, а минимальный пример - нет, я должен что-то упустить из виду. Несмотря на все усилия, я не могу понять, что. Идеи?

Спасибо

Минимальный пример:

    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;
    }

1 Ответ

1 голос
/ 20 марта 2012

Функция at также настраивается.C ++ попытается вывести аргумент типа шаблона.Это то, что происходит в вашем коде, так как вы не указываете тип в вызове, например a.at (1);

Этот код сгенерирует предупреждение, потому что он выводит тип какint без знака, а затем мы пытаемся передать 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;
}

РЕДАКТИРОВАТЬ: Я на самом деле пробовал этот код в VS, и он генерирует предупреждение.

Edit2: В коде, который я пробовал, size_t и unsigned int тоже 4 байта.Поэтому я немного покопался.В более старых версиях VS size_t определяется как typedef __w64 unsigned int size_t. __W64 теперь устарела, но использовалась для обозначения типов, которые будут иметь другой размер (например, 64 против 32) при переходе на 64-битную платформу.__W64 заставляет компилятор видеть size_t как другой тип.

В качестве эксперимента я набрал свой собственный unsigned int myint и изменил строку size_t i = 10 на myint i = 10.

, используя typedef __w64 unsigned int myint, генерирует предупреждение где as typedef unsigned int myint`не выдает предупреждение.

...