Новые возможности Visual C++ 2003–2015

Эта страница содержит все страницы о новых возможностях для всех версий Visual C++ от Visual Studio 2015 до Visual Studio 2003. Эти сведения предоставлены для справки на случай обновления с предыдущих версий Visual Studio.

Примечание.

Сведения о текущей версии Visual Studio см. в статьях Новые возможности Visual C++ в Visual Studio и Улучшения соответствия в Visual C++ в Visual Studio.

Новые возможности C++ в Visual Studio 2015

В Visual Studio 2015 постоянные улучшения соответствия компилятора иногда могут изменить то, как компилятор распознает существующий исходный код. В этом случае во время сборки могут возникнуть новые или другие ошибки или даже поведенческие различия в коде, который был построен ранее и, казалось, работал правильно.

К счастью, эти различия имеют минимальное влияние или совсем не затрагивают большую часть исходного кода. Если же требуется внести изменения в исходный код, чтобы устранить эти различия, как правило, применяются незначительные исправления. Мы включили много примеров ранее допустимого исходного кода, который может потребоваться изменить (раньше), и исправлений (теперь).

Несмотря на то, что эти различия могут повлиять на исходный код и другие артефакты сборки, они не влияют на совместимость двоичных файлов между обновлениями версий Visual C++. На совместимость двоичных файлов может повлиять более серьезный тип изменений (критическое изменение), но нарушения совместимости происходят только между основными версиями Visual C++. Например, между Visual C++ 2013 и Visual C++ 2015. Сведения о критических изменениях, введенных со времени выпуска Visual C++ 2013 до выпуска Visual C++ 2015, см. в статье Журнал изменений Visual C++ 2003–2015.

Улучшения соответствия в Visual Studio 2015

  • Параметр /Zc:forScope-

    Параметр компилятора /Zc:forScope- не рекомендуется к использованию и будет удален в одном из следующих выпусков.

      Command line warning  D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release
    

    Этот параметр обычно использовался, чтобы разрешить нестандартный код, использующий переменные цикла после того момента, когда, согласно стандарту, они должны выйти из области действия. Он требовался только при компиляции с параметром /Za, поскольку без /Za использование переменной цикла for после конца цикла всегда разрешено. Если вас не интересует соответствие стандартам (например, если код не предназначен для переноса в другие компиляторы), можно отключить параметр /Za (или задать для свойства Отключить расширения языка значение Нет). Если вы заботитесь о написании переносимого кода, соответствующего стандартам, необходимо переписать код таким образом, чтобы он соответствовал стандарту, переместив объявление таких переменных в точку за пределами цикла.

      // zc_forScope.cpp
      // compile with: /Zc:forScope- /Za
      // C2065 expected
      int main() {
         // Uncomment the following line to resolve.
         // int i;
         for (int i =0; i < 1; i++)
            ;
         i = 20;   // i has already gone out of scope under /Za
      }
    
  • Параметр компилятора Zg.

    Параметр компилятора /Zg (создать прототипы функций) больше не доступен. Ранее этот параметр компилятора был признан нерекомендуемым.

  • Вы больше не сможете выполнять модульные тесты с использованием C++/CLI из командной строки с помощью mstest.exe. Вместо этого используйте vstest.console.exe.

  • Ключевое слово mutable.

    Описатель класса хранения mutable больше нельзя использовать в местах, где ранее он компилировался без ошибок. Теперь компилятор выдает ошибку C2071 (недопустимый класс хранения). Согласно стандарту, описатель mutable может применяться только к именам членов класса данных и не может применяться к именам, объявленным постоянными или статическими, а также не может применяться к элементам ссылки.

    Рассмотрим следующий пример кода:

      struct S {
          mutable int &r;
      };
    

    Предыдущие версии компилятора Microsoft C++ принимали его, но теперь компилятор выдает следующую ошибку:

      error C2071: 'S::r': illegal storage class
    

    Чтобы устранить ошибку, просто удалите избыточные mutable ключевое слово.

  • char_16_t и char32_t

    char16_t или char32_t больше нельзя использовать в качестве псевдонимов в typedef, поскольку теперь эти типы считаются встроенными. Пользователи и разработчики библиотек повсеместно определяли char16_t и char32_t как псевдонимы uint16_t и uint32_t, соответственно.

      #include <cstdint>
    
      typedef uint16_t char16_t; //C2628
      typedef uint32_t char32_t; //C2628
    
      int main(int argc, char* argv[])
      {
      uint16_t x = 1; uint32_t y = 2;
      char16_t a = x;
      char32_t b = y;
      return 0;
      }
    

    Чтобы обновить код, удалите объявления и переименуйте typedef другие идентификаторы, которые сталкиваются с этими именами.

  • Параметры шаблона, не являющиеся типами

    Определенный код с параметрами шаблона, не являющимися типами, теперь правильно проверяется на совместимость типов при предоставлении явно заданных аргументов шаблона. Например, следующий код компилировался без ошибок в предыдущих версиях Visual C++.

      struct S1
      {
          void f(int);
          void f(int, int);
      };
    
      struct S2
      {
          template <class C, void (C::*Function)(int) const> void f() {}
      };
    
      void f()
      {
          S2 s2;
          s2.f<S1, &S1::f>();
      }
    

    Текущий компилятор правильно выдает ошибку, так как тип параметра шаблона не соответствует аргументу шаблона (параметр является указателем на элемент const, но функция f не констант):

      error C2893: Failed to specialize function template 'void S2::f(void)'note: With the following template arguments:note: 'C=S1'note: 'Function=S1::f'
    

    Чтобы устранить эту ошибку в коде, убедитесь, что используемый тип аргумента шаблона соответствует объявленному типу параметра шаблона.

  • __declspec(align)

    Компилятор больше не принимает __declspec(align) для функций. Оно всегда игнорировалось, но теперь вызывает ошибку компилятора.

      error C3323: 'alignas' and '__declspec(align)' are not allowed on function declarations
    

    Чтобы устранить эту проблему, удалите __declspec(align) из объявления функции. Поскольку оно не оказывает никакого влияния, его удаление ничего не меняет.

  • Обработка исключений

    Существует несколько изменений в обработке исключений. Во-первых, объекты исключений должны быть доступны для перемещения или копирования. Следующий код компилируется в Visual Studio 2013, но не в Visual Studio 2015:

      struct S {
      public:
          S();
      private:
          S(const S &);
      };
    
      int main()
      {
          throw S(); // error
      }
    

    Проблема заключается в том, что конструктор копии является закрытым, поэтому нельзя скопировать объект так, как это происходит во время обычной обработки исключения. То же самое происходит, когда конструктор копии объявлен explicit.

      struct S {
          S();
          explicit S(const S &);
      };
    
      int main()
      {
          throw S(); // error
      }
    

    Для обновления кода убедитесь в том, конструктор копии для объекта исключения является открытым и не отмечен как explicit.

    Перехват исключения по значению также требует, чтобы объект исключения был доступен для копирования. Следующий код компилируется в Visual Studio 2013, но не в Visual Studio 2015:

      struct B {
      public:
          B();
      private:
          B(const B &);
      };
    
      struct D : public B {
      };
    
      int main()
      {
          try
          {
          }
          catch (D d) // error
          {
          }
      }
    

    Эту проблему можно устранить, изменив тип параметра для catch на ссылку.

      catch(D& d)
      {
      }
    
  • Строковые литералы с последующими макросами

    Компилятор теперь поддерживает определенные пользователем литералы. В результате строковые литералы, за которыми следуют макросы без промежуточных пробелов, интерпретируются как определенные пользователем литералы, которые могут вызывать ошибки или приводить к непредвиденным результатам. Например, в предыдущих компиляторах следующий код компилируется успешно:

      #define _x "there"
      char* func() {
          return "hello"_x;
      }
      int main()
      {
          char * p = func();
          return 0;
      }
    

    Компилятор интерпретировал этот код как строковый литерал hello с последующим макросом, который представляет собой расширяющийся there, после чего два строковых литерала были объединены в один. В Visual Studio 2015 компилятор интерпретирует этот код как определенный пользователем литерал, но, поскольку соответствующий определяемый пользователем литерал _x не определен, он выдает ошибку.

      error C3688: invalid literal suffix '_x'; literal operator or literal operator template 'operator ""_x' not found
      note: Did you forget a space between the string literal and the prefix of the following string literal?
    
    

    Чтобы устранить эту проблему, добавьте пробел между строковым литералом и макросом.

  • Смежные строковые литералы

    Аналогично предыдущему случаю, из-за соответствующих изменений в синтаксическом анализе строк смежные строковые литералы (с широкими или узкими символами) без пробела интерпретировались в предыдущих версиях Visual C++ как одна объединенная строка. Теперь в Visual Studio 2015 необходимо добавлять пробелы между двумя строками. Например, необходимо изменить следующий код:

      char * str = "abc""def";
    

    Просто добавьте пробел между двумя строками.

      char * str = "abc" "def";
    
  • Размещаемые операторы new и delete

    Для обеспечения соответствия оператору C++14 было внесено delete изменение. Сведения об изменении стандартов можно найти на странице Освобождение с размером в C++. Изменения добавляют форму глобального delete оператора, который принимает параметр размера. Критическое изменение заключается в том, что если вы ранее использовали оператор delete с той же сигнатурой (чтобы соответствовать новому оператору размещения), вы получите ошибку компилятора (C2956, которая возникает в точке , где используется новое размещение , так как это позиция в коде, где компилятор пытается определить соответствующий оператор сопоставления delete ).

    Функция void operator delete(void *, size_t) была размещаемым оператором delete, соответствующим размещаемой функции newvoid * operator new(size_t, size_t) в C++11. При размещении сделки размера C++14 эта delete функция теперь является обычной функцией распределения сделки (глобальный delete оператор). Стандарт требует, чтобы, если использование нового размещения ищет соответствующую delete функцию и находит обычную функцию распределения сделки, программа не сформирована.

    Например, предположим, что код определяет как размещаемый оператор new, так и размещаемый оператор delete:

      void * operator new(std::size_t, std::size_t);
      void operator delete(void*, std::size_t) noexcept;
    

    Проблема возникает из-за совпадения в сигнатурах функций между определенным оператором удаления размещения и новым глобальным оператором размера delete . Рассмотрите возможность использования другого типа, отличного от size_t любого нового и оператора размещенияdelete. Обратите внимание, что тип size_ttypedef компилятора зависит от компилятора; он предназначен typedef для unsigned int Visual C++. Хорошим решением является использование перечисляемого типа, например:

      enum class my_type : size_t {};
    

    Затем измените определение размещения new и delete используйте этот тип в качестве второго аргумента size_tвместо . Кроме того, необходимо обновить вызовы размещения нового типа для передачи нового типа (например, с помощью static_cast<my_type> преобразования из целочисленного значения) и обновить определение new и delete вернуться к целочисленным типу. Для этого не нужно использовать enum тип класса с элементом size_t .

    Альтернативным решением является возможность полного удаления размещаемого оператора new. Если код использует размещение нового для реализации пула памяти, где аргумент размещения является размером выделенного или удаленного объекта, то функция распределения размера может быть подходит для замены собственного кода пула памяти, и вы можете избавиться от функций размещения и просто использовать собственный оператор двух аргументов delete вместо функций размещения.

    Если вы не хотите немедленно обновлять код, можно вернуться к старому поведению с помощью параметра компилятора /Zc:sizedDealloc-. Если этот параметр используется, функции с двумя аргументами delete не существуют и не вызывают конфликта с оператором удаления размещения.

  • Элементы данных объединений

    Элементы данных объединений больше не могут иметь ссылочные типы. Следующий код успешно компилируется в Visual Studio 2013, но выводит ошибку в Visual Studio 2015.

      union U1 {
          const int i;
      };
      union U2 {
         int &i;
      };
      union U3 {
          struct {int &i;};
      };
    

    Предыдущий код вызывает следующие ошибки:

      test.cpp(67): error C2625: 'U2::i': illegal union member; type 'int &' is reference type
      test.cpp(70): error C2625: 'U3::i': illegal union member; type 'int &' is reference type
    

    Чтобы устранить эту проблему, измените ссылочные типы на указатель или значение. Для изменения типа на указатель требуется внести изменения в код, который использует поле объединения. При изменении кода на значение будут изменены данные, хранящиеся в объединении, что повлияет на другие поля, поскольку поля в типах объединений имеют общую память. В зависимости от величины значения оно также может изменить размер объединения.

  • Анонимные объединения

    теперь более полно соответствуют стандарту. Компилятор предыдущей версии создавал для анонимных объединений явный конструктор и деструктор. Они удалены из Visual Studio 2015.

    struct S {
        S();
    };
    
    union {
        struct {
           S s;
        };
    } u; // C2280
    

    Предыдущий код вызывает следующие ошибки в Visual Studio 2015:

      error C2280: '<unnamed-type-u>::<unnamed-type-u>(void)': attempting to reference a deleted function
      note: compiler has generated '<unnamed-type-u>::<unnamed-type-u>' here
    

    Чтобы устранить эту проблему, предоставьте собственные определения конструктора и/или деструктора.

      struct S {
         // Provide a default constructor by adding an empty function body.
         S() {}
      };
    
      union {
         struct {
            S s;
         };
      } u;
    
  • Объединения с анонимными структурами

    В целях обеспечения соответствия стандарту было изменено поведение для членов анонимных структур в объединениях. Конструктор для членов анонимных структур в объединении больше не вызывается неявно при создании такого объединения. Кроме того, деструктор для членов анонимных структур в объединении больше не вызывается неявно при выходе такого объединения из области действия. Рассмотрим следующий код, в котором объединение U содержит анонимную структуру, содержащую элемент, представляющий собой именованную структуру S с деструктором.

      #include <stdio.h>
      struct S {
          S() { printf("Creating S\n"); }
          ~S(){ printf("Destroying S\n"); }
      };
      union U {
          struct {
          S s;
      };
          U() {}
          ~U(){}
      };
    
      void f()
      {
          U u;
          // Destructor implicitly called here.
      }
    
      int main()
      {
          f();
    
          char s[1024];
          printf("Press any key.\n");
          gets_s(s);
          return 0;
      }
    

    В Visual Studio 2013 конструктор для S вызывается при создании объединения, а деструктор для S вызывается при очистке стека для функции f. Однако в Visual Studio 2015 конструктор и деструктор не вызываются. Компилятор выдает предупреждение об изменении этого поведения.

      warning C4587: 'U::s': behavior change: constructor is no longer implicitly calledwarning C4588: 'U::s': behavior change: destructor is no longer implicitly called
    

    Чтобы восстановить первоначальное поведение, присвойте анонимной структуре имя. Поведение неанонимных структур во время выполнения остается прежним независимо от версии компилятора.

      #include <stdio.h>
    
      struct S {
          S() { printf("Creating S.\n"); }
          ~S() { printf("Destroying S\n"); }
      };
      union U {
          struct {
              S s;
          } namedStruct;
          U() {}
          ~U() {}
      };
    
      void f()
      {
          U u;
      }
    
      int main()
      {
          f();
    
          char s[1024];
          printf("Press any key.\n");
          gets_s(s);
          return 0;
      }
    

    Кроме того, попробуйте переместить код конструктора и деструктора в новые функции и добавьте вызовы этих функций из конструктора и деструктора для объединения.

      #include <stdio.h>
    
      struct S {
          void Create() { printf("Creating S.\n"); }
          void Destroy() { printf("Destroying S\n"); }
      };
      union U {
          struct {
              S s;
          };
          U() { s.Create();  }
          ~U() { s.Destroy(); }
      };
    
      void f()
      {
          U u;
      }
    
      int main()
      {
          f();
    
      char s[1024];
      printf("Press any key.\n");
      gets_s(s);
      return 0;
      }
    
  • Разрешение шаблонов

    В разрешение имен для шаблонов были внесены изменения. При рассмотрении кандидатов для разрешения имени d C++ может возникнуть ситуация, когда одно или несколько рассматриваемых имен приводят к созданию недопустимого экземпляра шаблона. Эти недопустимые экземпляры обычно не вызывают ошибки компилятора, данный принцип известен как SFINAE (сбой подстановки не является ошибкой).

    Если принцип SFINAE требует от компилятора создать экземпляр специализации шаблона класса, то любые ошибки, возникающие во время этого процесса, являются ошибками компилятора. В предыдущих версиях компилятор игнорирует такие ошибки. Рассмотрим следующий пример кода:

      #include <type_traits>
    
      template<typename T>
      struct S
      {
      S() = default;
      S(const S&);
      S(S&&);
    
      template<typename U, typename = typename std::enable_if<std::is_base_of<T, U>::value>::type>
      S(S<U>&&);
      };
    
      struct D;
    
      void f1()
      {
      S<D> s1;
          S<D> s2(s1);
      }
    
      struct B
      {
      };
    
      struct D : public B
      {
      };
    
      void f2()
      {
      S<D> s1;
          S<D> s2(s1);
      }
    

    При компиляции с помощью текущего компилятора появляется следующая ошибка:

      type_traits(1110): error C2139: 'D': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_base_of'
      ..\t331.cpp(14): note: see declaration of 'D'
      ..\t331.cpp(10): note: see reference to class template instantiation 'std::is_base_of<T,U>' being compiled
              with
              [
                  T=D,
                  U=D
              ]
    

    Это происходит из-за того, что при первом вызове is_base_of класс "D" еще не был определен.

    В этом случае исправление заключается в том, чтобы не использовать такие характеристики типов, пока не будет определен класс. При перемещении определений B и D в начало файла с кодом ошибка будет устранена. Если определения указаны в файлах заголовков, проверьте порядок операторов include для этих файлов заголовков, чтобы убедиться в том, что все определения классов компилируются до использования проблемных шаблонов.

  • Конструкторы копии

    Как в Visual Studio 2013, так и в Visual Studio 2015, если пользователь создал в классе конструктор перемещения, но не создал конструктор копии, конструктор копии будет создан компилятором. В Dev14 этот неявно создаваемый конструктор копии также помечается как "= delete".

Улучшения соответствия в обновлении 1 для Visual Studio 2015

  • Закрытые виртуальные базовые классы и косвенное наследование

    В предыдущих версиях компилятора производному классу разрешалось вызывать функции-члены косвенныхprivate virtual базовых классов. Это поведение было неправильным и не соответствовало стандарту языка C++. Компилятор больше не принимает код, написанный таким образом, и выдает в результате ошибку C2280.

      error C2280: 'void *S3::__delDtor(unsigned int)': attempting to reference a deleted function
    

    Пример (раньше)

      class base
      {
      protected:
          base();
          ~base();
      };
    
      class middle: private virtual base {};class top: public virtual middle {};
    
      void destroy(top *p)
      {
          delete p;  //
      }
    

    Пример (теперь)

      class base;  // as above
    
      class middle: protected virtual base {};
      class top: public virtual middle {};
    
      void destroy(top *p)
      {
          delete p;
      }
    

    –или–

      class base;  // as above
    
      class middle: private virtual base {};
      class top: public virtual middle, private virtual bottom {};
    
      void destroy(top *p)
      {
          delete p;
      }
    
  • Перегруженный оператор new и оператор delete

    Предыдущие версии компилятора разрешали объявлять оператор new, не являющийся членом, и оператор delete, не являющийся членом, статически и в пространствах имен, отличных от глобального. При этом создавался риск того, что программа вызовет не ту реализацию оператора new или delete , которую планировал программист, результатом чего будет неправильное поведение во время выполнения. Компилятор больше не принимает код, написанный таким образом, и выдает вместо этого ошибку C2323.

      error C2323: 'operator new': non-member operator new or delete functions may not be declared static or in a namespace other than the global namespace.
    

    Пример (раньше)

      static inline void * __cdecl operator new(size_t cb, const std::nothrow_t&)  // error C2323
    

    Пример (теперь)

      void * __cdecl operator new(size_t cb, const std::nothrow_t&)  // removed 'static inline'
    

    Кроме того, хотя компилятор не дает определенной диагностики, встроенный оператор new считается плохо сформированным.

  • Вызов "operator тип()" (пользовательское преобразование) для типов, не являющихся классами Предыдущие версии компилятора разрешали вызов "operator тип()" для типов, не являющихся классами, при этом он игнорировался без вывода предупреждения. Это создавало риск создания некорректного кода и непредсказуемого поведения во время выполнения. Компилятор больше не принимает код, написанный таким образом, и выдает вместо этого ошибку C2228.

      error C2228: left of '.operator type' must have class/struct/union
    

    Пример (раньше)

      typedef int index_t;
    
      void bounds_check(index_t index);
    
      void login(int column)
      {
          bounds_check(column.operator index_t());  // error C2228
      }
    

    Пример (теперь)

      typedef int index_t;
    
      void bounds_check(index_t index);
    
      void login(int column)
      {
           bounds_check(column);  // removed cast to 'index_t', 'index_t' is an alias of 'int'
      }
    
  • Избыточное ключевое слово typename в сложных спецификаторах типов Предыдущие версии компилятора допускали ключевое слово typename в сложных спецификаторах типов. Код, написанный таким образом, семантически неправилен. Компилятор больше не принимает код, написанный таким образом, и выдает вместо этого ошибку C3406.

      error C3406: 'typename' cannot be used in an elaborated type specifier
    

    Пример (раньше)

      template <typename class T>
      class container;
    

    Пример (теперь)

      template <class T>  // alternatively, could be 'template <typename T>'; 'typename' is not elaborating a type specifier in this case
      class container;
    
  • Выведение типов массивов из списка инициализаторов Предыдущие версии компилятора не поддерживали выведение типов массивов из списка инициализаторов. Теперь компилятор поддерживает подобное выведение типов, и в результате вызовы шаблонов функций с помощью списков инициализаторов теперь могут быть неоднозначными либо может выбираться не та перегрузка, что в предыдущих версиях компилятора. Для устранения этой проблемы теперь необходимо явно указывать в программе требуемую перегрузку.

    Если в результате этого нового поведения при разрешении перегрузки дополнительный кандидат считается равноценным ранее существовавшему, вызов становится неоднозначным, и компилятор выдает ошибку C2668.

      error C2668: 'function' : ambiguous call to overloaded function.
    

    Пример 1. Неоднозначный вызов перегруженной функции (раньше)

      // In previous versions of the compiler, code written in this way would unambiguously call f(int, Args...)
      template <typename... Args>
      void f(int, Args...);  //
    
      template <int N, typename... Args>
      void f(const int (&)[N], Args...);
    
      int main()
      {
          // The compiler now considers this call ambiguous, and issues a compiler error
          f({3});  error C2668: 'f' ambiguous call to overloaded function
      }
    

    Пример 1. Неоднозначный вызов перегруженной функции (теперь)

      template <typename... Args>
      void f(int, Args...);  //
    
      template <int N, typename... Args>
      void f(const int (&)[N], Args...);
    
      int main()
      {
          // To call f(int, Args...) when there is just one expression in the initializer list, remove the braces from it.
          f(3);
      }
    

    Если в результате этого нового поведения при разрешении перегрузки дополнительный кандидат считается лучше ранее существовавшего, вызов разрешается однозначно в нового кандидата, что приводит к изменению поведения программы, которое, возможно, не планировалось программистом.

    Пример 2. Изменение в разрешении перегрузки (раньше)

      // In previous versions of the compiler, code written in this way would unambiguously call f(S, Args...)
      struct S
      {
          int i;
          int j;
      };
    
      template <typename... Args>
      void f(S, Args...);
    
      template <int N, typename... Args>
      void f(const int *&)[N], Args...);
    
      int main()
      {
          // The compiler now resolves this call to f(const int (&)[N], Args...) instead
          f({1, 2});
      }
    

    Пример 2. Изменение в разрешении перегрузки (теперь)

      struct S;  // as before
    
      template <typename... Args>
      void f(S, Args...);
    
      template <int N, typename... Args>
      void f(const int *&)[N], Args...);
    
      int main()
      {
          // To call f(S, Args...), perform an explicit cast to S on the initializer list.
          f(S{1, 2});
      }
    
  • Восстановление предупреждений, касающихся оператора switch

    В предыдущей версии компилятора были удалены ранее существовавшие предупреждения, касающиеся операторов switch . Теперь эти предупреждения восстановлены. Компилятор теперь выдает эти предупреждения. Предупреждения, связанные с определенными вариантами (включая вариант по умолчанию), теперь выдаются в строке, содержащей неправильный вариант, а не в последней строке оператора switch. В результате того, что теперь предупреждения выдаются не в тех строках, что раньше, предупреждения, которые ранее подавлялись с помощью #pragma warning(disable:####) , могут больше не подавляться, как планировалось. Для правильного подавления этих предупреждений может потребоваться перенести директиву #pragma warning(disable:####) в строку перед первым потенциально неправильным вариантом. Ниже приведены восстановленные предупреждения.

      warning C4060: switch statement contains no 'case' or 'default' labels
    
      warning C4061: enumerator 'bit1' in switch of enum 'flags' is not explicitly handled by a case label
    
      warning C4062: enumerator 'bit1' in switch of enum 'flags' is not handled
    
      warning C4063: case 'bit32' is not a valid value for switch of enum 'flags'
    
      warning C4064: switch of incomplete enum 'flags'
    
      warning C4065: switch statement contains 'default' but no 'case' labels
    
      warning C4808: case 'value' is not a valid value for switch condition of type 'bool'
    
      Warning C4809: switch statement has redundant 'default' label; all possible 'case' labels are given
    

    Пример предупреждения C4063 (раньше)

      class settings
      {
      public:
          enum flags
          {
              bit0 = 0x1,
              bit1 = 0x2,
              ...
          };
          ...
      };
    
      int main()
      {
          auto val = settings::bit1;
    
          switch (val)
          {
          case settings::bit0:
              break;
    
          case settings::bit1:
              break;
    
          case settings::bit0 | settings::bit1:  // warning C4063
              break;
          }
      };
    

    Пример предупреждения C4063 (теперь)

      class settings {...};  // as above
    
      int main()
      {
          // since C++11, use std::underlying_type to determine the underlying type of an enum
          typedef std::underlying_type<settings::flags>::type flags_t;
    
          auto val = settings::bit1;
    
          switch (static_cast<flags_t>(val))
          {
          case settings::bit0:
              break;
    
          case settings::bit1:
              break;
    
          case settings::bit0 | settings::bit1:  // ok
              break;
          }
      };
    

    Примеры других восстановленных предупреждений приведены в соответствующей документации.

  • #include: использование описателя родительского каталога '.' в имени пути (только влияет)/Wall/WX

    В предыдущих версиях компилятора не определялись случаи использования спецификатора parent-directory ".." в пути директив #include. Код, написанный таким образом, обычно предназначен для включения заголовков, находящихся за пределами проекта, путем неправильного использования относительных путей к проектам. Это прежнее поведение создавало риск того, что при компиляции программы мог включаться не тот файл исходного кода, который планировал программист, или что эти относительные пути невозможно было бы перенести в другие среды сборки. Компилятор теперь обнаруживает код, написанный таким образом, уведомляет о нем программиста и выдает необязательное предупреждение C4464, если оно включено.

      warning C4464: relative include path contains '..'
    

    Пример (раньше)

      #include "..\headers\C4426.h"  // emits warning C4464
    

    Пример (теперь)

      #include "C4426.h"  // add absolute path to 'headers\' to your project's include directories
    

    Кроме того, хотя компилятор не выдает соответствующего диагностического сообщения, мы также рекомендуем не использовать спецификатор parent-directory ".." для указания включаемых в проект каталогов.

  • #pragma optimize() выходит за пределы файла заголовка (касается только /Wall/WX)

    В предыдущих версиях компилятора не определялись изменения в параметрах флагов оптимизации за пределами файла заголовка, включенного в запись преобразования. Компилятор теперь обнаруживает код, написанный таким образом, уведомляет о нем программиста и выдает необязательное предупреждение C4426 в месте нахождения неправильного #include, если оно включено. Это предупреждение выдается только в том случае, если изменения конфликтуют с флагами оптимизации, установленными аргументами командной строки, переданными в компилятор.

      warning C4426: optimization flags changed after including header, may be due to #pragma optimize()
    

    Пример (раньше)

      // C4426.h
      #pragma optimize("g", off)
      ...
      // C4426.h ends
    
      // C4426.cpp
      #include "C4426.h"  // warning C4426
    

    Пример (теперь)

      // C4426.h
      #pragma optimize("g", off)
      ...
      #pragma optimize("", on)  // restores optimization flags set via command-line arguments
      // C4426.h ends
    
      // C4426.cpp
      #include "C4426.h"
    
  • Несоответствие #pragma warning(push) и #pragma warning(pop) (касается только /Wall/WX)

    В предыдущих версиях компилятора не обнаруживалось сопоставление изменений состояния #pragma warning(push) с изменениями состояния #pragma warning(pop) в другом файле исходного кода, которое редко бывает намеренным. Это создавало риск компиляции программы с набором включенных предупреждений, отличным от того, которое запланировал программист, что могло приводить к неправильному поведению во время выполнения. Компилятор теперь обнаруживает код, написанный таким образом, уведомляет о нем программиста и выдает необязательное предупреждение C5031 в месте нахождения соответствующего #pragma warning(pop), если это предупреждение включено. Это предупреждение включает примечание, ссылающееся на расположение соответствующего #pragma warning(push).

      warning C5031: #pragma warning(pop): likely mismatch, popping warning state pushed in different file
    

    Пример (раньше)

      // C5031_part1.h
      #pragma warning(push)
      #pragma warning(disable:####)
      ...
      // C5031_part1.h ends without #pragma warning(pop)
    
      // C5031_part2.h
      ...
      #pragma warning(pop)  // pops a warning state not pushed in this source file
      ...
      // C5031_part1.h ends
    
      // C5031.cpp
      #include "C5031_part1.h" // leaves #pragma warning(push) 'dangling'
      ...
      #include "C5031_part2.h" // matches 'dangling' #pragma warning(push), resulting in warning C5031
      ...
    

    Пример (теперь)

      // C5031_part1.h
      #pragma warning(push)
      #pragma warning(disable:####)
      ...
      #pragma warning(pop)  // pops the warning state pushed in this source file
      // C5031_part1.h ends without #pragma warning(pop)
    
      // C5031_part2.h
      #pragma warning(push)  // pushes the warning state pushed in this source file
      #pragma warning(disable:####)
      ...
      #pragma warning(pop)
      // C5031_part1.h ends
    
      // C5031.cpp
      #include "C5031_part1.h" // #pragma warning state changes are self-contained and independent of other source files or their #include order.
      ...
      #include "C5031_part2.h"
      ...
    

    Хотя и редко, иногда код намеренно пишется таким образом. Такой код зависит от изменений в порядке #include. Мы рекомендуем, чтобы по возможности файлы исходного кода самостоятельно управляли состояниями предупреждений.

  • Несоответствие #pragma warning(push) (касается только /Wall/WX)

    В предыдущих версиях компилятора не определялось несоответствие изменений состояния #pragma warning(push) в конце записи преобразования. Компилятор теперь обнаруживает код, написанный таким образом, уведомляет о нем программиста и выдает необязательное предупреждение C5032 в месте нахождения несоответствующего #pragma warning(push), если это предупреждение включено. Это предупреждение выдается только в том случае, если в записи преобразования нет ошибок компиляции.

      warning C5032: detected #pragma warning(push) with no corresponding #pragma warning(pop)
    

    Пример (раньше)

      // C5032.h
      #pragma warning(push)
      #pragma warning(disable:####)
      ...
      // C5032.h ends without #pragma warning(pop)
    
      // C5032.cpp
      #include "C5032.h"
      ...
      // C5032.cpp ends -- the translation unit is completed without #pragma warning(pop), resulting in warning C5032 on line 1 of C5032.h
    

    Пример (теперь)

      // C5032.h
      #pragma warning(push)
      #pragma warning(disable:####)
      ...
      #pragma warning(pop) // matches #pragma warning (push) on line 1
      // C5032.h ends
    
      // C5032.cpp
      #include "C5032.h"
      ...
      // C5032.cpp ends -- the translation unit is completed without unmatched #pragma warning(push)
    
  • В результате усовершенствования отслеживания состояния #pragma warning могут выдаваться дополнительные предупреждения

    В предыдущей версии компилятора изменения состояния #pragma warning отслеживались недостаточно хорошо для того, чтобы выдавались все необходимые предупреждения. В результате возникал риск того, что некоторые предупреждения могли подавляться в ситуациях, не предусмотренных программистом. Теперь компилятор более тщательно отслеживает состояние #pragma warning, а особенно изменения состояния #pragma warning внутри шаблонов. При необходимости он также выдает новые предупреждения C5031 и C5032, которые призваны помочь программисту в определении случаев непредусмотренного использования #pragma warning(push) и #pragma warning(pop).

    В результате усовершенствованного отслеживания изменения состояния #pragma warning теперь могут выдаваться предупреждения, которые раньше некорректно подавлялись, или предупреждения о проблемах, которые ранее диагностировались неправильно.

  • Улучшенное определение недостижимого кода

    Изменения, внесенные в стандартную библиотеку C++, и улучшенная возможность встраивания вызовов функций по сравнению с предыдущими версиями компилятора позволяют компилятору определять недостижимость определенного кода. Это может привести к тому, что предупреждение C4720 будет выдаваться чаще.

      warning C4720: unreachable code
    

    Зачастую это предупреждение выдается только при компиляции с включенными оптимизациями, так как при этом может встраиваться больше вызовов функций, удаляться избыточный код или могут производиться другие действия, позволяющие определить недостижимость определенного кода. По нашим наблюдениям, предупреждение C4720 начало часто появляться в блоках try/catch, особенно в связи с использованием std::find.

    Пример (раньше)

      try
      {
          auto iter = std::find(v.begin(), v.end(), 5);
      }
      catch(...)
      {
          do_something();  // ok
      }
    

    Пример (теперь)

      try
      {
          auto iter = std::find(v.begin(), v.end(), 5);
      }
      catch(...)
      {
          do_something();  // warning C4702: unreachable code
      }
    
  • Удаление оптимизации pow(T, int) отката

    Предыдущие версии стандартной библиотеки C++ определили pow(T, int) шаблон функции, который развернет pow вызов функции в ряд операций умножения. Этот метод будет начислять большое количество неточностей из-за характера операций с плавающей запятой, вызывая конечные результаты, которые могут быть значительно неточными. В Visual Studio 2015 с обновлением 1 это поведение было удалено, чтобы избежать непреднамеренной потери точности при использовании pow функции. Однако эта версия pow была гораздо быстрее, чем правильный расчет. Если это изменение приводит к значительной регрессии производительности, а для проекта не требуются точные результаты с плавающей запятой (например, проект уже компилируется с помощью /fp:fast), рассмотрите возможность замены вызовов pow этой функцией обходного решения:

    template <class T> 
    inline T pow_int(T x, int y) throw() {
         unsigned int n;
         if (y >= 0) {
             n = (unsigned int)(y);
         } else {
             n = (unsigned int)(-y);
         }
         for (T z = T(1); ; x *= x) {
             if ((n & 1) != 0) {
                 z *= x;
             }
             if ((n >>= 1) == 0) {
                 return (y < 0 ? T(1) / z : z);
             }
         }
    }
    

    Эта реализация идентична тому, что было включено в предыдущие версии Visual Studio.

Улучшения соответствия в обновлении 2 для Visual Studio 2015

  • В результате частичной поддержки правила SFINAE для выражений могут возникать дополнительные предупреждения и ошибки

    В предыдущих версиях компилятора из-за отсутствия поддержки правила SFINAE для выражений не анализировались некоторые типы выражений внутри описателей decltype. Это поведение было неправильным и не соответствовало стандарту языка C++. В результате непрерывной оптимизации соответствия компилятор теперь анализирует эти выражения и частично поддерживает правило SFINAE для выражений. Поэтому компилятор теперь выдает предупреждения и сообщения об ошибках, найденных в выражениях, которые в предыдущих версиях компилятора не анализировались.

    Если в новой версии анализируется выражение decltype, включающее тип, который еще не был объявлен, выдается ошибка компилятора C2039.

      error C2039: 'type': is not a member of 'global namespace'
    

    Пример 1. Использование необъявленного типа в предыдущих версиях

      struct s1
      {
        template <typename T>
        auto f() -> decltype(s2<T>::type::f());  // error C2039
    
        template<typename>
        struct s2 {};
      }
    

    Пример 1 в текущей версии

      struct s1
      {
        template <typename>  // forward declare s2struct s2;
    
        template <typename T>
        auto f() -> decltype(s2<T>::type::f());
    
        template<typename>
        struct s2 {};
      }
    

    Если в новой версии анализируется выражение decltype, в котором не используется обязательное ключевое слово typename для указания на то, что зависимое имя представляет собой тип, выдается предупреждение компилятора C4346, а также ошибка компилятора C2923.

      warning C4346: 'S2<T>::Type': dependent name is not a type
    
      error C2923: 's1': 'S2<T>::Type' is not a valid template type argument for parameter 'T'
    

    Пример 2. Зависимое имя не является типом (в предыдущих версиях)

      template <typename T>
      struct s1
      {
        typedef T type;
      };
    
      template <typename T>
      struct s2
      {
        typedef T type;
      };
    
      template <typename T>
      T declval();
    
      struct s
      {
        template <typename T>
        auto f(T t) -> decltype(t(declval<S1<S2<T>::type>::type>()));  // warning C4346, error C2923
      };
    

    Пример 2 в текущей версии

      template <typename T> struct s1 {...};  // as above
      template <typename T> struct s2 {...};  // as above
    
      template <typename T>
      T declval();
    
      struct s
      {
        template <typename T>
        auto f(T t) -> decltype(t(declval<S1<typename S2<T>::type>::type>()));
      };
    
  • volatileПеременные-члены не допускают неявно определенных конструкторов и операторов присваивания Предыдущие версии компилятора допускали автоматическое создание конструкторов копирования и перемещения по умолчанию, а также операторов присваивания копирования и перемещения по умолчанию для класса, содержащего переменные-члены volatile. Это поведение было неправильным и не соответствовало стандарту языка C++. Теперь компилятор рассматривает класс с переменными-членами volatile как имеющий нетривиальные конструкторы и операторы присваивания, что делает невозможным автоматическую реализацию этих операторов по умолчанию. Если такой класс является членом объединения (или анонимного объединения внутри класса), конструкторы копирования и перемещения и операторы присваивания копирования и перемещения объединения (или класса, содержащего анонимное объединение) будут неявно определены как удаленные. Попытка создать или скопировать объединение (или класс, содержащий анонимное объединение), не объявляя их явно, будет являться ошибкой. В результате будет выдана ошибка компилятора C2280.

      error C2280: 'B::B(const B &)': attempting to reference a deleted function
    

    Пример (раньше)

      struct A
      {
        volatile int i;
        volatile int j;
      };
    
      extern A* pa;
    
      struct B
      {
        union
        {
          A a;
          int i;
        };
      };
    
      B b1 {*pa};
      B b2 (b1);  // error C2280
    

    Пример (теперь)

      struct A
      {
        int i;int j;
      };
    
      extern volatile A* pa;
    
      A getA()  // returns an A instance copied from contents of pa
      {
        A a;
        a.i = pa->i;
        a.j = pa->j;
        return a;
      }
    
      struct B;  // as above
    
      B b1 {GetA()};
      B b2 (b1);  // error C2280
    
  • Статические функции-члены не поддерживают CV-квалификаторы.

    В предыдущих версиях Visual C++ 2015 допускалось наличие CV-квалификаторов у статических функций-членов. Это поведение связано с регрессией в Visual C++ 2015 и Visual C++ 2015 с обновлением 1. В Visual C++ 2013 и более ранних версиях Visual C++ код, написанный таким образом, отклонялся. Такое поведение Visual C++ 2015 и Visual C++ 2015 с обновлением 1 является неправильным и не соответствует стандарту C++. Среда Visual Studio 2015 с обновлением 2 отклоняет код, написанный таким образом, и выдает вместо этого ошибку компилятора C2511.

      error C2511: 'void A::func(void) const': overloaded member function not found in 'A'
    

    Пример (раньше)

      struct A
      {
        static void func();
      };
    
      void A::func() const {}  // C2511
    

    Пример (теперь)

      struct A
      {
        static void func();
      };
    
      void A::func() {}  // removed const
    
  • Опережающее объявление перечисления недопустимо в коде WinRT (влияет только на /ZW)

    Код, скомпилированный для среда выполнения Windows (WinRT), не позволяет enum объявлять типы, аналогично тому, когда управляемый код C++ компилируется для .Net Framework с помощью коммутатора компилятора/clr. Таким образом гарантируется, что размер перечисления всегда известен и может быть правильно спрогнозирован для системы типов WinRT. Компилятор отклоняет код, написанный таким образом, и выдает ошибку компилятора C2599, а также ошибку компилятора C3197.

      error C2599: 'CustomEnum': the forward declaration of a WinRT enum is not allowed
    
      error C3197: 'public': can only be used in definitions
    

    Пример (раньше)

      namespace A {
        public enum class CustomEnum: int32;  // forward declaration; error C2599, error C3197
      }
    
      namespace A {
        public enum class CustomEnum: int32
        {
          Value1
        };
      }
    
      public ref class Component sealed
      {
      public:
        CustomEnum f()
        {
          return CustomEnum::Value1;
        }
      };
    

    Пример (теперь)

                // forward declaration of CustomEnum removed
      namespace A {
        public enum class CustomEnum: int32
        {
          Value1
        };
      }
    
      public ref class Component sealed
      {
      public:
        CustomEnum f()
        {
          return CustomEnum::Value1;
        }
      };
    
  • Встроенное объявление перегруженных операторов new и delete, не являющихся членами, невозможно (уровень 1 (/W1) включен по умолчанию)

    При встроенном объявлении функций с операторами new и delete, не являющихся членами, в предыдущих версиях компилятора не выводилось предупреждение. Код, написанный таким образом, является неверно сформированным (диагностика не требуется) и может приводить к проблемам с памятью, которые возникают в результате несоответствия операторов new и delete (особенно при совместном использовании в размерных функциях удаления) и которые может быть трудно диагностировать. Для выявления кода, написанного таким образом, компилятор теперь выдает предупреждение C4595.

      warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline
    

    Пример (раньше)

      inline void* operator new(size_t sz)  // warning C4595
      {
        ...
      }
    

    Пример (теперь)

      void* operator new(size_t sz)  // removed inline
      {
        ...
      }
    

    Для исправления кода, написанного таким образом, может потребоваться перенести определения операторов из файла заголовка в соответствующий исходный файл.

Улучшения соответствия в обновлении 3 для Visual Studio 2015

  • std::is_convertable теперь обнаруживает присваивания самому себе (стандартная библиотека) Предыдущие версии признака типа std::is_convertable некорректно обнаруживали присваивание типа класса самому себе, когда конструктор копии удален или является закрытым. Теперь для std::is_convertable<>::value правильно задано false при применении к типу класса с удаленным или закрытым конструктором копии.

    Диагностические данные компилятора, связанные с этим изменением, отсутствуют.

    Пример

      #include <type_traits>
    
      class X1
      {
      public:
          X1(const X1&) = delete;
      };
    
      class X2
      {
      private:
          X2(const X2&);
      };
    
      static_assert(std::is_convertible<X1&, X1>::value, "BOOM");static_assert(std::is_convertible<X2&, X2>::value, "BOOM");
    

    В предыдущих версиях Visual C++ статические утверждения в нижней части этого примера выполнялись, так как для std::is_convertable<>::value было неправильно задано true. Теперь std::is_convertable<>::value правильно задано false, что приводит к ошибкам статических утверждений.

  • Заданные по умолчанию или удаленные упрощенные конструкторы копии и перемещения поддерживают описатели доступа

    Предыдущие версии компилятора не проверяли описатель доступа заданных по умолчанию или удаленных упрощенных конструкторов копии и перемещения перед предоставлением им возможности получать вызовы. Это поведение было неправильным и не соответствовало стандарту языка C++. В некоторых случаях это создавало риск формирования некорректного кода и непредсказуемого поведения во время выполнения. Теперь компилятор проверяет описатель доступа заданных по умолчанию или удаленных упрощенных конструкторов копии и перемещения, чтобы определить, могут ли они быть вызваны, и если нет, выдает предупреждение компилятора C2248.

      error C2248: 'S::S' cannot access private member declared in class 'S'
    

    Пример (раньше)

      class S {
      public:
         S() = default;
      private:
          S(const S&) = default;
      };
    
      void f(S);  // pass S by value
    
      int main()
      {
          S s;
          f(s);  // error C2248, can't invoke private copy constructor
      }
    

    Пример (теперь)

      class S {
      public:
         S() = default;
      private:
          S(const S&) = default;
      };
    
      void f(const S&);  // pass S by reference
    
      int main()
      {
          S s;
          f(s);
      }
    
  • Недопустимость поддержки атрибутивного кода ATL (уровень 1 (/W1) включен по умолчанию)

    Предыдущие версии компилятора поддерживали атрибутивный код ATL. На следующем этапе процесса отмены поддержки атрибутивного кода ATL, который начался в Visual C++ 2008, атрибутивный код ATL выведен из эксплуатации. Для выявления такого нерекомендуемого кода компилятор теперь выдает предупреждение C4467.

      warning C4467: Usage of ATL attributes is deprecated
    

    Если вы хотите продолжать использовать код ATL с атрибутами ATL, пока поддержка не будет удалена из компилятора, можно отключить это предупреждение, передав /Wv:18 аргументы командной строки компилятору или /wd4467 добавив #pragma warning(disable:4467) его в исходный код.

    Пример 1 (раньше)

                [uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")]
      class A {};
    

    Пример 1 в текущей версии

      __declspec(uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")) A {};
    

    Иногда может потребоваться создать IDL-файл, чтобы избежать использования нерекомендуемых атрибутов ATL, как показано в следующем примере кода.

    Пример 2 (раньше)

      [emitidl];
      [module(name="Foo")];
    
      [object, local, uuid("9e66a290-4365-11d2-a997-00c04fa37ddb")]
      __interface ICustom {
          HRESULT Custom([in] long l, [out, retval] long *pLong);
          [local] HRESULT CustomLocal([in] long l, [out, retval] long *pLong);
      };
    
      [coclass, appobject, uuid("9e66a294-4365-11d2-a997-00c04fa37ddb")]
      class CFoo : public ICustom
      {
          // ...
      };
    

    Сначала создайте файл *.idl; Созданный файл vc140.idl можно использовать для получения файла *.idl, содержащего интерфейсы и заметки.

    Затем добавьте в сборку шаг MIDL, чтобы убедиться в создании определений интерфейса C++.

    Пример 2. IDL (теперь)

      import "docobj.idl";
    
      [
          object,local,uuid(9e66a290-4365-11d2-a997-00c04fa37ddb)
      ]
    
      interface ICustom : IUnknown {
          HRESULT  Custom([in] long l, [out,retval] long *pLong);
          [local] HRESULT  CustomLocal([in] long l, [out,retval] long *pLong);
      };
    
      [ version(1.0), uuid(29079a2c-5f3f-3325-99a1-3ec9c40988bb) ]
      library Foo
      {
          importlib("stdole2.tlb");
          importlib("olepro32.dll");
              [
                  version(1.0),
                  appobject,uuid(9e66a294-4365-11d2-a997-00c04fa37ddb)
              ]
    
          coclass CFoo {
              interface ICustom;
          };
      }
    

    Затем используйте ATL непосредственно в файле реализации, как показано в следующем примере кода.

    Пример 2. Реализация (теперь)

      #include <idl.header.h>
      #include <atlbase.h>
    
      class ATL_NO_VTABLE CFooImpl :
          public ICustom,
          public ATL::CComObjectRootEx<CComMultiThreadModel>
      {
      public:
          BEGIN_COM_MAP(CFooImpl)
          COM_INTERFACE_ENTRY(ICustom)
          END_COM_MAP()
      };
    
  • Файлы предкомпилированных заголовков (PCH) и несовпадающие директивы #include (влияет только на /Wall/WX)

    Предыдущие версии компилятора принимали несовпадающие директивы #include в файлах исходного кода между компиляциями -Yc и -Yu при использовании файлов предкомпилированных заголовков (PCH). Компилятор больше не принимает код, написанный таким образом. Теперь для выявления несовпадающих директив #include при использовании PCH-файлов компилятор выдает предупреждение CC4598.

      warning C4598: 'b.h': included header file specified for Ycc.h at position 2 does not match Yuc.h at that position
    

    Пример (раньше)

    X.cpp (-Ycc.h)

      #include "a.h"
      #include "b.h"
      #include "c.h"
    

    Z.cpp (-Yuc.h)

      #include "b.h"
      #include "a.h"  // mismatched order relative to X.cpp
      #include "c.h"
    

    Пример (теперь)

    X.cpp (-Ycc.h)

      #include "a.h"
      #include "b.h"
      #include "c.h"
    

    Z.cpp (-Yuc.h)

      #include "a.h"
      #include "b.h" // matched order relative to X.cpp
      #include "c.h"
    
  • Файлы предкомпилированных заголовков (PCH) и несовпадающие каталоги include (влияет только на /Wall/WX)

    Предыдущие версии компилятора принимали аргументы командной строки несовпадающего каталога включаемых файлов (-I) в компиляторе между компиляциями -Yc и -Yu при использовании файлов предкомпилированных заголовков (PCH). Компилятор больше не принимает код, написанный таким образом. Теперь для выявления аргументов командной строки несовпадающего каталога включаемых файлов (-I) при использовании PCH-файлов компилятор выдает предупреждение CC4599.

      warning C4599: '-I..' : specified for Ycc.h at position 1 does not match Yuc.h at that position
    

    Пример (раньше)

      cl /c /Wall /Ycc.h -I.. X.cpp
      cl /c /Wall /Yuc.h Z.cpp
    

    Пример (теперь)

      cl /c /Wall /Ycc.h -I.. X.cpp
      cl /c /Wall /Yuc.h -I.. Z.cpp
    

Новые возможности C++ в Visual Studio 2013

Улучшенная поддержка стандартов ISO C/C++

GNU C ++

MSVC поддерживает следующие функции языка C++11 стандарта ISO:

  • Аргументы шаблонов по умолчанию для шаблонов функций.
  • Делегирующие конструкторы
  • Операторы явного преобразования.
  • Списки инициализаторов и унифицированная инициализация.
  • Необработанные строковые литералы.
  • Шаблоны с переменным числом аргументов.
  • Шаблоны псевдонимов.
  • Удаленные функции.
  • Инициализаторы нестатических данных-членов (NSDMI).
  • Заданные по умолчанию функции. *
  • Поддерживаются следующие функции языка C99 стандарта ISO:
  • _Bool
  • Составные литералы.
  • Назначенные инициализаторы.
  • Совместное использование объявлений с кодом.
  • Преобразование строковых литералов в изменяемые значения может быть отключено с помощью нового параметра компилятора /Zc:strictStrings. В C++98 преобразование строковых литералов в значения char* (и расширенных строковых литералов в значения wchar_t*) стало нерекомендуемым. В C++11 это преобразование было полностью удалено. Хотя компилятор мог бы строго соответствовать стандарту, вместо этого он предоставляет параметр /Zc:strictStrings, чтобы предоставить возможность управления преобразованием. По умолчанию этот параметр отключен. Обратите внимание, что при использовании этого параметра в режиме отладки библиотека STL не будет компилироваться.
  • Приведения ссылок rvalue и lvalue. С помощью ссылок rvalue C++11 может четко различать значения lvalue и rvalue. Ранее компилятор не предоставлял эту возможность в определенных сценариях приведения. Для обеспечения соответствия компилятора рабочей документации языка C++(см. раздел 5.4, [expr.cast]/1) добавлен новый параметр компилятора /Zc:rvalueCast. Если этот параметр не задан, поведение по умолчанию является таким же, как в Visual Studio 2012.

Примечание.

Для заданных по умолчанию функций использование =default для запроса почленных конструкторов перемещения и операторов присваивания с перемещением не поддерживается.

Библиотеки C99

Добавлены объявления и реализации для отсутствующих функций в следующих заголовках: math.h, ctype.h, wctype.h, stdio.h, stdlib.h и wchar.h. Кроме того, добавлены новые заголовки complex.h, stdbool.h, fenv.h и inttypes.h, а также реализации для всех объявленных в них функций. Добавлены новые заголовки-оболочки C++ (ccomplex, cfenv, cinttypes, ctgmath) и обновлен ряд других заголовков (ccomplex, cctype, clocale, cmath, cstdint, cstdio, cstring, cwchar и cwctype).

Библиотека стандартных шаблонов

Поддержка операторов явного преобразования, списков инициализаторов, ограниченных перечислений и шаблонов с переменным числом аргументов C++11. Все контейнеры теперь поддерживают детализированные требования к элементам C++11. Поддержка следующих функций C++14:

  • "Прозрачные операторы functors" меньше<>, больше<>, плюс<>, умножаются<> и т. д.
  • <make_unique T>(args...) и make_unique<T[]>(n)
  • Функции, не являющиеся членами, — cbegin()/cend(), rbegin()/rend() и crbegin()/crend().
  • <атомар> получил множество улучшений производительности.
  • <> type_traits получили основные исправления стабилизации и кода.

Критические изменения

Подобная расширенная поддержка стандартов ISO C/C++ может потребовать внесения изменений в существующий код, чтобы он соответствовал стандарту C++11 и правильно компилировался в Visual C++ в Visual Studio 2013.

Усовершенствования библиотек Visual C++

  • Добавлен пакет C++ REST SDK. В него включена современная реализация C++ для служб REST.
  • Усовершенствована поддержка текстур C++ AMP. Теперь она включает поддержку MIP-карт и новых режимов выборки.
  • Задачи PPL поддерживают несколько технологий планирования и асинхронную отладку. Новые API-интерфейсы позволяют создавать задачи PPL как для нормальных результатов, так и для исключений.

Производительность приложений C++

  • Автоматический векторизатор теперь распознает и оптимизирует больше шаблонов C++ для ускорения выполнения кода.
  • Усовершенствования, направленные на повышение качества кода для платформы ARM и микроархитектуры Atom.
  • Добавлено соглашение о вызовах __vectorcall. Аргументы типа вектора передаются с помощью соглашения о вызовах __vectorcall для использования регистров вектора.
  • Новые параметры компоновщика. Параметры /Gw (компилятор) и /Gy (ассемблер) позволяют включить оптимизации компоновщика для создания более компактных двоичных файлов.
  • Поддержка общей памяти C++ AMP для уменьшения или исключения копирования данных между ЦП и GPU.

Усовершенствования профильной оптимизации (вероятностного оптимизатора)

  • Повышение производительности за счет уменьшения рабочего набора приложений, оптимизируемых с использованием вероятностного оптимизатора.
  • Новый вероятностный оптимизатор для разработки приложений среды выполнения Windows.

Поддержка разработки приложений среды выполнения Windows

  • Поддержка упакованных типов в структурах значений.

    Теперь можно определить типы значений с помощью полей, которые могут иметь значение NULL, например, IBox<int>^ в отличие от int. Это означает, что поля могут иметь значение или быть равными nullptr.

  • Более подробная информация об исключениях.

    C++/CX поддерживает новую модель ошибок Windows, которая обеспечивает получение и распространение подробной информации об исключении через двоичный интерфейс приложений (ABI), в том числе стеков вызовов и строк пользовательских сообщений.

  • Object::ToString () теперь виртуальный.

    Теперь можно переопределять ToString в пользовательских ссылочных типах среды выполнения Windows.

  • Поддержка нерекомендуемых API.

    Теперь можно помечать открытые API-интерфейсы среды выполнения Windows как нерекомендуемые и предоставлять пользовательские сообщения, которые выводятся как предупреждения при сборке и могут содержать инструкции по миграции.

  • Усовершенствования отладчика.

    Поддержка отладки взаимодействия машинного кода и JavaScript, диагностики исключений среды выполнения Windows и отладки асинхронного кода (среды выполнения Windows и PPL).

Примечание.

В дополнение к возможностям и усовершенствованиям C++, описанным в данном разделе, в Visual Studio доступны и другие усовершенствования, способные помочь в написании более качественных приложений для среды выполнения Windows.

Усовершенствования диагностики

  • Усовершенствования отладчика. Поддержка асинхронной отладки и отладки "Только мой код".
  • Категории анализа кода. Теперь можно просматривать распределенные по категориям выходные данные анализатора кода для поиска и устранения дефектов кода.
  • Диагностика XAML. Теперь можно диагностировать проблемы в разметке XAML, связанные со скоростью реагирования ИП и использованием заряда батарей.
  • Усовершенствования отладки графики и GPU.
  • Удаленные запись и воспроизведение в реальных устройствах.
  • Одновременная отладка C++ AMP и ЦП.
  • Усовершенствованная диагностика среды выполнения AMP C++.
  • Отладка трассировки вычислительных шейдеров, написанных на HLSL.

Усовершенствования трехмерной графики

  • Поддержка формата DDS с предварительным умножением альфа-канала в конвейере содержимого изображений.
  • Редактор изображений использует внутреннее предварительное умножение альфа-канала для отрисовки, что позволяет избежать отрисовки артефактов, таких как темные ореолы.
  • Редакторы изображений и моделей. Теперь в конструкторе шейдеров редактора изображений и редактора моделей поддерживается создание пользовательских фильтров.

Интегрированная среда разработки и производительность работы

Усовершенствованное форматирование кода. К коду на C++ теперь можно применять больше параметров форматирования. С помощью этих параметров можно управлять размещением на новых строках фигурных скобок и ключевых слов, отступами, интервалами и переносом на новую строку. Код форматируется автоматически по завершении написания операторов и блоков, а также при вставке кода в файл.

Завершение скобок. В коде C++ теперь автоматически подставляются закрывающие символы, соответствующие следующим открывающим символам:

  • { (фигурная скобка)
  • [ (квадратная скобка)
  • ( (круглая скобка)
  • ' (одинарная кавычка)
  • " (двойная кавычка)

Дополнительные функции автозавершения в языке C++.

  • Добавление точки с запятой для типов классов.
  • Завершение скобок для необработанных строковых литералов.
  • Завершение многострочных комментариев (/* */)

Команда Найти все ссылки теперь автоматически разрешает и фильтрует ссылки в фоновом режиме после отображения списка текстовых совпадений.

Фильтрация списка членов на основе контекста. Недоступные члены отфильтровываются из списка членов IntelliSense. Например, закрытые члены не отображаются в списке членов, кроме случаев, когда вы изменяете код, реализующий тип. Если список членов открыт, можно нажать CTRL+J для удаления одного уровня фильтрации (применяется только к текущему окну списка членов). Можно нажать CTRL+J еще раз, чтобы снять текстовую фильтрацию и отобразить все члены.

Прокрутка справки по параметрам. Сигнатура функции, отображаемая в окне подсказки справки по параметрам, теперь меняется в зависимости от количества введенных параметров, а не просто отображает произвольную сигнатуру, которая не обновляется на основе текущего контекста. Справка по параметрам также правильно функционирует, когда отображается во вложенных функциях.

Переключение между файлами заголовков и кода. Теперь можно переключаться между заголовком и соответствующим файлом кода с помощью команды контекстного меню или сочетания клавиш.

Возможность изменения размера окна свойств проекта С++

Автоматическое создание кода обработчиков событий в C++/CX и C++/CLI. При вводе кода для добавления обработчика событий в файле кода C++/CX или C++/CLI редактор может автоматически создать экземпляр делегата и определение обработчика событий. Если код обработчика событий может быть создан автоматически, открывается окно подсказки.

Усовершенствованная поддержка определения DPI. Параметр "Поддержка DPI" для файлов манифеста приложения теперь поддерживает значение "Поддержка высокого DPI по мониторам".

Ускорение перехода с одной конфигурации на другую. Для больших приложений переход между конфигурациями (особенно последующие операции переключения) выполняется гораздо быстрее.

Оперативность выполнения сборок. Множество оптимизаций и использование нескольких ядер ускоряет сборку, особенно в крупных проектах. Инкрементные сборки для приложений C++, имеющих ссылки на C++ WinMD, выполняются намного быстрее.

Новые возможности C++ в Visual Studio 2012

Улучшенная поддержка стандартов C/C++11

Библиотека стандартных шаблонов

  • Поддержка новых заголовков STL: <atomic, chrono>, <<condition_variable>, <filesystem>, <future>, mutex>, <<ratio> и <thread>.>
  • Чтобы оптимизировать использование ресурсов памяти, контейнеры теперь имеют меньший размер. Например, в режиме выпуска x86 с параметрами по умолчанию std::vector уменьшился с 16 байт в Visual Studio 2010 до 12 байт в Visual Studio 2012, а std::map — с 16 байт в Visual Studio 2010 до 8 байт в Visual Studio 2012.
  • Были реализованы итераторы SCARY, которые допустимы по стандарту C++11, хотя и не являются обязательными.

Другие усовершенствования C ++11

  • Циклы for на основе диапазона. Вы можете создавать более надежные циклы, которые работают с массивами, контейнерами STL и коллекциями среды выполнения Windows в форме for ( объявление-диапазона-for : выражение ). Это часть базовой языковой поддержки.

  • Лямбда-выражения без отслеживания состояния, которые являются блоками кода, начинающимися с пустого элемента ввода лямбда-выражения [] и не записывающие локальные переменные, теперь можно неявно преобразовать в указатели функций, как того требует стандарт C ++11.

  • Поддержка ограниченных перечислений. Теперь поддерживается ключ перечисления класса перечисления C++. В следующем коде показано, чем этот ключ перечисления отличается от предыдущего поведения перечисления.

    enum class Element { Hydrogen, Helium, Lithium, Beryllium };
    void func1(Element e);
    func1(Hydrogen); // error C2065: 'Hydrogen' : undeclared identifier
    func1(Element::Helium); // OK
    

Поддержка разработки приложений среды выполнения Windows

  • Модель собственного пользовательского интерфейса на базе XAML. Для приложений среды выполнения Windows вы можете использовать новую собственную модель пользовательского интерфейса на базе XAML.
  • Расширения компонентов Visual C++. Эти расширения упрощают использование объектов среды выполнения Windows, являющихся неотъемлемой частью ее приложений. Дополнительные сведения: Roadmap for Windows Runtime apps using C++ (Стратегия создания приложений среды выполнения Windows на C++), Справочник по языку Visual C++ (C++/CX)
  • Игры DirectX. Разрабатывайте захватывающие игры, используя поддержку новой версии DirectX для приложений среды выполнения Windows.
  • Взаимодействие XAML и DirectX. Мы обеспечили более эффективное внутреннее взаимодействие между XAML и DirectX в приложениях среды выполнения Windows.
  • Разработка библиотеки DLL для компонента среды выполнения Windows. Разработка библиотеки DLL для компонента делает среду выполнения Windows расширяемой.

Компилятор и компоновщик

  • Автоматический векторизатор. Компилятор анализирует циклы в коде и, где это возможно, выдает инструкции, использующие векторные регистры, и инструкции, представленные во всех современных процессорах. Это ускоряет выполнение циклов. (Эти инструкции процессора называются потоковыми SIMD-расширениями — SSE.) Вам не требуется включать или запрашивать такую оптимизацию, так как она применяется автоматически.
  • Автоматический параллелизатор. Компилятор может анализировать циклы в коде и выдавать инструкции, распределяющие вычисления между несколькими ядрами или процессорами. Это может ускорять выполнение циклов. Эту оптимизацию нужно запросить, так как она отключена по умолчанию. Во многих случаях помогает включение в код #pragma loop(hint_parallel(N)) непосредственно перед циклами, которые нужно параллелизовать.
  • Автоматический параллелизатор и автоматический векторизатор могут работать совместно, чтобы распределить вычисления между несколькими ядрами и код на каждом ядре использовал его векторные регистры.

Новые возможности в обновлении 1 для Visual Studio 2012

Ориентация на Windows XP при сборке кода C++. Вы также можете использовать библиотеки и компилятор Microsoft C++ для ориентации на Windows XP и Windows Server 2003.

Поддержка параллельного программирования

C++ Accelerated Massive Parallelism (AMP)

C++ AMP ускоряет выполнение кода C++ благодаря использованию преимуществ оборудования для параллельной обработки данных, которое обычно представлено GPU на выделенной видеокарте. Модель программирования C++ AMP включает многомерные массивы, индексирование, перенос памяти, мозаичное заполнение и библиотеку математических функций. С помощью расширений языка C++ AMP и ограничений компилятора можно управлять перемещением данных из ЦП в GPU и обратно.

Отладка. Процесс отладки для приложений, использующих C++ AMP для ориентации GPU, аналогичен отладке для других приложений C++. Сюда входят новые дополнения параллельной отладки, упомянутые ранее.

Профилирование. Доступна новая поддержка профилирования для активности GPU, основанная на C++ AMP и других модулях программирования на базе Direct3D.

Общие усовершенствования параллельного программирования

Учитывая то, что оборудование переходит на многоядерные архитектуры, разработчики больше не могут полагаться на постоянное повышение частоты одноядерных систем. Поддержка параллельного программирования в среде выполнения с параллелизмом позволяет разработчикам использовать преимущества этих новых архитектур. В Visual Studio 2010 появились эффективные библиотеки параллелизации C++, например библиотека параллельных шаблонов, а также функции, позволяющие воспользоваться преимуществами параллелизма посредством реализации сложных конвейеров потока данных. В Visual Studio 2012 эти библиотеки расширены и обеспечивают повышенную производительность, лучшую управляемость и улучшенную поддержку параллельных шаблонов, наиболее востребованных разработчиками. Теперь это предложение включает в себя следующее:

  • Полнофункциональная модель программирования на основе задач, поддерживающая асинхронность и продолжения.
  • Параллельные алгоритмы, которые поддерживают параллелизм ветвления-слияния (parallel_for, parallel_for со сходством, parallel_for_each, parallel_sort, parallel_reduce, parallel_transform).
  • Безопасные в отношении параллельного выполнения контейнеры, которые предоставляют потокобезопасные версии структур данных std, таких как priority_queue, queue, vector и map.
  • Библиотека асинхронных агентов, которую разработчики могут использовать для реализации конвейеров потока данных, естественным образом раскладываемых на параллельных блоки.
  • Настраиваемые планировщик заданий или диспетчер ресурсов для упрощения композиции шаблонов в этом списке.
Общие усовершенствования параллельной отладки

Кроме окон Параллельные задачи и Параллельные стеки, Visual Studio 2012 содержит новое окно Контроль параллельных данных, чтобы вы могли проверить значения выражения во всех потоках и процессах, а также выполнить сортировку и фильтрацию результата. Вы также можете использовать собственные визуализаторы для расширения этого окна и пользоваться преимуществами новой поддержки нескольких процессов во всех окнах инструментов.

IDE

Поддержка шаблонов Visual Studio. Теперь вы можете использовать технологию шаблонов Visual Studio для создания шаблонов проектов и элементов C++.

Асинхронная загрузка решения. Проекты теперь загружаются асинхронно — сначала обрабатываются ключевые компоненты решения, чтобы вы могли быстрее приступить к работе.

Автоматическое развертывание для удаленной отладки. Развертывание файлов для удаленной отладки в Visual C++ стало еще проще. Параметр Развернуть в контекстном меню проекта автоматически копирует на удаленный компьютер файлы, указанные в свойствах конфигурации отладки. Копировать файлы на удаленный компьютер вручную больше не требуется.

C++/CLI IntelliSense. C++/CLI теперь полностью поддерживает IntelliSense. Функции IntelliSense, такие как краткие сведения, справка по параметрам, список членов и автозавершение, теперь работают в C++/CLI. Кроме того, другие усовершенствования IntelliSense и IDE, указанные в этом документе, также работают в C++/CLI.

Расширение подсказок IntelliSense. Подсказки с краткими сведениями IntelliSense C++ теперь отображают расширенную информацию в стиле комментариев XML-документации. Если вы используете API из библиотеки, например C++ AMP, имеющий комментарии в стиле XML-документации, подсказка IntelliSense показывает расширенные сведения, а не одно объявление. Кроме того, если код содержит комментарии XML-документации, подсказки IntelliSense показывают более полные сведения.

Конструкции кода C++. Структура кода доступна для switch, if-else, цикла for и других базовых конструкций кода в раскрывающемся списке "Список членов". Выберите фрагмент кода в этом списке, чтобы вставить его в код, а затем задайте необходимую логическую схему. Кроме того, можно создать собственные пользовательские фрагменты кода для использования в редакторе.

Улучшения списка членов. Раскрывающийся список Список членов отображается автоматически при вводе кода в редакторе кода. Результаты отфильтруются так, чтобы отображались только соответствующие члены. Вы можете управлять логикой фильтрации, используемой в списке членов, в диалоговом окне Параметры в разделе Текстовый редактор>C/C++>Дополнительно.

Семантическая раскраска. Типы, перечисления, макросы и другие токены C++ теперь по умолчанию имеют раскраску.

Выделение ссылок. Теперь при выборе символа выделяются все его экземпляры в текущем файле. Нажмите клавиши CTRL+SHIFT+СТРЕЛКА ВВЕРХ или CTRL+SHIFT+СТРЕЛКА ВНИЗ для перемещения по выделенным ссылкам. Вы можете отключить эту функцию в диалоговом окне Параметры в разделе Текстовый редактор>C/C++>Дополнительно.

Средства управления жизненным циклом приложения

Статический анализ кода

Статический анализ для C++ был обновлен, чтобы предоставлять расширенные сведения о контексте ошибок, больше правил анализа и улучшенные результаты анализа. В новом окне "Анализ кода" можно отфильтровать сообщения по ключевому слову, проекту и серьезности. Если выбрать в этом окне сообщение, в редакторе кода выделяется строка, где это сообщение было активировано. Для некоторых предупреждений C++ это сообщение содержит список строк исходного кода, показывающих путь выполнения, который приводит к данному предупреждению; кроме того, выделяются точки принятия решений и причины для выбора этого конкретного пути. Анализ кода входит в состав большинства выпусков Visual Studio 2012. Выпуски Professional, Premium и Ultimate содержат все правила. Выпуски Express для Windows 8 и Windows Phone содержат только наиболее важные предупреждения. В выпуск Express для Web анализ кода не входит. Ниже указаны некоторые улучшения анализа кода:

  • Новые предупреждения параллелизма помогают избежать ошибок параллелизма, гарантируя использование подходящих дисциплин блокировки в многопоточных программах C/C++. Анализатор обнаруживает потенциальные состояния гонки, инверсии порядка блокировки, нарушения контракта блокировки вызываемого и вызывающего объектов, несоответствующие операции синхронизации и другие ошибки параллелизма.
  • Вы можете указать правила C++, которые нужно применить к анализу кода, с помощью наборов правил.
  • В окне Анализ кода можно вставить в исходный код директиву pragma, подавляющую выбранное предупреждение.
  • Вы можете повысить точность и полноту анализа статического кода, используя новую версию языка заметок для исходного кода (SAL) корпорации Майкрософт, позволяющую описать, как функция использует свои параметры, какие предположения о них она делает и какие гарантии предоставляет при завершении.
  • Поддержка 64-разрядных проектов C++.

Обновленная платформа модульного тестирования

Новая платформа модульного тестирования C++ в Visual Studio служит для написания модульных тестов C++. Добавьте новый проект модульного теста в имеющееся решение C++, используя шаблон проекта модульного теста C++ в разделе "Visual C++" диалогового окна "Новый проект". Приступить к написанию модульных тестов можно в созданный заглушке кода TEST_METHOD в файле Unittest1.cpp. После написания кода теста выполните сборку решения. Если вы хотите выполнить тесты, откройте окно Обозреватель модульных тестов, выбрав Вид>Другие окна>Обозреватель модульных тестов, а затем в контекстном меню для нужного тестового случая выберите Запустить выбранный тест. По завершении тестового запуска в том же окне можно просмотреть результаты теста и дополнительные сведения о трассировке стека.

Графы зависимостей архитектуры

Теперь, чтобы лучше понять свой код, вы можете создать графы зависимостей для двоичного файла, класса, пространства имен, а также включить файлы в решение. В строке меню выберите Архитектура>Сформировать диаграмму зависимостей, а затем Для решения или Для включаемого файла, чтобы создать граф зависимостей. После создания графа его можно изучить, развернув каждый узел, определить отношения зависимости, перемещаясь между узлами, а также просмотреть исходный код, щелкнув пункт Просмотр содержимого в контекстном меню для узла. Чтобы создать граф зависимостей для включаемых файлов, в контекстном меню для файла исходного кода *.cpp или файла заголовка *.h выберите Создать диаграмму включаемых файлов.

Обозреватель архитектуры

С помощью обозревателя архитектуры можно изучать ресурсы в решении, проектах или файлах C++. В строке меню выберите Архитектура>Окна>Обозреватель архитектуры. Вы можете выбрать нужный узел, например Представление классов. В этом случае правая часть окна инструментов развертывается, отображая список пространств имен. Если выбрать пространство имен, появляется новый столбец со списком классов, структур и перечислений в этом пространстве имен. Вы можете продолжить просмотр ресурсов или вернуться в крайний левый столбец для запуска другого запроса. См. раздел Поиск кода с помощью обозревателя архитектуры.

Объем протестированного кода

Функция объема протестированного кода была обновлена, чтобы динамически инструментировать двоичные файлы во время выполнения. Это уменьшает временные затраты на настройку и повышает производительность. Вы также можете собирать данные об объеме протестированного кода из модульных тестов для приложений C++. В случае создания модульных тестов C++ вы можете использовать обозреватель модульных тестов для просмотра тестов в решении. Чтобы запустить модульные тесты и собрать для них данные об объеме протестированного кода, в обозревателе модульных тестов выберите элемент Анализ покрытия кода. Вы можете изучить результаты для объема протестированного кода в соответствующем окне результатов. Чтобы открыть его, в строке меню выберите Тест>Окна>Результаты покрытия кода.

Новые возможности C++ в Visual Studio 2010

Компилятор и компоновщик C++

Ключевое слово auto. Ключевое слово auto имеет новую цель. Используйте значение auto по умолчанию ключевое слово для объявления переменной, тип которой выводится из выражения инициализации в объявлении переменной. Параметр /Zc:auto компилятора вызывает новое или предыдущее значение auto ключевое слово.

Описатель типа decltype. Описатель decltype типов возвращает тип указанного выражения. decltype Используйте описатель типов в сочетании с auto ключевое слово, чтобы объявить тип, который является сложным или известным только компилятором. Например, используйте это сочетание для объявления функции шаблонов, тип возвращаемого значения которой зависит от типов аргументов его шаблонов. Либо объявите функцию шаблонов, которая вызывает другую функцию, а затем возвращает тип возвращаемого значения вызванной функции.

Лямбда-выражения. Лямбда-функции имеют тело функции, но не имеют имени. Лямбда-функции сочетают лучшие характеристики указателей функций и объектов функций. Используйте лямбда-функцию самостоятельно, как параметр функции шаблона вместо объекта функции или вместе с auto ключевое слово для объявления переменной, тип которой является лямбда-объектом.

Ссылка rvalue. Декларатор ссылки rvalue (&&) объявляет ссылку на rvalue. Ссылка на rvalue позволяет использовать семантику перемещения и точную пересылку для написания более эффективных конструкторов, функций и шаблонов.

Объявление static_assert. Объявление static_assert проверяет утверждение программного обеспечения во время компиляции, в отличие от других механизмов утверждения, которые тестируются во время выполнения. Если утверждение не выполняется, не выполняется и компиляция. При этом выводится сообщение о возникшей ошибке.

Ключевые слова nullptr и __nullptr. MSVC позволяет использовать nullptr ключевое слово с машинным кодом или с управляемым кодом. Ключевое слово nullptr указывает, что дескриптор объекта, внутренний указатель или собственный тип указателя не указывает на объект. Компилятор интерпретирует nullptr управляемый код при использовании /clr параметра компилятора и машинного кода, если этот параметр не используется /clr . Ключевое слово __nullptr для конкретной корпорации Майкрософт имеет то же значение, что nullptrи только для машинного кода. При компиляции собственного кода C/C++ с помощью /clr параметра компилятора компилятор не может определить, является ли nullptr ключевое слово собственным или управляемым термином. Чтобы устранить эту неоднозначность, используйте ключевое слово nullptr для обозначения управляемого значения, а __nullptr — машинного.

/Zc:trigraphs Параметр компилятора. По умолчанию поддержка триграфов отключена. Для включения поддержки триграфов используйте параметр компилятора /Zc:trigraphs. Триграф состоит из двух последовательных вопросительных знаков (??), за которыми следует третий уникальный знак. Компилятор заменяет триграф соответствующим знаком пунктуации. Например, компилятор заменяет триграф ??= на символ решетки #. Триграфы можно применять в файлах исходного кода на С, которые используют набор символов, не содержащий определенные знаки пунктуации.

Новый вариант профильной оптимизации. PogoSafeMode — это новый вариант профильной оптимизации, который позволяет указать, какой режим использовать при оптимизации приложения: безопасный или быстрый. Безопасный режим медленнее быстрого, но безопасен в многопоточной среде. По умолчанию применяется быстрый режим.

Новый параметр /clr:nostdlib в среде CLR. Для /clr (компиляция среды CLR) добавлен новый параметр. Если включены разные версии одних библиотек, выдается ошибка компиляции. Новый параметр позволяет исключить библиотеки CLR по умолчанию, чтобы программа могла использовать указанную версию.

Новая директива pragma — detect_mismatch. Директива pragma detect_mistmatch позволяет поместить в файлы тег, сравниваемый с другими тегами с таким же именем. Если существует несколько значений для одного имени, компоновщик выдает ошибку.

Встроенные компоненты XOP, FMA4 и LWP. Для процессорных технологий были добавлены новые встроенные функции, поддерживающие новые встроенные компоненты XOP в Visual Studio 2010 с пакетом обновления 1 (SP1), новые встроенные компоненты FMA4 в Visual Studio 2010 с пакетом обновления 1 (SP1) и новые встроенные компоненты LWP в Visual Studio 2010 с пакетом обновления 1 (SP1). Используйте __cpuid, __cpuidex, чтобы определить, какие технологии процессора поддерживаются на определенном компьютере.

Система сборки и проекты Visual Studio C++

MSBuild. Теперь решения и проекты Visual C++ создаются с помощью системы MSBuild.exe, которая заменяет собой VCBuild.exe. MSBuild представляет собой то же гибкое средство и тип расширяемой сборки на базе XML, которые применяются для других языков и типов проектов Visual Studio. Из-за этого изменения файлы проекта Visual Studio C++ теперь используют формат файла XML и имеют расширение VCXPROJ. Visual Studio C++ автоматически преобразует файлы проекта более ранней версии Visual Studio в новый формат файла.

Каталоги VC++. Параметр каталогов VC++ теперь доступен в двух местах. Вы можете использовать страницы свойств проекта, чтобы задать значения каталогов VC++ для отдельных проектов. Вы можете использовать диспетчер свойств и страницу свойств, чтобы задать глобальные значения каталогов VC++ для отдельных конфигураций.

Межпроектные зависимости. В более ранних выпусках определенные зависимости между проектами хранились в файле решения. При преобразовании этих решений в новый формат файла проекта зависимости преобразуются в межпроектные ссылки. Это изменение может отрицательно повлиять на приложения, так как концепции зависимостей решения и межпроектных ссылок различаются.

Макросы и переменные среды. Новый макрос _ITERATOR_DEBUG_LEVEL вызывает поддержку отладки для итераторов. Используйте этот макрос вместо старых _SECURE_SCL и _HAS_ITERATOR_DEBUGGING.

Библиотеки Visual C++

Библиотеки среды выполнения с параллелизмом. Платформа среды выполнения с параллелизмом поддерживает приложения и компоненты, которые выполняются одновременно, и предназначена для программирования параллельных приложений в Visual C++. Для поддержки программирования параллельных приложений библиотека параллельных шаблонов (PPL) предоставляет алгоритмы и контейнеры общего назначения для реализации детального параллелизма. Библиотека асинхронных агентов предоставляет модель программирования на основе субъектов и интерфейсы передачи сообщений для недетализированного потока данных и задач конвейеризации.

Стандартная библиотека C++. Ниже приведен список многих изменений, внесенных в стандартную библиотеку C++.

  • Новая функция языка C++ — ссылки rvalue — позволяет реализовать семантику перемещения и точную пересылку для многих функций в библиотеке стандартных шаблонов. Семантика перемещения и точная пересылка значительно повышают производительность операций, выделяющих или присваивающих переменные либо параметры.
  • Ссылки rvalue также используются для реализации нового класса unique_ptr, который является более безопасным типом смарт-указателя, чем класс auto_ptr. Класс unique_ptr является перемещаемым, но не копируемым. Он реализует строгую семантику владения без ущерба для безопасности и хорошо работает с контейнерами, поддерживающими ссылки rvalue. Класс auto_ptr устарел.
  • Пятнадцать новых функций, например , и , были добавлены в заголовок алгоритма><.is_sortedcopy_iffind_if_not
  • В заголовке <памяти> новая функция make_shared — это удобный, надежный и эффективный способ сделать общий указатель на объект одновременно созданным объектом.
  • Последовательно связанные списки поддерживаются заголовком <forward_list> .
  • Новые функции-члены cbegin, cend, crbegin и crend предоставляют const_iterator, который перемещается вперед или назад по контейнеру.
  • Заголовок <system_error> и связанные шаблоны поддерживают обработку ошибок системы низкого уровня. Члены класса exception_ptr можно использовать для переноса исключений между потоками.
  • Заголовок <codecvt> поддерживает преобразование различных кодировк символов Юникода в другие кодировки.
  • Заголовок <распределителей> определяет несколько шаблонов, которые помогают выделить и освободить блоки памяти для контейнеров на основе узлов.
  • Существует множество обновлений случайного> заголовка<.

Библиотека Microsoft Foundation Class (MFC)

Функции Windows 7. MFC поддерживает многие функции Windows 7, например пользовательский интерфейс ленты, панель задач, списки переходов, эскизы на вкладках, предварительные просмотры эскизов, индикатор выполнения, дополнительный значок и индексирование поиска. Так как MFC автоматически поддерживает многие функции Windows 7, изменение существующего приложения может не требоваться. Для поддержки других функций в новых приложениях используйте мастер приложений MFC, чтобы указать нужные функциональные возможности.

Поддержка мультисенсорной технологии. MFC поддерживает приложения с мультисенсорным пользовательским интерфейсом, например приложения для операционной системы Microsoft Surface. Мультисенсорные приложения могут обрабатывать сообщения Windows Touch и сообщения жестов, которые являются сочетанием сообщений касаний. Просто зарегистрируйте приложение для событий касаний и жестов, и операционная система будет перенаправлять мультисенсорные события обработчикам событий.

Поддержка высокого DPI. Теперь приложения MFC по умолчанию поддерживают высокий DPI. Если приложение поддерживает высокий DPI (параметр числа точек на дюйм), операционная система может масштабировать окна, текст и другие элементы пользовательского интерфейса до текущего разрешения экрана. Это означает, что масштабированное изображение с большей вероятностью будет отображаться правильно, то есть необрезанным или пикселизованным.

Диспетчер перезапуска. Диспетчер перезапуска автоматически сохраняет документы и перезапускает приложение в случае неожиданного завершения работы или перезапуска. Например, диспетчером перезапуска можно воспользоваться для запуска приложения после закрытия его программой автоматического обновления. Дополнительные сведения о настройке приложения для использования диспетчера перезапуска см. в разделе Практическое руководство. Добавление поддержки диспетчера перезапуска.

CTaskDialog. Класс CTaskDialog можно использовать вместо стандартного окна сообщений AfxMessageBox. Класс CTaskDialog отображает и собирает больше данных, чем стандартное окно сообщений.

Библиотека SafeInt

Новая библиотека SafeInt выполняет безопасные арифметические операции, ответственные за целочисленное переполнение. Она также сравнивает разные типы целых чисел.

Новые макросы библиотеки шаблонных классов ATL

В библиотеку ATL были добавлены новые макросы для расширения функциональности PROP_ENTRY_TYPE и PROP_ENTRY_TYPE_EX. PROP_ENTRY_INTERFACE и PROP_ENTRY_INTERFACE_EX позволяют добавить список допустимых CLSID. PROP_ENTRY_INTERFACE_CALLBACK и PROP_ENTRY_INTERFACE_CALLBACK_EX позволяют задать функцию обратного вызова, чтобы определить, допустим ли CLSID.

Предупреждения /analyze

Из библиотек среды выполнения C (CRT), MFC и ATL было удалено большинство предупреждений /analyze (корпоративный анализ кода).

Анимация и поддержка D2D

Теперь MFC поддерживает анимацию и графику Direct2D. Библиотека MFC содержит несколько новых функций и классов MFC для поддержки этой функциональности. Существует также два новых пошаговых руководства, описывающих добавление объекта D2D и объекта анимации в проект: Пошаговое руководство. Добавление объекта D2D в проект MFC и Пошаговое руководство. Добавление анимации в проект MFC.

IDE

Усовершенствования IntelliSense. Технология IntelliSense для Visual C++ была полностью переработана, в результате чего стала быстрее, точнее и получила возможность обрабатывать крупные проекты. Для этого в интегрированной среде разработки проводится различие между тем, как разработчик просматривает и изменяет исходный код, и как среда использует исходный код и параметры проекта для сборки решения. Благодаря такому разделению обязанностей функции просмотра, такие как представление классов и новое диалоговое окно Перейти к, обрабатываются системой, основанной на новом файле базы данных (SDF) системы SQL Server, который заменяет старый файл просмотра без компиляции (NCB). Функции IntelliSense, такие как краткие сведения, автозавершение и справка по параметрам, анализируют записи преобразования только при необходимости. Гибридные функции, такие как новое окно Иерархия вызовов, используют сочетание функций просмотра и IntelliSense. Так как IntelliSense обрабатывает только данные, которые нужны в данный момент, скорость реагирования интегрированной среды разработки повышается. Кроме того, так как используется более актуальная информация, окна и представления интегрированной среды разработки отражают более точные сведения. Наконец, так как инфраструктура интегрированной среды разработки лучше организована, располагает увеличенным объемом ресурсов и лучше масштабируется, она способна обрабатывать более крупные проекты.

Усовершенствования обработки ошибок IntelliSense. Интегрированная среда разработки лучше распознает ошибки, которые могут привести к потере IntelliSense, и подчеркивает их красной волнистой линией. Кроме того, эта среда сообщает об ошибках IntelliSense в окно списка ошибок. Для отображения кода, который вызвал проблему, дважды щелкните ошибку в окне списка ошибок.

Функция автозавершения #include. Интегрированная среда разработки поддерживает автозавершение для ключевого слова #include. При вводе #include она создает раскрывающийся список допустимых файлов заголовка. Если продолжить ввод имени файла, среда отфильтровывает список соответствующим образом. Вы можете в любой момент выбрать в списке включаемый файл. Это позволяет быстро включать файлы, не зная их точное имя.

Перейти к. Диалоговое окно Перейти к позволяет найти все символы и файлы в проекте, соответствующие указанной строке. Результаты уточняются сразу после ввода дополнительных символов в строке поиска. Поле Результаты содержит число найденных элементов и помогает вам решить, нужно ли ограничить поиск. Поля Вид/область, Расположение и Предварительный просмотр помогают различать элементы с одинаковыми именами. Кроме того, вы можете расширить эту функцию для поддержки других языков программирования.

Параллельные отладка и профилирование. Отладчик Visual Studio поддерживает среду выполнения с параллелизмом и помогает устранять неполадки в приложениях с параллельной обработкой. Новый профилировщик с параллелизмом позволяет визуализировать общее поведение приложения. Кроме того, можно использовать новые окна инструментов, чтобы визуализировать состояние задач и их стеки вызовов.

Конструктор лент. Конструктор лент — это графический редактор, позволяющий создавать и изменять пользовательский интерфейс ленты MFC. Окончательный пользовательский интерфейс ленты представлен файлом ресурсов на основе XML (MFCRIBBON-MS). Для существующих приложений можно записать текущий пользовательский интерфейс ленты, временно добавив несколько строк кода и затем вызвав конструктор лент. После создания файла ресурсов ленты вы можете заменить рукописный код пользовательского интерфейса ленты на несколько операторов, загружающих ресурс ленты.

Иерархия вызовов. Окно Иерархия вызовов позволяет перейти ко всем функциям, вызываемым определенной функцией и вызывающих ее.

Инструменты

Мастер классов MFC. В Visual C++ 2010 снова появился популярный мастер классов MFC. Мастер классов MFC позволяет удобно добавлять в проект классы, сообщения и переменные, не редактируя наборы исходных файлов вручную.

Мастер элементов управления ATL. Мастер элементов управления ATL больше не заполняет поле ProgID автоматически. Если элемент управления ATL не имеет программного идентификатора ProgID, другие средства могут с ним не работать. Одним из примеров инструмента, требующего элементы управления ProgID, является диалоговое окно Вставка элемента управления ActiveX. Дополнительные сведения о диалоговом окне см. в разделе "Вставка элементов ActiveX".

Справочные материалы по ассемблеру Microsoft Macro Assembler

Добавление типа данных YMMWORD поддерживает 256-разрядные операнды мультимедиа, входящие в состав инструкций Intel Advanced Vector Extensions (AVX).

Новые возможности C++ в Visual Studio 2008

Интегрированная среда разработки (IDE) Visual C++

  • Диалоговые окна, созданные в ПРИЛОЖЕНИЯх ATL, MFC и Win32, теперь соответствуют рекомендациям по стилю Windows Vista. При создании проекта с помощью Visual Studio 2008 все диалоговые окна, вставляемые в приложение, соответствуют руководству по стилю Windows Vista. При перекомпиляции проекта, созданного с помощью более ранней версии Visual Studio, все существующие диалоговые окна сохранят предыдущий внешний вид. Дополнительные сведения о вставке диалоговых окон в приложение см. в разделе Редактор диалоговых окон.

  • Мастер проектов ATL теперь позволяет регистрировать компоненты для всех пользователей. Начиная с Visual Studio 2008 COM-компоненты и библиотеки типов, создаваемые мастером проектов ATL, регистрируются в узле HKEY_CURRENT_USER реестра, если только не выбрана регистрация компонентов для всех пользователей.

  • Мастер проектов ATL больше не позволяет создавать проекты ATL с атрибутами. Начиная с Visual Studio 2008 мастер проектов ATL не позволяет изменять состояние принадлежности нового проекта. Все создаваемые мастером проекты ATL стали неопределенными.

  • Запись данных в реестр можно перенаправить. С появлением Windows Vista для записи в определенные области реестра требуется запускать программу в режиме с повышенными правами. Постоянно запускать Visual Studio с повышенными правами нежелательно. Перенаправление по пользователям автоматически перенаправляет операции записи в реестр из HKEY_CLASSES_ROOT в HKEY_CURRENT_USER программных изменений.

  • Конструктор классов теперь имеет ограниченную поддержку машинного кода C++. В более ранних версиях Visual Studio конструктор классов работал только с Visual C# и Visual Basic. Теперь пользователи C++ могут использовать конструктор классов, но только в режиме для чтения. Дополнительные сведения об использовании конструктора классов в C++ см. в разделе Работа с кодом Visual C++ в конструкторе классов.

  • Мастер проектов больше не может создавать проект SQL Server на C++. Начиная с версии Visual Studio 2008, мастер создания проектов не поддерживает возможности создания проекта C++ SQL Server. Проекты SQL Server, созданные в более ранней версии Visual Studio, компилируются и работают правильно.

Библиотеки Visual C++

Общие

  • Приложения можно привязать к конкретным версиям библиотек Visual C++. Иногда приложение зависит от обновлений, внесенных в библиотеки Visual C++ после выпуска. В этом случае запуск приложения на компьютере с более ранними версиями библиотек может привести к непредвиденному поведению. Теперь вы можете привязать приложение к определенной версии библиотек, чтобы оно не запускалось на компьютере с более ранними их версиями.

Библиотека STL/CLR

  • Visual C++ теперь содержит библиотеку STL/CLR. Библиотека STL/CLR представляет собой упакованную библиотеку стандартных шаблонов (STL), подмножество стандартной библиотеки C++, и служит для использования с C++ и средой CLR .NET Framework. С помощью STL/CLR вы можете использовать все контейнеры, итераторы и алгоритмы STL в управляемой среде.

Библиотека MFC

  • Windows Vista поддерживает стандартные элементы управления. Было добавлено более 150 методов в 18 новых или существующих классах, чтобы обеспечить поддержку функций в Windows Vista или улучшить функциональность в текущих классах MFC.
  • Новый класс CNetAddressCtrl позволяет вводить и проверять IPv4- и IPv6-адреса или DNS-имена.
  • Новый класс CPagerCtrl упрощает использование элемента управления страничного навигатора Windows.
  • Новый класс CSplitButton упрощает использование элемента управления splitbutton Windows для выбора действия умолчанию или дополнительного действия.

Библиотека поддержки C++

  • В C++ появилась библиотека маршалинга. Библиотека маршалинга позволяет легко и просто маршалировать данные между собственной и управляемой средами. Эта библиотека является альтернативой более сложным и менее эффективным подходам, таким как использование PInvoke. Дополнительные сведения см. в разделе Общие сведения о маршалинге в C++.

Сервер ATL

  • Сервер ATL выпущен в виде проекта с общим исходным кодом.
  • Основная часть базы кода сервера ATL была выпущена в виде проекта с общим исходным кодом в CodePlex и не устанавливается вместе с Visual Studio 2008. Некоторые файлы, связанные с сервером ATL, больше не являются частью Visual Studio. Список удаленных файлов см. в разделе Удаленные файлы сервера ATL.
  • Классы кодирования и декодирования данных из файла atlenc.h и служебных функций и классы из файлов atlutil.h и atlpath.h теперь входят в библиотеку ATL.
  • Корпорация Майкрософт продолжит поддерживать версии сервера ATL, включенные в состав более ранних версий Visual Studio, пока поддерживаются эти версии Visual Studio. CodePlex продолжит разработку кода сервера ATL как проекта сообщества. Корпорация Майкрософт не поддерживает CodePlex-версию сервера ATL.

Компилятор и компоновщик Visual C++

Изменения в компиляторе

  • Компилятор поддерживает управляемые добавочные сборки. Если указан этот параметр, компилятор не перекомпилирует код при изменении сборки, на которую указывает ссылка. Вместо этого он выполняет добавочную сборку. Файлы перекомпилируются только в том случае, если изменения затрагивают зависимый код.
  • Атрибуты, связанные с сервером ATL, больше не поддерживаются. Компилятор больше не поддерживает некоторые атрибуты, которые были связаны непосредственно с сервером ATL. Полный список удаленных атрибутов см. в разделе "Критические изменения".
  • Компилятор поддерживает микроархитектуру Intel Core. Компилятор содержит средство для настройки микроархитектуры Intel Core во время создания кода. По умолчанию оно включено и не может быть отключено, так как обеспечивает работу Pentium 4 и других процессоров.
  • Встроенные функции поддерживают более новые процессоры AMD и Intel. Несколько новых встроенных инструкций поддерживают дополнительные функциональные возможности в более новых процессорах AMD и Intel. Дополнительные сведения о новых встроенных функциях см. в следующих разделах: Дополнительные инструкции потокового SIMD-расширения 3, Дополнительные инструкции потокового SIMD-расширения 4, SSE4A и внутренние функции для расширенных поразрядных операций, Внутренние функции AES, _mm_clmulepi64_si128 и __rdtscp.
  • Функция __cpuid обновлена. Теперь функции __cpuid и __cpuidex поддерживают несколько новых возможностей из последних ревизий процессоров AMD и Intel. Встроенная функция __cpuidex собирает больше данных на новых процессорах.
  • Параметр компилятора /MP уменьшает общее время сборки. Параметр /MP позволяет значительно уменьшить общее время компиляции нескольких исходных файлов за счет создания нескольких процессов, компилирующих эти файлы одновременно. Этот параметр особенно полезен на компьютерах, поддерживающих технологию Hyper-Threading, несколько процессоров или несколько ядер.
  • Параметр /Wp64 компилятора и __w64 ключевое слово устарели. Параметр /Wp64 компилятора и __w64 ключевое слово, которые обнаруживают 64-разрядные проблемы переносимости, устарели и будут удалены в будущей версии компилятора. Вместо них рекомендуется использовать MSVC, ориентированный на 64-разрядную платформу.
  • /Qfast_transcendentals создает встроенный код для трансцендентных функций.
  • /Qimprecise_fwaits удаляет внутренние команды fwait для блоков try при использовании параметра компилятора /fp:except.

Изменения в компоновщике

  • Сведения о контроле учетных записей теперь внедряются в файлы манифеста для исполняемых файлов компоновщиком Visual C++ (link.exe). По умолчанию эта функция включена. Дополнительные сведения о том, как отключить эту функцию или изменить поведение по умолчанию, см. в разделе /MANIFESTUAC (встраивает в манифест сведения об UAC).
  • Теперь компоновщик имеет параметр /DYNAMICBASE, чтобы включить функцию Address Space Layout Randomization в Windows Vista. Этот параметр изменяет заголовок исполняемого файла, чтобы указать, требуется ли случайным образом переместить изменения из одной ветви в другую для приложения во время загрузки.

Новые возможности C++ в Visual Studio 2005

C++ 2005 с пакетом обновления 1 содержал следующие новые возможности:

Встроенные функции для x86 и x64

  • __halt
  • __lidt
  • __nop
  • __readcr8
  • __sidt
  • __svm_clgi
  • __svm_invlpga
  • __svm_skinit
  • __svm_stgi
  • __svm_vmload
  • __svm_vmrun
  • __svm_vmsave
  • __ud2
  • __vmx_off
  • __vmx_vmptrst
  • __writecr8

Встроенные функции только для x64

  • __vmx_on
  • __vmx_vmclear
  • __vmx_vmlaunch
  • __vmx_vmptrld
  • __vmx_vmread
  • __vmx_vmresume
  • __vmx_vmwrite

Новые ключевые слова языка

__sptr, __uptr

Новые функции компилятора

Этот выпуск компилятора содержит критические изменения.

  • 64-разрядные и кросс-компиляторы.
  • Добавлен параметр компилятора /analyze (корпоративный анализ кода).
  • Добавлен параметр компилятора /bigobj.
  • Добавлены теги /clr:pure, /clr:safe и /clr:oldSyntax. (Впоследствии отмечены как нерекомендуемые в Visual Studio 2015 и удалены в Visual Studio 2017.)
  • Устаревшие параметры компилятора: многие параметры компилятора в этом выпуске устарели. Дополнительные сведения см. в разделе Отмененные режимы компилятора.
  • В коде /clr уменьшено двойное преобразование, дополнительные сведения см. в разделе Двойное преобразование (С++).
  • Параметр /EH (модель обработки исключений) или /EHs больше невозможно использовать для перехвата исключения, вызванного не с помощью throw; используйте параметр /EHa.
  • Добавлен параметр /errorReport (отчет о внутренних ошибках компилятора).
  • Добавлен параметр компилятора /favor (оптимизация для 64).
  • Добавлен параметр компилятора /FA, /Fa (файл листинга).
  • Добавлен параметр компилятора /FC (полный путь к файлу исходного кода в папке Diagnostics).
  • Добавлен параметр компилятора /fp (определение поведения с плавающей запятой).
  • Добавлен параметр компилятора /G (оптимизация под процессор).
  • Добавлен параметр компилятора /G (оптимизация под процессор).
  • Параметры компилятора /G3, /G4, /G5, /G6, /G7 и /GB удалены. Теперь компилятор использует "смешанную модель", которая пытается создать оптимальный выходной файл для всех архитектур.
  • /Gf был удален. Используйте вместо него /GF (исключение повторяющихся строк).
  • /GL (оптимизация всей программы) теперь совместим с /CLRHEADER.
  • Теперь /GR включен по умолчанию.
  • Параметр /GS (проверка безопасности буфера) теперь обеспечивает защиту безопасности для уязвимых параметров указателей. Теперь /GS включен по умолчанию. /GS теперь также работает с функциями, скомпилированными в MSIL с параметром /clr (компиляция среды CLR).
  • Добавлен параметр компилятора /homeparams (копирование параметров регистров в стек).
  • Добавлен параметр компилятора /hotpatch (создание образа, допускающего оперативное обновление).
  • Обновлены эвристики встроенных функций; дополнительные сведения см. в разделе inline, __inline__forceinline inline_depth и inline_depth
  • Были добавлены многие новые встроенные функции, а также задокументированы многие из незадокументированных ранее.
  • По умолчанию любой неудачный вызов new выдает исключение.
  • Параметры компилятора /ML и /MLd удалены. Visual C++ больше не поддерживает однопоточную библиотеку CRT со статическим связыванием.
  • Компилятор реализует оптимизацию именованных возвращаемых значений, которая включается при компиляции с параметрами /O1, /O2 (наименьший размер, наибольшая скорость), /Og (глобальная оптимизация) и /Ox (полная оптимизация).
  • Параметр компилятора /Oa удален, но будет игнорироваться без уведомлений; используйте модификаторы noalias или restrict__declspec, чтобы указать, как компилятор присваивает псевдоним.
  • Удален параметр компилятора /Op. Используйте вместо него /fp (определение поведения с плавающей запятой).
  • Visual C++ теперь поддерживает OpenMP.
  • Добавлен параметр компилятора /openmp (включение поддержки OpenMP 2.0).
  • Параметр компилятора /Ow удален, но будет игнорироваться без уведомлений. Используйте модификаторы noalias или restrict__declspec, чтобы указать, как компилятор присваивает псевдоним.

Профильная оптимизация

  • /QI0f был удален.
  • /QIfdiv был удален.
  • Добавлен параметр компилятора /QIPF_B (список ошибок для пошагового выполнения B ЦП).
  • Добавлен параметр компилятора /QIPF_C (список ошибок для пошагового выполнения C ЦП).
  • Добавлен параметр компилятора /QIPF_fr32 (не используйте верхние регистры 96-разрядного формата с плавающей запятой).
  • Добавлен параметр компилятора /QIPF_noPIC (создание кода, зависящего от позиции).
  • Добавлен параметр компилятора /QIPF_restrict_plabels (предполагается, что функции во время выполнения не создаются).

Поддержка Юникода в компиляторе и компоновщике

  • Параметр /vd (отключение смещений при выполнении конструктора) теперь позволяет использовать оператор dynamic_cast для создаваемого объекта (/vd2).
  • Удален параметр компилятора /YX. Используйте вместо него /Yc (создание файла предкомпилированного заголовка) или /Yu (использование файла предкомпилированного заголовка). Если удалить /YX из конфигураций сборки, ничем его не заменив, это может привести к ускорению сборки.
  • Теперь /Zc:forScope включен по умолчанию.
  • Теперь /Zc:wchar_t включен по умолчанию.
  • Удален параметр компилятора /Zd. Отладочная информация, ограниченная номером строки, больше не поддерживается. Используйте вместо него /Zi (дополнительные сведения см. в разделе /Z7, /Zi, /ZI (формат отладочной информации)).
  • /Zg теперь можно использовать только для файлов исходного кода C, но не с файлами исходного кода C++.
  • Добавлен параметр компилятора /Zx (код Itanium, оптимизированный для отладки).

Новые функции языка

  • Attributeattribute считается устаревшим.
  • Добавлен параметр appdomain__declspec.
  • Добавлено соглашение о вызовах __clrcall.
  • Устаревший модификатор declspec (C++) теперь позволяет указать строку, которая будет отображаться во время компиляции, когда пользователь пытается получить доступ к устаревшему классу или устаревшей функции.
  • dynamic_cast Оператор имеет критические изменения.
  • Собственные перечисления теперь позволяют задать базовый тип.
  • Добавлен параметр jitintrinsicdeclspec.
  • Добавлен параметр noaliasdeclspec.
  • Добавлен параметр process__declspec.
  • abstract, override и sealed допустимы для компиляций в машинный код.
  • __restrictдобавлена ключевое слово.
  • Добавлен параметр restrictdeclspec.
  • __thiscallтеперь ключевое слово.
  • __unalignedключевое слово теперь документируется.
  • volatile (C++) обновил поведение в отношении оптимизаций.

Новые функции препроцессора

  • Добавлен предустановленный макрос __CLR_VER.
  • Директива pragma comment (C/C++) теперь принимает /MANIFESTDEPENDENCY в качестве комментария компоновщика. Параметр exestr для comment устарел.
  • Атрибут embedded_idl (директива #import) теперь принимает необязательный параметр.
  • pragma fenv_access
  • pragma float_control
  • pragma fp_contract
  • Глобальные переменные не будут инициализированы в том порядке, в котором объявлены, если они присутствуют в разделах директивы pragma managed, unmanaged и unmanaged. Это может быть критическим изменением, если, например, неуправляемая глобальная переменная инициализируется с использованием управляемых глобальных переменных и требуется полностью сформированный управляемый объект.
  • Разделы, указанные в init_seg, сейчас доступны только для чтения, а не для чтения и записи, как в предыдущих версиях.
  • Сейчас inline_depth имеет значение по умолчанию 16. Значение по умолчанию 16 также используется в Visual C++ .NET 2003.
  • Добавлен предустановленный макрос _INTEGRAL_MAX_BITS, см. раздел "Предустановленные макросы".
  • Добавлены предустановленные макросы _M_CEE, _M_CEE_PURE и _M_CEE_SAFE, см. раздел "Предустановленные макросы".
  • Добавлен предустановленный макрос _M_IX86_FP.
  • Добавлен предустановленный макрос _M_X64.
  • pragma make_public
  • Обновлен синтаксис pragma managed, unmanaged (теперь имеется push и pop)
  • На библиотеку mscorlib.dll теперь неявно ссылается директива #using во всех компиляциях /clr.
  • Добавлен предустановленный макрос _OPENMP.
  • Директива pragma optimize обновлена, a и w перестали быть допустимыми параметрами.
  • Добавлен атрибут no_registry#import.
  • Добавлены директивы pragma region, endregion
  • Добавлен предустановленный макрос _VC_NODEFAULTLIB.
  • Реализованы макросы с переменным числом аргументов.
  • Директива vtordisp устарела и будет удалена в одном из следующих выпусков Visual C++.
  • Директива pragma warning теперь имеет описатель suppress.

Новые функции компоновщика

  • Модули (не являющиеся сборками выходные файлы MSIL) теперь можно использовать в качестве входных данных компоновщика.
  • Добавлен параметр компоновщика /ALLOWISOLATION (поиск манифеста).
  • /ASSEMBLYRESOURCE (внедрение управляемого ресурса) теперь обновлен и позволяет указать имя ресурса в сборке и то, что такой ресурс является закрытым.
  • Добавлен параметр компоновщика /CLRIMAGETYPE (определение типа образа среды CLR).
  • Добавлен параметр компоновщика /CLRSUPPORTLASTERROR (сохранение кода последней ошибки для вызовов PInvoke).
  • Добавлен параметр компоновщика /CLRTHREADATTRIBUTE (указание атрибута потока среды CLR).
  • Добавлен параметр компоновщика /CLRUNMANAGEDCODECHECK (добавление атрибута SuppressUnmanagedCodeSecurityAttribute).
  • Добавлен параметр компоновщика /ERRORREPORT (создание отчетов о внутренних ошибках компоновщика).
  • Удален параметр компоновщика /EXETYPE. Компоновщик больше не поддерживает создание драйверов устройств Windows 95 и Windows 98. Используйте для этого подходящий соответствующий пакет DDK. Ключевое слово EXETYPE больше не является допустимым для файлов определений модулей.
  • Добавлен параметр компоновщика /FUNCTIONPADMIN (создание образа, допускающего оперативное обновление).
  • Параметр компоновщика /LTCG теперь поддерживается в модулях, скомпилированных с использованием /clr. Параметр /LTCG также был обновлен для поддержки профильных оптимизаций.
  • Добавлен параметр компоновщика /MANIFEST (создание манифеста параллельной сборки).
  • Добавлен параметр компоновщика /MANIFESTDEPENDENCY (определение зависимостей манифеста).
  • Добавлен параметр компоновщика /MANIFESTFILE (именование файла манифеста).
  • Удален параметр компоновщика /MAPINFO:LINES.
  • Добавлен параметр компоновщика /NXCOMPAT (совместимость с предотвращением выполнения данных).
  • Добавлен параметр компоновщика /PGD (указание базы данных для профильной оптимизации).
  • Добавлен параметр компоновщика /PROFILE (профилировщик средств оценки производительности).
  • Параметр компоновщика /SECTION (указание атрибутов секции) теперь поддерживает отрицание атрибутов и больше не поддерживает атрибуты L или D (связанные с VxD).
  • Поддержка Юникода в компиляторе и компоновщике
  • Параметр компоновщика /VERBOSE (печать сообщений о ходе выполнения) теперь принимает ICF и REF.
  • Удален параметр компоновщика /VXD. Компоновщик больше не поддерживает создание драйверов устройств Windows 95 и Windows 98. Используйте для этого подходящий соответствующий пакет DDK. Ключевое слово VXD больше не является допустимым для файлов определений модулей.
  • Удален параметр компоновщика /WS. Параметр /WS использовался для изменения образов, ориентированных на Windows NT 4.0. Вместо /WS можно использовать команду IMAGECFG.exe -R имя файла. IMAGECFG.exe находится на компакт-диске Windows NT 4.0 в каталоге SUPPORT\DEBUG\I386\IMAGECFG.EXE.
  • Теперь параметр компоновщика /WX (обработка предупреждений компоновщика как ошибки) задокументирован.

Новые функции служебной программы компоновщика

  • Добавлен параметр /ALLOWISOLATION программы editbin
  • Удален оператор DESCRIPTION файла определения модуля. Компоновщик больше не поддерживает сборку драйверов виртуальных устройств.
  • Добавлен параметр /ERRORREPORT в bscmake.exe, dumpbin.exe, editbin.exe и lib.exe.
  • Добавлен параметр /LTCG программы lib.
  • Добавлен параметр /NXCOMPAT программы editbin.
  • Добавлен параметр /RANGE программы dumpbin.
  • Добавлен параметр /TLS программы dumpbin.
  • Удален параметр /WS программы editbin. Параметр /WS использовался для изменения образов, ориентированных на Windows NT 4.0. Вместо /WS можно использовать команду IMAGECFG.exe -R имя файла. IMAGECFG.exe находится на компакт-диске Windows NT 4.0 в каталоге SUPPORT\DEBUG\I386\IMAGECFG.EXE.
  • Добавлен параметр /WX[:NO] программы lib.

Новые функции NMAKE

  • Добавлен /ERRORREPORT.
  • Добавлен /G.
  • Обновлены предопределенные правила.
  • Макрос $(MAKE), задокументированный в разделе "Макросы рекурсии", теперь предоставляет полный путь к nmake.exe.

Новые функции MASM

  • Выражения MASM теперь являются 64-разрядными значениями. В предыдущих версиях выражения MASM были 32-разрядными значениями.
  • При использовании инструкции __asm int 3 функция компилируется в машинный код.
  • ALIAS (MASM) теперь задокументирован.
  • Добавлен параметр /ERRORREPORT ml.exe и ml64.exe.
  • .FPO теперь задокументирован.
  • H2INC.exe не будет входить в состав Visual C++ 2005. Если вам нужно продолжить работу с H2INC, используйте H2INC.exe из предыдущей версии Visual C++.
  • Добавлен оператор IMAGEREL.
  • Добавлен оператор HIGH32.
  • Добавлен оператор LOW32.
  • ML64.exe — это версия MASM для архитектуры x64. Он собирает ASM-файлы x64 в файлы объектов x64. Встроенный язык ассемблера не поддерживается в компиляторе x64. Были добавлены следующие директивы MASM для ml64.exe (x64):
  • .ALLOCSTACK
  • .ENDPROLOG
  • .PUSHFRAME
  • .PUSHREG
  • .SAVEREG
  • .SAVEXMM128
  • .SETFRAME Кроме того, директива PROC была обновлена, чтобы использовать только синтаксис x64.
  • Добавлена директива MMWORD.
  • /omf (параметр командной строки ML.exe) теперь подразумевает /c. ML.exe не поддерживает связывание объектов формата OMF.
  • Директива SEGMENT теперь поддерживает дополнительные атрибуты.
  • Добавлен оператор SECTIONREL.
  • Добавлена директива XMMWORD.

Новые функции CRT

  • Были добавлены безопасные версии нескольких функций. Эти функции лучше обрабатывают ошибки и более строго контролируют буферы, что помогает устранить наиболее распространенные бреши безопасности. Эти новые безопасные версии обозначены суффиксом _s.
  • Имеющиеся версии функций, отличающиеся меньшей безопасностью, стали нерекомендуемыми. Чтобы отключить сообщения об устаревании, определите _CRT_SECURE_NO_WARNINGS.
  • Многие существующие функции теперь проверяют свои параметры и вызывают обработчик недопустимых параметров при передаче такого параметра.
  • Для многих существующих функций теперь установлен отсутствовавший ранее параметр errno.
  • Был добавлен typedef errno_t с типом integer. errno_t используется, когда тип возвращаемого функцией значения или параметр связан с кодами ошибок из errno. errno_t заменяет собой errcode.
  • Функции, зависящие от языкового стандарта, теперь имеют версии, которые принимают языковой стандарт в качестве параметра, а не используют текущий языковой стандарт. Эти новые функции имеют суффикс _l. Для работы с объектами языковых стандартов добавлено несколько новых функций. К новым функциям относятся _get_current_locale, _create_locale и _free_locale.
  • Были добавлены новые функции для поддержки блокировки и снятия блокировки дескрипторов файлов.
  • Семейство функций _spawn не сбрасывает errno в ноль в случае успешного выполнения, как это было в предыдущих версиях.
  • Доступны версии семейства функций printf, которые позволяют указать порядок использования аргументов.
  • Юникод теперь является поддерживаемым форматом текста. Функция _open поддерживает атрибуты _O_TEXTW, _O_UTF8 и _O_UTF16. Функция fopen поддерживает метод "ccs=ENCODING" для указания формата Юникод.
  • Доступна новая версия библиотек CRT, встроенная в управляемый код (MSIL), которая используется при компиляции с параметром /clr (компиляция среды CLR).
  • _fileinfo удален.
  • Размер по умолчанию для time_t теперь составляет 64 бита, что расширяет диапазон time_t и некоторых функций времени до 3000 года.
  • CRT теперь поддерживает указание языкового стандарта для каждого потока. Для поддержки этой возможности добавлена функция _configthreadlocale.
  • Добавлены функции _statusfp2 и __control87_2, чтобы разрешить использование контрольного слова с плавающей запятой на процессорах с плавающей запятой x87 и SSE2.
  • Добавлены функции _mkgmtime и _mkgmtime64, чтобы обеспечить поддержку преобразования времени (struct tm) на время по Гринвичу (GMT).
  • В swprintf и vswprintf были внесены изменения для лучшего соответствия стандарту.
  • Новый файл заголовка INTRIN.H предоставляет прототипы для некоторых встроенных функций.
  • Функция fopen теперь имеет атрибут N.
  • Функция _open теперь имеет атрибут _O_NOINHERIT.
  • Функция atoi теперь возвращает INT_MAX и задает для errno значение ERANGE при переполнении. В предыдущих версиях поведение при переполнении определено не было.
  • Семейство функций printf поддерживает шестнадцатеричные выходные данные с плавающей запятой, реализованные по стандарту ANSI C99 с использованием описателей типа формата %a и %A.
  • Семейство printf теперь поддерживает префикс размера "ll" (long long).
  • Функция _controlfp оптимизирована для повышения производительности.
  • Были добавлены отладочные версии нескольких функций.
  • Добавлены _chgsignl и _cpysignl (версии long double).
  • В таблицу типов добавлен тип _locale_t.
  • Добавлен новый макрос _countof для вычисления числа элементов в массиве.
  • В каждую статью о функциях добавлен раздел об эквивалентах .NET Framework.
  • Некоторые строковые функции теперь могут усекать строки, а не завершаться со сбоем, когда выходные буферы слишком малы; см. описание _TRUNCATE.
  • _set_se_translator теперь требует использования параметра компилятора /EHa.
  • fpos_t теперь __int64 находится в разделе /Za (для кода C) и когда stDC устанавливается вручную (для кода C++). Он использовался для того, чтобы быть struct.
  • _CRT_DISABLE_PERFCRIT_LOCKS может повысить производительность операций ввода-вывода для однопоточных программ.
  • Имена POSIX признаны нерекомендуемыми, вместо них используются имена, соответствующие стандартам ISO C++ (например, используйте _getch вместо getch).
  • Для режима pure доступны новые OBJ-файлы параметров компоновки.
  • _recalloc объединяет возможности realloc и calloc.

Новые возможности C++ в Visual Studio 2003

GNU C ++

  • Сведения о запуске управляемых расширений для приложения C++, созданного с помощью текущей версии компилятора, в предыдущей версии среды выполнения.
  • Часто задаваемые вопросы об управляемых расширениях для C++.
  • Добавлено пошаговое руководство, описывающее перенос существующего собственного приложения в целях использования управляемых расширений для C++: "Пошаговое руководство. Перенос существующего собственного приложения C++ для взаимодействия с компонентами .NET Framework".
  • Теперь можно создать делегат для метода типа значения.
  • Соответствие компилятора стандарту C++ было значительно расширено в Visual C++ .NET 2003.
  • Добавлен параметр компилятора /arch.
  • Параметр /Gf устарел и будет удален в следующей версии Visual C++.
  • Добавлен параметр компилятора /G7.
  • Параметр компилятора /GS был улучшен, чтобы защитить локальные переменные от прямого переполнения буфера.
  • Удален параметр компилятора /noBool. Теперь компилятор может bool отображаться только как ключевое слово (а не идентификатор) в файле исходного кода C++.
  • Теперь тип long long доступен как typedef__int64 примечание о том, что в CRT еще не поддерживается long long .
  • Параметр компилятора /Zm теперь указывает предел выделения памяти для предкомпилированного заголовка.
  • Встроенная функция _InterlockedCompareExchange теперь задокументирована.
  • Встроенная функция _InterlockedDecrement теперь задокументирована.
  • Встроенная функция _InterlockedExchange теперь задокументирована.
  • Встроенная функция _InterlockedExchangeAdd теперь задокументирована.
  • Встроенная функция _InterlockedIncrement теперь задокументирована.
  • Добавлена встроенная функция _ReadWriteBarrier.

Атрибуты

  • Атрибут implements теперь задокументирован.

Функции компоновщика

Добавлены следующие параметры компоновщика:

  • /ASSEMBLYDEBUG
  • /ASSEMBLYLINKRESOURCE
  • DELAYSIGN
  • /KEYFILE
  • /KEYCONTAINER
  • /SAFESEH

MASM

Добавлены директива .SAFESEH и параметр /safeseh ml.exe.

См. также

Руководство по переносу и обновлению Visual C++