Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Эта страница содержит все страницы о новых возможностях для всех версий 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.
Улучшения соответствия в обновлении 1 для Visual Studio 2015
Улучшения соответствия в обновлении 2 для Visual Studio 2015
Улучшения соответствия в обновлении 3 для Visual Studio 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
Было внесено изменение в оператор
delete
, чтобы привести его в соответствие со стандартом C++14. Сведения об изменении стандартов можно найти на странице Изменения в C++ для освобождения памяти с указанием размера. Изменения добавляют форму глобальногоdelete
оператора, который принимает параметр размера. Критическое изменение заключается в том, что если вы ранее использовали операторdelete
с той же сигнатурой (вместе с оператором placement new), вы получите ошибку компилятора (C2956, которая возникает в момент использования placement new, так как это позиция в коде, где компилятор пытается определить соответствующий операторdelete
).Функция
void operator delete(void *, size_t)
была размещаемым оператором delete, соответствующим размещаемой функции newvoid * operator new(size_t, size_t)
в C++11. При освобождении памяти с учетом размера в C++14, этаdelete
функция теперь является обычной функцией освобождения памяти (глобальныйdelete
оператор). Стандарт требует, чтобы, если использование placement new находит соответствующуюdelete
функцию и обнаруживает обычную функцию освобождения памяти, программа была с ошибкой описания.Например, предположим, что в коде определены и placement new, и placement delete:
void * operator new(std::size_t, std::size_t); void operator delete(void*, std::size_t) noexcept;
Проблема возникает из-за совпадения в сигнатурах функций между определенным оператором удаления размещения и новым глобальным оператором размера
delete
. Рассмотрите возможность использования типа, отличного отsize_t
, для любых операторов размещения new иdelete
. Обратите внимание, что типsize_t
typedef
зависит от компилятора; он являетсяtypedef
дляunsigned int
в Visual C++. Хорошим решением является использование перечисляемого типа, например:enum class my_type : size_t {};
Затем измените определение размещения
new
иdelete
, чтобы использовать этот тип в качестве второго аргумента вместоsize_t
. Кроме того, необходимо обновить вызовы placement new, чтобы передать новый тип (например, используяstatic_cast<my_type>
для преобразования из целочисленного значения) и обновить определениеnew
иdelete
, чтобы привести их обратно к целочисленному типу. Вам не нужно использоватьenum
для этого; также подойдёт тип класса с элементомsize_t
.Альтернативным решением может быть полное исключение оператора placement new. Если ваш код использует placement new для реализации пула памяти, где аргумент размещения является размером выделяемого или удаляемого объекта, то функция размерного освобождения может подойти для замены вашего собственного кода пула памяти. Вы можете избавиться от функций размещения и просто использовать свой собственный оператор с двумя аргументами
delete
вместо этих функций размещения.Если вы не хотите немедленно обновлять код, можно вернуться к старому поведению с помощью параметра компилятора
/Zc:sizedDealloc-
. Если вы используете этот параметр, функции с двумя аргументамиdelete
не существуют и не вызывают конфликта с вашим оператором размещения 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; }
Разрешение шаблонов
В разрешение имен для шаблонов были внесены изменения. При рассмотрении кандидатов на разрешение имени в 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 предупреждения(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_convertible теперь обнаруживает присваивание самому себе (стандартная библиотека) Предыдущие версии свойства типа
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 до тех пор, пока поддержка не будет удалена из компилятора, вы можете отключить это предупреждение, передав аргументы командной строки
/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) и несоответственное включение каталогов (влияет только на
/Wall
/WX
)Предыдущие версии компилятора принимали аргументы командной строки с несовпадающим каталогом включаемых файлов (
-I
) между компиляциями-Yc
и-Yu
при использовании файлов предкомпилированных заголовков. Компилятор больше не принимает код, написанный таким образом. Теперь для помощи в выявлении аргументов командной строки несовпадающих каталогов подключаемых файлов (-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:
- "Прозрачные функциональные операторы меньше<>, больше<>, плюс<>, умножить<> и т. д."
- make_unique<T>(args...) и make_unique<T[]>(n)
- Нечленские функции cbegin()/cend(), rbegin()/rend() и crbegin()/crend().
- <Atomic> получил множество улучшений производительности.
- <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.
Усовершенствования оптимизации с использованием профилей (PGO)
- Повышение производительности за счет уменьшения рабочего набора приложений, оптимизируемых с использованием вероятностного оптимизатора.
- Новый метод профилирования для оптимизации разработки приложений с использованием среды выполнения Windows (Windows Runtime).
Поддержка разработки приложений среды выполнения 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 ( объявление диапазона : выражение ). Это часть базовой языковой поддержки.
Лямбда-выражения без состояния, которые являются блоками кода, начинающимися с пустого интродьюсера лямбда-выражения [] и не захватывающими локальные переменные, теперь можно неявно преобразовать в указатели функций, как это предусмотрено стандартом 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++. В строке меню выберите Архитектура>Windows>Обозреватель архитектуры. Вы можете выбрать нужный узел, например Представление классов. В этом случае правая часть окна инструментов развертывается, отображая список пространств имен. Если выбрать пространство имен, появляется новый столбец со списком классов, структур и перечислений в этом пространстве имен. Вы можете продолжить просмотр ресурсов или вернуться в крайний левый столбец для запуска другого запроса. См. раздел Поиск кода с помощью обозревателя архитектуры.
Объем протестированного кода
Покрытие кода было обновлено, чтобы динамически проводить инструментализацию бинарных файлов во время выполнения. Это уменьшает временные затраты на настройку и повышает производительность. Вы также можете собирать данные об объеме протестированного кода из модульных тестов для приложений C++. В случае создания модульных тестов C++ вы можете использовать обозреватель модульных тестов для просмотра тестов в решении. Чтобы запустить модульные тесты и собрать для них данные об объеме протестированного кода, в обозревателе модульных тестов выберите элемент Анализ покрытия кода. Вы можете изучить результаты покрытия кода в окне Результаты покрытия кода — в строке меню выберите Тест>Windows>Результаты покрытия кода.
Новые возможности 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
устарел. - Пятнадцать новых функций, например , и , были добавлены в заголовок алгоритма
find_if_not
copy_if
.is_sorted
<> - В заголовке <памяти> новая функция make_shared — это удобный, надежный и эффективный способ сделать общий указатель на объект одновременно созданным объектом.
- Последовательно связанные списки поддерживаются заголовком <forward_list> .
- Новые функции-члены
cbegin
,cend
,crbegin
иcrend
предоставляютconst_iterator
, который перемещается вперед или назад по контейнеру. - Заголовок <system_error> и связанные шаблоны поддерживают обработку ошибок системы низкого уровня. Члены класса
exception_ptr
можно использовать для переноса исключений между потоками. - Заголовок <codecvt> поддерживает преобразование различных кодировк символов Юникода в другие кодировки.
- Заголовочный файл <allocators> определяет несколько шаблонов, которые помогают выделять и освобождать блоки памяти для контейнеров, основанных на узлах.
- Существует множество обновлений случайного< заголовка>.
Библиотека 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, и подчеркивает их красной волнистой линией. Кроме того, IDE сообщает об ошибках IntelliSense в окно списка ошибок. Для отображения кода, который вызвал проблему, дважды щелкните ошибку в окне списка ошибок.
Включить функцию автозаполнения. Интегрированная среда разработки поддерживает автозавершение для ключевого слова #include
. При вводе #include
она создает раскрывающийся список допустимых файлов заголовка. Если продолжить ввод имени файла, среда отфильтровывает список соответствующим образом. Вы можете в любой момент выбрать в списке включаемый файл. Это позволяет быстро включать файлы, не зная их точное имя.
Перейти к. Диалоговое окно Перейти к позволяет найти все символы и файлы в проекте, соответствующие указанной строке. Результаты уточняются сразу после ввода дополнительных символов в строке поиска. Поле Результаты содержит число найденных элементов и помогает вам решить, нужно ли ограничить поиск. Поля Вид/область, Расположение и Предварительный просмотр помогают различать элементы с одинаковыми именами. Кроме того, вы можете расширить эту функцию для поддержки других языков программирования.
Параллельные отладка и профилирование. Отладчик Visual Studio поддерживает среду выполнения с параллелизмом и помогает устранять неполадки в приложениях с параллельной обработкой. Новый профилировщик с параллелизмом позволяет визуализировать общее поведение приложения. Кроме того, можно использовать новые окна инструментов, чтобы визуализировать состояние задач и их стеки вызовов.
Конструктор лент. Конструктор лент — это графический редактор, позволяющий создавать и изменять пользовательский интерфейс ленты MFC. Окончательный пользовательский интерфейс ленты представлен файлом ресурсов на основе XML (MFCRIBBON-MS). Для существующих приложений можно записать текущий пользовательский интерфейс ленты, временно добавив несколько строк кода и затем вызвав конструктор лент. После создания файла ресурсов ленты вы можете заменить ручной код пользовательского интерфейса ленты на несколько инструкций, загружающих ресурс ленты.
Иерархия вызовов. Окно Иерархия вызовов позволяет перейти ко всем функциям, вызываемым определенной функцией, или ко всем функциям, которые вызывают определенную функцию.
Инструменты
Мастер классов MFC. В Visual C++ 2010 снова появился популярный мастер классов MFC. Мастер классов MFC позволяет удобно добавлять в проект классы, сообщения и переменные, не редактируя наборы исходных файлов вручную.
Мастер ATL-контролов. Мастер элементов управления ATL больше не заполняет поле ProgID
автоматически. Если элемент управления ATL не имеет ProgID
, другие инструменты могут не работать с ним. Одним из примеров инструмента, требующего элементы управления ProgID
, является диалоговое окно Вставка активного элемента управления. Дополнительные сведения о диалоговом окне см. в разделе "Вставка элементов 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 Project не имеет опции для изменения атрибутированного статуса нового проекта. Все новые проекты 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
упрощает использование элемента управления Windows splitbutton для выбора стандартного или дополнительного действия.
Библиотека поддержки 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 - Были добавлены многие новые встроенные функции, а многие ранее незадокументированные теперь задокументированы.
- По умолчанию любой неудачный вызов 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 для комментирования теперь устарела. - Атрибут
embedded_idl
(директива#import
) теперь принимает необязательный параметр. - pragma
fenv_access
- pragma
float_control
- pragma
fp_contract
- Глобальные переменные не будут инициализированы в том порядке, в котором объявлены, если они присутствуют в разделах pragma managed, 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
, совместимый с блокировкой выполнения данных (Data Execution Prevention). - Добавлен параметр компоновщика
/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
(компиляция для общей языковой среды выполнения). - _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
(версии с длинной плавающей запятой). - В таблицу типов добавлен тип
_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
). - Для чистого режима доступны новые варианты компоновки .obj файлов.
-
_recalloc
объединяет возможностиrealloc
иcalloc
.
Новые возможности C++ в Visual Studio 2003
Компилятор
- Сведения о запуске управляемых расширений для приложения 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
- ДЕЛАЙСАЙН
- /KEYFILE
- /KEYCONTAINER
- /SAFESEH
MASM
Добавлены директива .SAFESEH и параметр /safeseh
ml.exe.