Historie změn Microsoft C/C++ 2003 – 2015
Tento článek popisuje všechny zásadní změny sady Visual Studio 2015, které se vrátí do sady Visual Studio 2003, a v tomto článku se termíny "nové chování" nebo "teď" týkají sady Visual Studio 2015 a novější. Termíny "staré chování" a "před" odkazují na Visual Studio 2013 a starší verze.
Informace o nejnovější verzi sady Visual Studio najdete v tématu Co je nového pro jazyk C++ v sadě Visual Studio a vylepšení shody jazyka C++ v sadě Visual Studio.
Poznámka:
Mezi sadou Visual Studio 2015 a Visual Studio 2017 neexistují žádné binární zásadní změny.
Když upgradujete na novou verzi sady Visual Studio, může dojít k chybám kompilace nebo modulu runtime v kódu, který se dříve zkompiloval a spustil správně. Změny v nové verzi, které způsobují takové problémy, se označují jako zásadní změny a obvykle je vyžadují úpravy ve standardu jazyka C++, podpisech funkcí nebo rozložení objektů v paměti.
Abyste se vyhnuli chybám za běhu, které jsou obtížné rozpoznat a diagnostikovat, doporučujeme nikdy staticky propojit binární soubory kompilované pomocí jiné verze kompilátoru. Když upgradujete projekt EXE nebo DLL, nezapomeňte také provést upgrade knihoven, na které odkazuje. Nepředávejte typy CRT (C Runtime) ani standardní knihovny C++ (standardní knihovna C++) mezi binárními soubory, včetně knihoven DLL, kompilovaných pomocí různých verzí kompilátoru. Další informace naleznete v tématu Potenciální chyby předávání objektů CRT přes hranice knihovny DLL.
Nikdy byste neměli psát kód, který závisí na konkrétním rozložení objektu, který není rozhraním MODELU COM nebo objektem POD. Pokud takový kód napíšete, musíte zajistit, aby po upgradu fungoval. Další informace naleznete v tématu Přenositelnost na hranicích ABI.
Kromě toho průběžná vylepšení shody kompilátoru můžou někdy změnit způsob, jakým kompilátor rozumí vašemu stávajícímu zdrojovému kódu. Během sestavení můžete například najít nové nebo jiné chyby nebo dokonce rozdíly v chování v kódu, který byl dříve sestaven a zdál se, že je správně spuštěný. I když tato vylepšení nejsou zásadními změnami, jako jsou ty, které jsou popsány v tomto dokumentu, možná budete muset udělat změny ve zdrojovém kódu, abyste mohli tyto problémy vyřešit:
Změny v souladu se sadou Visual Studio 2015
C Runtime Library (CRT)
Obecné změny
Refaktorované binární soubory
Knihovna CRT byla refaktorována do dvou různých binárních souborů: Univerzální CRT (ucrtbase), která obsahuje většinu standardních funkcí a knihovnu modulu runtime VC (vcruntime). Knihovna vcruntime obsahuje funkce související s kompilátorem, jako je zpracování výjimek a vnitřní funkce. Pokud používáte výchozí nastavení projektu, tato změna vás neovlivní, protože linker používá nové výchozí knihovny automaticky. Pokud jste nastavili vlastnost Linker projektu Ignorovat všechny výchozí knihovny na Ano nebo používáte
/NODEFAULTLIB
možnost linkeru na příkazovém řádku, musíte aktualizovat seznam knihoven (ve vlastnosti Další závislosti), aby zahrnovaly nové refaktorované knihovny. Nahraďte starou knihovnu CRT (libcmt.lib
,libcmtd.lib
,msvcrt.lib
msvcrtd.lib
) ekvivalentními refaktorovanými knihovnami. Pro každou ze dvou refaktorovaných knihoven existují statické (.lib) a dynamické (.dll) verze a verze (bez přípony) a ladicí verze (s příponou d). Dynamické verze mají knihovnu importu, se kterou propojíte. Tyto dvě refaktorované knihovny jsou Univerzální CRT, konkrétně ucrtbase.dll nebo ucrtbase.lib, ucrtbased.dll nebo ucrtbased.lib a knihovnu modulu runtime VC, verzilibvcruntime.lib
vcruntime.dll alibvcruntimed.lib
verzi vcruntimed.dll. Verze v sadě Visual Studio 2015 i Visual Studio 2017 je 140. Viz funkce knihovny CRT.
<locale.h>
localeconv
Funkce
localeconv
deklarovaná v národním prostředí.h teď funguje správně, když je povolené národní prostředí pro jednotlivá vlákna. V předchozích verzích knihovny by tato funkce vrátilalconv
data pro globální národní prostředí, nikoli národní prostředí vlákna.Pokud používáte národní prostředí pro jednotlivá vlákna, měli byste zkontrolovat použití
localeconv
. Pokud váš kód předpokládá, želconv
vrácená data jsou pro globální národní prostředí, měli byste je opravit.
<math.h>
Přetížení funkcí matematické knihovny jazyka C++
V předchozích verzích jsme
<math.h>
definovali některé, ale ne všechny přetížení jazyka C++ pro funkce matematické knihovny. Zbytek přetížení byl v<cmath>
hlavičce. Kód, který obsahuje<math.h>
pouze může mít problémy s řešením přetížení funkce. Nyní jsou přetížení jazyka C++ odebrána z<math.h>
a jsou nalezena pouze v<cmath>
.Chcete-li vyřešit chyby, uveďte
<cmath>
získání deklarací funkcí, které byly odebrány z<math.h>
. Tyto funkce byly přesunuty:double abs(double)
afloat abs(float)
double pow(double, int)
,float pow(float, float)
,float pow(float, int)
, ,long double pow(long double, long double)
long double pow(long double, int)
float
along double
verze funkcí s plovoucí desetinou čárkouacos
, ,atanh
,tgamma
tan
tanh
sqrt
acosh
asin
asinh
atan
atan2
cbrt
ceil
copysign
cos
cosh
erf
erfc
exp
exp2
expm1
fabs
fdim
floor
fma
fmax
fmin
fmod
frexp
hypot
ilogb
ldexp
lgamma
llrint
llround
log
log10
log1p
log2
lrint
lround
modf
nearbyint
nextafter
nexttoward
remainder
remquo
rint
round
scalbln
scalbn
sin
sinh
trunc
Pokud máte kód, který se používá
abs
s typem s plovoucí desetinou čárkou, který obsahuje<math.h>
pouze záhlaví, verze s plovoucí desetinou čárkou už nebudou k dispozici. Volání se teď vyřešíabs(int)
i s argumentem s plovoucí desetinou čárkou, která způsobí chybu:warning C4244: 'argument' : conversion from 'float' to 'int', possible loss of data
Oprava tohoto upozornění spočívá v nahrazení volání
abs
verzí s plovoucí desetinou čárkouabs
, napříkladfabs
pro dvojitý argument nebofabsf
plovoucí argument, nebo zahrnout<cmath>
záhlaví a pokračovat v použitíabs
.Shoda s plovoucí desetinou čárkou
Mnoho změn matematické knihovny bylo provedeno za účelem zlepšení souladu se specifikacemi IEEE-754 a C11 přílohy F s ohledem na zvláštní vstupy malých a malých písmen, jako jsou nan a infinity. Například tiché vstupy NaN, které byly často považovány za chyby v předchozích verzích knihovny, se už nezachází jako s chybami. Viz standard IEEE 754 a příloha F standardu C11.
Tyto změny nezpůsobí chyby v době kompilace, ale můžou způsobit, že se programy budou chovat jinak a správněji podle standardu.
FLT_ROUNDS
V sadě Visual Studio 2013 se makro FLT_ROUNDS rozšířilo na konstantní výraz, což bylo nesprávné, protože režim zaokrouhlování je možné konfigurovat za běhu, například voláním fesetroundu. Makro FLT_ROUNDS je teď dynamické a správně odráží aktuální režim zaokrouhlování.
<new>
a <new.h>
new
adelete
V předchozích verzích knihovny byly nové a odstraněné funkce operátoru definované implementací exportovány z knihovny DLL modulu runtime (například msvcr120.dll). Tyto funkce operátoru jsou nyní vždy staticky propojeny s binárními soubory, i když používáte knihovny DLL modulu runtime.
Nejedná se o zásadní změnu nativního nebo smíšeného kódu (
/clr
), ale pro kód zkompilovaný jako /clr:pure, tato změna může způsobit, že se váš kód nepodaří zkompilovat. Pokud kód zkompilujete jako/clr:pure
, možná budete muset kvůli této změně přidat#include <new>
nebo#include <new.h>
obejít chyby sestavení. Tato/clr:pure
možnost je v sadě Visual Studio 2015 zastaralá a v sadě Visual Studio 2017 není podporovaná. Kód, který musí být čistý, by měl být portován do C#.
<process.h>
_beginthread
a_beginthreadex
_beginthreadex
Funkce_beginthread
teď obsahují odkaz na modul, ve kterém je procedura vlákna definována po dobu trvání vlákna. To pomáhá zajistit, aby se moduly nenačítá, dokud se vlákno nespustí do dokončení.
<stdarg.h>
va_start
a odkazové typyPři kompilaci kódu jazyka C++ se teď ověřuje v době kompilace,
va_start
že argument předaný není typu odkazu. Argumenty typu odkazu jsou zakázány standardním jazykem C++.
<stdio.h>
a <conio.h>
Řada funkcí printf a scanf je teď definovaná jako vložená.
Definice všech
printf
funkcí bylyscanf
přesunuty vložené do<stdio.h>
,<conio.h>
a další hlavičky CRT. Tato změna způsobující chybu vede k chybě linkeru (LNK2019, nevyřešený externí symbol) pro všechny programy, které tyto funkce deklarovaly místně bez zahrnutí příslušných hlaviček CRT. Pokud je to možné, měli byste kód aktualizovat tak, aby zahrnoval hlavičky CRT (to znamená přidat#include <stdio.h>
) a vložené funkce, ale pokud nechcete kód upravit tak, aby zahrnoval tyto soubory hlaviček, je alternativním řešením přidatlegacy_stdio_definitions.lib
do vstupu linkeru.Pokud chcete tuto knihovnu přidat do vstupu linkeru v integrovaném vývojovém prostředí, otevřete místní nabídku uzlu projektu, zvolte Vlastnosti, potom v dialogovém okně Vlastnosti projektu, zvolte Linker a upravte vstup linkeru, který chcete přidat
legacy_stdio_definitions.lib
do seznamu odděleného středníkem.Pokud váš projekt odkazuje na statické knihovny, které byly zkompilovány s verzí sady Visual Studio starší než 2015, může linker hlásit nevyřešený externí symbol. Tyto chyby mohou odkazovat na vnitřní definice pro
_iob
,_iob_func
nebo související importy pro určité<stdio.h>
funkce ve formě imp*. Společnost Microsoft doporučuje při upgradu projektu překompilovat všechny statické knihovny s nejnovější verzí kompilátoru a knihoven jazyka C++. Pokud je knihovna třetí stranou, pro kterou zdroj není k dispozici, měli byste buď požádat o aktualizovaný binární soubor od třetí strany, nebo zapouzdřit použití této knihovny do samostatné knihovny DLL, kterou kompilujete se starší verzí kompilátoru a knihoven.Upozorňující
Pokud propojíte se sadou Windows SDK 8.1 nebo staršími verzemi, může dojít k těmto nevyřešeným chybám externího symbolu. V takovém případě byste měli chybu vyřešit přidáním legacy_stdio_definitions.lib do vstupu linkeru, jak je popsáno výše.
Při řešení potíží s nevyřešenými chybami symbolů se můžete pokusit
dumpbin.exe
prozkoumat symboly definované v binárním souboru. Zkuste následující příkazový řádek zobrazit symboly definované v knihovně.dumpbin.exe /LINKERMEMBER somelibrary.lib
získá a _getws
Funkce získání a _getws byly odebrány. Funkce Gets byla odebrána ze standardní knihovny jazyka C v C11, protože ji nelze bezpečně použít. Funkce _getws byla rozšíření Microsoftu, které bylo ekvivalentní k získání, ale pro široké řetězce. Jako alternativy k těmto funkcím zvažte použití fgetů, fgetws, gets_s a _getws_s.
_cgets a _cgetws
Funkce _cgets a _cgetws byly odebrány. Jako alternativy k těmto funkcím zvažte použití _cgets_s a _cgetws_s.
Formátování nekonečna a naN
V předchozích verzích by se definice a sítě NAN naformátovaly pomocí sady řetězců sentinelu specifických pro MSVC.
Nekonečno: 1,#INF
Quiet NaN: 1.#QNAN
Signaling NaN: 1.#SNAN
Neurčené naN: 1.#IND
Některé z těchto formátů můžou mít před znaménko a můžou být formátované mírně odlišně v závislosti na šířce a přesnosti pole (někdy s neobvyklými efekty by například
printf("%.2f\n", INFINITY)
tiskl 1,#J, protože #INF by bylo "zaokrouhleno" na dvoucifernou přesnost). C99 zavedl nové požadavky na to, jak se mají formátovat definice a sítě NaN. Implementace MSVC teď vyhovuje těmto požadavkům. Nové řetězce jsou následující:Nekonečno: inf
Quiet NaN: nan
Signaling NaN: nan(snan)
Neurčené naN: nan(ind)
Každá z těchto možností může být předponou znaménka. Pokud se použije specifikátor formátu s velkými písmeny (%F místo %f), vytisknou se řetězce velkými písmeny (
INF
místoinf
), jak je třeba.Funkce scanf byly upraveny tak, aby parsovaly tyto nové řetězce, takže tyto řetězce nyní prochází
printf
scanf
a .Formátování a analýza s plovoucí desetinou čárkou
Byly zavedeny nové algoritmy formátování a analýzy s plovoucí desetinou čárkou, aby se zlepšila správnost. Tato změna ovlivňuje řadu funkcí printf a scanf a funkcí, jako je strtod.
Staré algoritmy formátování by vygenerovaly pouze omezený počet číslic a pak by vyplnily zbývající desetinná místa nulou. Obvykle by mohly generovat řetězce, které by se vrátily zpět na původní hodnotu s plovoucí desetinnou čárkou, ale nebyly skvělé, pokud byste chtěli přesnou hodnotu (nebo nejbližší desítkové vyjádření). Nové algoritmy formátování generují tolik číslic, kolik je potřeba k reprezentaci hodnoty (nebo k vyplnění zadané přesnosti). Příkladem zlepšení; při tisku velkého výkonu dvou možností vezměte v úvahu výsledky:
printf("%.0f\n", pow(2.0, 80))
Starý výstup:
1208925819614629200000000
Nový výstup:
1208925819614629174706176
Staré algoritmy analýzy by považovaly pouze 17 významných číslic ze vstupního řetězce a zbývající číslice by zahodily. Tento přístup stačí k vygenerování úzké aproximace hodnoty představované řetězcem a výsledek je obvykle velmi blízko správnému zaokrouhlení výsledku. Nová implementace považuje všechny současné číslice a vytvoří správně zaokrouhlený výsledek pro všechny vstupy (až 768 číslic). Kromě toho tyto funkce nyní respektují režim zaokrouhlování (lze ovládat pomocí fesetroundu). Toto je potenciálně změna chování způsobující chybu, protože tyto funkce můžou výstupem různých výsledků. Nové výsledky jsou vždy správnější než staré výsledky.
Hexadecimální a nekonečno/Parsování plovoucí desetinné čárky NaN
Algoritmy parsování s plovoucí desetinnou čárkou teď budou parsovat šestnáctkové řetězce s plovoucí desetinnou čárkou (například řetězce generované specifikátory formátu %a %A printf) a všechny řetězce nekonečna a řetězce NaN generované funkcemi
printf
, jak je popsáno výše.%A a %a nula odsazení
Specifikátory formátu %a %A formátují číslo s plovoucí desetinnou čárkou jako šestnáctkové mantisy a binární exponent. V předchozích verzích
printf
by funkce nesprávně použily řetězce s nulovou nulou. Napříkladprintf("%07.0a\n", 1.0)
by se tiskl 00x1p+0, kde by se měl vytisknout 0x01p+0. Tato chyba byla opravena.%A a %a přesnost
Výchozí přesnost specifikátorů formátu %A a %a je 6 v předchozích verzích knihovny. Výchozí přesnost je nyní 13 pro shodu se standardem C.
Jedná se o změnu chování za běhu ve výstupu jakékoli funkce, která používá formátovací řetězec s %A nebo %a. Ve starém chování může být výstup používající specifikátor %A "1.1A2B3Cp+111". Výstup pro stejnou hodnotu je "1.1A2B3C4D5E6F7p+111". Pokud chcete získat staré chování, můžete zadat přesnost, například %.6A. Viz specifikace přesnosti.
Specifikátor %F
Specifikátor formátu nebo převodu %F je teď podporovaný. Funkčně odpovídá specifikátoru formátu %f s tím rozdílem, že infinity a sítě NAN jsou formátovány velkými písmeny.
V předchozích verzích se implementace použila k analýze F a N jako modifikátorů délky. Toto chování se datovalo zpět do věku segmentovaných adresních prostorů: tyto modifikátory délky byly použity k označení vzdálených a blízkých ukazatelů, v uvedeném pořadí, jako v %Fp nebo %Ns. Toto chování bylo odebráno. Pokud je %F zjištěn, je nyní považován za specifikátor formátu %F; Pokud je zjištěna hodnota %N, považuje se nyní za neplatný parametr.
Formátování exponentu
Specifikátory formátu %e a %E naformátují číslo s plovoucí desetinnou čárkou jako desetinnou čárku a exponent. Specifikátory formátu %g a %G také v některých případech formátují čísla v tomto formuláři. V předchozích verzích by CRT vždy vygeneroval řetězce s trojcifernými exponenty. Například
printf("%e\n", 1.0)
by se vytisklo číslo 1,000000e+000, což bylo nesprávné. Jazyk C vyžaduje, aby byl exponent reprezentován pouze jednou nebo dvěma číslicemi, budou vytištěny pouze dvě číslice.V sadě Visual Studio 2005 byl přidán globální přepínač shody: _set_output_format. Program může tuto funkci volat s argumentem _TWO_DIGIT_EXPONENT, aby bylo možné povolit odpovídající exponentní tisk. Výchozí chování bylo změněno na režim exponentu při tisku odpovídající standardům.
Ověření řetězce formátu
V předchozích verzích
printf
by funkcescanf
bezobslužně přijímaly mnoho neplatných formátových řetězců, někdy s neobvyklými efekty. Například %hlhlhld by byl považován za %d. Všechny neplatné řetězce formátu jsou nyní považovány za neplatné parametry.Ověření řetězce v režimu fopen
Vpředchozíchch
fopen
r+b+
Řetězce režimu jsou nyní zjištěny a považovány za neplatné parametry.režim _O_U8TEXT
Funkce _setmode nyní správně hlásí režim datových proudů otevřených in_O_U8TEXT režimu. V předchozíchverzích _O_WTEXT ch
Jedná se o zásadní změnu, pokud váš kód interpretuje režim _O_WTEXT pro datové proudy, kde kódování je UTF-8. Pokud vaše aplikace nepodporuje UTF_8, zvažte přidání podpory pro toto stále častější kódování.
snprintf a vsnprintf
Funkce snprintf a vsnprintf jsou teď implementované. Starší kód často poskytoval definice verzí maker těchto funkcí, protože nebyly implementovány knihovnou CRT, ale už nejsou potřeba v novějších verzích. Pokud je před zahrnutím
<stdio.h>
souboru snprintf nebo vsnprintf definován jako makro , kompilace nyní selže s chybou, která označuje, kde bylo makro definováno.Oprava tohoto problému obvykle spočívá v odstranění všech deklarací
snprintf
uživatelského kódu nebovsnprintf
v kódu uživatele.Tmpnam generuje použitelné názvy souborů.
V předchozích verzích
tmpnam
atmpnam_s
funkce vygenerovaly názvy souborů v kořenovém adresáři jednotky (například \sd3c.). Tyto funkce teď generují použitelné cesty k názvům souborů v dočasném adresáři.Zapouzdření SOUBORU
V předchozíchverzích
<stdio.h>
Knihovna byla změněna tak, aby skrývala podrobnosti implementace. V rámci této změny je teď SOUBOR definovaný<stdio.h>
neprůmyslným typem a jeho členové jsou nepřístupní mimo samotný CRT._outp a _inp
Funkce _outp, _outpw, _outpd, _inp, _inpw a _inpd byly odebrány.
<stdlib.h>
, <malloc.h>
a <sys/stat.h>
strtof a wcstof
Funkce
strtof
awcstof
funkce se nepodařilo nastaviterrno
na ERANGE, pokud hodnota nebyla reprezentovatelná jako float. Tato chyba byla specifická pro tyto dvě funkce; ,strtod
wcstod
strtold
awcstold
funkce nebyly ovlivněny. Tento problém je opravený a jedná se o změnu způsobující chybu za běhu.Zarovnané funkce přidělení
V předchozích verzích by zarovnané funkce přidělování (
_aligned_malloc
_aligned_offset_malloc
atd.) bezobslužně přijímaly požadavky na blok se zarovnáním 0. Požadované zarovnání musí být mocnina dvou, což neplatí pro nulu. Požadované zarovnání 0 je nyní považováno za neplatný parametr. Tento problém je opravený a jedná se o změnu způsobující chybu za běhu.Funkce haldy
Funkce
_heapadd
a funkce_heapset
_heapused
byly odebrány. Tyto funkce byly nefunkční od aktualizace CRT tak, aby používaly haldu Windows.smallheap
Možnost
smallheap
propojení byla odebrána. Viz Možnosti propojení._Stat
Řada
_stat
funkcí se používáCreateFile
v sadě Visual Studio 2015 místoFindFirstFile
jako v sadě Visual Studio 2013 a starších verzích. To znamená, že_stat
na cestě končící lomítkem proběhne úspěšně, pokud cesta odkazuje na adresář, na rozdíl od dříve, kdy by funkce chybovala s nastaveným parametremerrno
ENOENT
.
<string.h>
wcstok
Podpis
wcstok
funkce byl změněn tak, aby odpovídal tomu, co vyžaduje standard C. V předchozích verzích knihovny byl podpis této funkce:wchar_t* wcstok(wchar_t*, wchar_t const*)
Použil interní kontext pro jednotlivá vlákna ke sledování stavu napříč voláními, jak je tomu u
strtok
. Funkce teď má podpiswchar_t* wcstok(wchar_t*, wchar_t const*, wchar_t**)
a vyžaduje, aby volající předal kontext jako třetí argument funkci.Byla přidána nová
_wcstok
funkce se starým podpisem pro usnadnění přenosu. Při kompilaci kódu jazyka C++ existuje také vložené přetíženíwcstok
, které má starý podpis. Toto přetížení je deklarováno jako zastaralé. V kódu jazyka C můžete define_CRT_NON_CONFORMING_WCSTOK způsobit_wcstok
použití místowcstok
.
<time.h>
clock
V předchozích verzích
clock
byla funkce implementována pomocí rozhraní APIGetSystemTimeAsFileTime
systému Windows . Při této implementaci byla hodinová funkce citlivá na systémový čas, a proto nebyla nutně monotónní. Funkce hodin byla reimplementována z hlediskaQueryPerformanceCounter
a je nyní monotónní.fstat a _utime
V předchozích verzích
_stat
fstat
, a_utime
funkce zpracovávají letní čas nesprávně. Před sadou Visual Studio 2013 všechny tyto funkce nesprávně upravily standardní časy, jako by byly v letním čase.V sadě Visual Studio 2013 se problém vyřešil ve
_stat
skupině funkcí, ale podobné problémy vfstat
řadách funkcí a_utime
rodiny funkcí nebyly opraveny. Tato částečná oprava vedla k problémům kvůli nekonzistence mezi funkcemi._utime
Nynífstat
byly opraveny řadu funkcí, takže všechny tyto funkce nyní zpracovávají letní čas správně a konzistentně.asctime
V předchozích verzích
asctime
by funkce vložovala jednociferné dny s úvodní nulou, například:Fri Jun 06 08:00:00 2014
. Specifikace vyžaduje, aby tyto dny byly vycpávky s úvodní mezerou, jako vFri Jun 6 08:00:00 2014
. Tento problém byl opraven.strftime a wcsftime
wcsftime
Funkcestrftime
teď podporují specifikátory formátu %C, %D, %e, %F, %g, %G, %h, %n, %r, %R, %t, %T, %u a %V. Modifikátory E a O se navíc analyzují, ale ignorují.Specifikátor formátu %c je určen jako vytvoření "odpovídající reprezentace data a času" pro aktuální národní prostředí. V národním prostředí jazyka C musí být tato reprezentace stejná jako
%a %b %e %T %Y
, stejná forma, jakou vytváříasctime
. V předchozích verzích specifikátor formátu %c nesprávně formátoval časy pomocíMM/DD/YY HH:MM:SS
reprezentace. Tento problém byl opraven.timespec a TIME_UTC
Hlavička
<time.h>
teď definujetimespec
typ a funkci ze standardutimespec_get
C11. Kromě toho je nyní definováno makro TIME_UTC pro použití stimespec_get
funkcí. Tato aktualizace představuje zásadní změnu kódu, která má konfliktní definici pro kterýkoli z těchto identifikátorů.CLOCKS_PER_SEC
Makro CLOCKS_PER_SEC se teď rozbalí na celé číslo typu
clock_t
, jak to vyžaduje jazyk C.
Standardní knihovna C++
Pokud byte chtěli povolit nové optimalizace a kontroly ladění, implementace standardní knihovny C++ záměrně neumožňuje binární kompatibilitu mezi verzemi. Proto při použití standardní knihovny C++ nelze objektové soubory a statické knihovny, které jsou kompilovány pomocí různých verzí, směšovat v jednom binárním souboru (EXE nebo DLL) a objekty standardní knihovny C++ nelze předávat mezi binárními soubory, které jsou kompilovány pomocí různých verzí. Takovéto směšování objektů vyvolává chyby linkeru týkající se neshod _MSC_VER. (_MSC_VER je makro, které obsahuje hlavní verzi kompilátoru – například 1800 pro Visual Studio 2013.) Tato kontrola nedokáže rozpoznat kombinování knihoven DLL a nedokáže rozpoznat kombinování, které zahrnuje Visual Studio 2008 nebo starší.
Standardní knihovna C++ – zahrnutí souborů
V hlavičce standardní knihovny C++ byly provedeny některé změny struktury zahrnutí. Hlavičky standardní knihovny jazyka C++ mohou navzájem obsahovat nespecifikované způsoby. Obecně byste měli napsat kód tak, aby pečlivě zahrnoval všechny hlavičky, které potřebuje podle standardu C++, a nespoléhá na to, které hlavičky standardní knihovny C++ zahrnují další hlavičky standardní knihovny C++. Díky tomu je kód přenosný napříč verzemi a platformami. Nejméně dvě změny hlaviček v sadě Visual Studio 2015 ovlivňují uživatelský kód. Za prvé,
<string>
již neobsahuje<iterator>
. Za druhé, nyní deklarujestd::array
bez zahrnutí všech<array>
, které mohou přerušit kód pomocí následující kombinace konstruktorů kódu: váš kód má proměnnou s názvem "array" a máte direktivu using-direktivu "using namespace std;" a zahrnete hlavičku standardní knihovny jazyka C++ (například<functional>
) zahrnující<tuple>
, která nyní deklarujestd::array
.<tuple>
steady_clock
Implementace
<chrono>
steady_clock
se změnila tak, aby splňovala standardní požadavky jazyka C++ na stálost a monotonitu.steady_clock
je nyní založen naQueryPerformanceCounter
ahigh_resolution_clock
je nyní typedef prosteady_clock
. V důsledku toho je v sadě Visual Studiosteady_clock::time_point
nyní typedef prochrono::time_point<steady_clock>
; to však nemusí nutně být případ pro jiné implementace.alokátory a const
Nyní vyžadujeme porovnávání rovnosti a nerovnosti alokátoru, abychom přijali argumenty const na obou stranách. Pokud vaše alokátory definují tyto operátory takto,
bool operator==(const MyAlloc& other)
pak byste je měli aktualizovat a deklarovat jako členy const:
bool operator==(const MyAlloc& other) const
const – prvky
Standard C++ má vždy zakázané kontejnery prvků const (například
vector<const T>
).set<const T>
Visual Studio 2013 a starší tyto kontejnery přijali. V aktuální verzi se takové kontejnery nepodaří zkompilovat.std::allocator::d eallocate
V sadě Visual Studio 2013 a starších
std::allocator::deallocate(p, n)
ignoroval argument předaný pro n. Standard jazyka C++ vždy vyžaduje, aby n musel být roven hodnotě předané jako první argument vyvoláníallocate
, které vrátilo p. V aktuální verzi se ale zkontroluje hodnota n . Kód, který předává argumenty pro n , které se liší od standardních požadavků, může při běhu dojít k chybovému ukončení.hash_map a hash_set
Nestandardní soubory
<hash_map>
hlaviček a<hash_set>
jsou zastaralé v sadě Visual Studio 2015 a v budoucí verzi se odeberou. Použijte<unordered_map>
a<unordered_set>
místo toho.komparátory a operátory()
Asociativní kontejnery (
<map>
rodina) teď vyžadují, aby jejich komparátory měly operátory volání funkce s možností kont-callable. Následující kód v deklaraci srovnávací třídy se teď nepodaří zkompilovat:bool operator()(const X& a, const X& b)
Pokud chcete tuto chybu vyřešit, změňte deklaraci funkce na:
bool operator()(const X& a, const X& b) const
typové vlastnosti
Staré názvy pro vlastnosti typu ze starší verze konceptu C++ byly odebrány. V jazyce C++11 byly změněny a byly aktualizovány na hodnoty C++11 v sadě Visual Studio 2015. V následující tabulce jsou uvedeny staré a nové názvy.
Starý název Nový název add_reference add_lvalue_reference has_default_constructor is_default_constructible has_copy_constructor is_copy_constructible has_move_constructor is_move_constructible has_nothrow_constructor is_nothrow_default_constructible has_nothrow_default_constructor is_nothrow_default_constructible has_nothrow_copy is_nothrow_copy_constructible has_nothrow_copy_constructor is_nothrow_copy_constructible has_nothrow_move_constructor is_nothrow_move_constructible has_nothrow_assign is_nothrow_copy_assignable has_nothrow_copy_assign is_nothrow_copy_assignable has_nothrow_move_assign is_nothrow_move_assignable has_trivial_constructor is_trivially_default_constructible has_trivial_default_constructor is_trivially_default_constructible has_trivial_copy is_trivially_copy_constructible has_trivial_move_constructor is_trivially_move_constructible has_trivial_assign is_trivially_copy_assignable has_trivial_move_assign is_trivially_move_assignable has_trivial_destructor is_trivially_destructible launch::any a launch::sync policies
Nestandardní
launch::any
zásady alaunch::sync
zásady byly odebrány. Místo toho prolaunch::any
použitílaunch:async | launch:deferred
. Prolaunch::sync
použitílaunch::deferred
. Viz spuštění výčtu.
Rozhraní MFC a knihovna ATL
Knihovna MFC (Microsoft Foundation Classes)
není už součástí typické instalace sady Visual Studio kvůli své velké velikosti. Pokud chcete nainstalovat prostředí MFC, zvolte možnost Vlastní instalace v instalačním programu sady Visual Studio 2015. Pokud už máte nainstalovanou sadu Visual Studio 2015, můžete prostředí MFC nainstalovat opětovným spuštěním instalace sady Visual Studio . Zvolte možnost Vlastní instalace a pak zvolte Třídy služby Microsoft Foundation. Instalační program sady Visual Studio můžete spustit z Ovládací panely řídit programy a funkce nebo z instalačního média.
Distribuovatelný balíček Visual C++ stále zahrnuje i tuto knihovnu.
Concurrency Runtime
Výnos makra z Windows.h v konfliktu s souběžností::Context::Yield
Modul Concurrency Runtime dříve použil
#undef
k nedefinaci makra Yield, aby nedocházelo ke konfliktům mezi makrem Yield definovaným ve Windows.h aconcurrency::Context::Yield
funkcí. Tato#undef
akce byla odebrána a byla přidána nová nekonfliktní ekvivalentní volání rozhraní API concurrency::Context::YieldExecution . Pokud chcete obejít konflikty s funkcí Yield, můžete aktualizovat kód tak, aby místo toho volalYieldExecution
funkci, nebo název funkce ohraničovatYield
do závorek na webech volání, jak je znázorněno v následujícím příkladu:(concurrency::Context::Yield)();
Vylepšení shody kompilátoru v sadě Visual Studio 2015
Při upgradu kódu z předchozích verzí můžete také narazit na chyby kompilátoru, které jsou způsobeny vylepšeními shody v sadě Visual Studio 2015. Tato vylepšení neporušují binární kompatibilitu ze starších verzí sady Visual Studio, ale můžou způsobit chyby kompilátoru, ve kterých se předtím nevygenerovaly žádné. Další informace najdete v tématu Visual C++ What's New 2003 až 2015.
V sadě Visual Studio 2015 můžou probíhající vylepšení souladu kompilátoru někdy změnit způsob, jakým kompilátor rozumí vašemu existujícímu zdrojovému kódu. V důsledku toho můžete během sestavení narazit na nové nebo jiné chyby nebo dokonce na rozdíly v chování v kódu, který jste dříve vytvořili a zdáli se, že jsou správně spuštěné.
Tyto rozdíly naštěstí mají malý nebo žádný vliv na většinu zdrojového kódu. Pokud jsou k vyřešení těchto rozdílů potřeba zdrojový kód nebo jiné změny, opravy jsou obvykle malé a jednoduché. Zahrnuli jsme mnoho příkladů dříve přijatelného zdrojového kódu, které můžou být potřeba změnit (před) a opravy pro jejich opravu (po).
I když tyto rozdíly můžou ovlivnit zdrojový kód nebo jiné artefakty sestavení, nemají vliv na binární kompatibilitu mezi aktualizacemi verzí sady Visual Studio. Zásadní změna je vážnější a může ovlivnit binární kompatibilitu, ale tyto druhy přerušení binární kompatibility se vyskytují pouze mezi hlavními verzemi sady Visual Studio, například mezi sadou Visual Studio 2013 a sadou Visual Studio 2015. Informace o zásadních změnách, ke kterým došlo mezi sadou Visual Studio 2013 a Visual Studio 2015, najdete v tématu Změny shody sady Visual Studio 2015.
Vylepšení shody v sadě Visual Studio 2015
/Zc:forScope- možnost
Možnost
/Zc:forScope-
kompilátoru je zastaralá a bude odebrána v budoucí verzi.Command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release
Tato možnost se obvykle použila k povolení nestandardního kódu, který používá proměnné smyčky za bodem, kde by podle standardu měly být mimo rozsah. Bylo nutné pouze v případě, že jste kompilovali s
/Za
možností, protože bez/Za
použití proměnné smyčky for po ukončení smyčky je vždy povoleno. Pokud vás nezajímá shoda se standardy (například pokud váš kód nemá být přenositelný do jiných kompilátorů), můžete tuto možnost vypnout/Za
(nebo nastavit vlastnost Disable Language Extensions na Ne). Pokud vás zajímá psaní přenosného kódu vyhovujícího standardům, měli byste kód přepsat tak, aby odpovídal standardu přesunutím deklarace těchto proměnných do bodu mimo smyčku.// 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
Možnost kompilátoruMožnost kompilátoru
/Zg
(Generování prototypů funkcí) už není dostupná. Tato možnost kompilátoru byla dříve zastaralá.Testy jednotek s C++/CLI už nemůžete spouštět z příkazového řádku s mstest.exe. Místo toho použijte vstest.console.exe. Viz VSTest.Console.exe možnosti příkazového řádku.
proměnlivé klíčové slovo
mutable
Specifikátor třídy úložiště už není povolený na místech, kde se dříve zkompiloval bez chyby. Kompilátor teď zobrazí chybu C2071 (neplatná třída úložiště). Podle standardumutable
lze specifikátor použít pouze na názvy datových členů třídy a nelze jej použít u názvů deklarovaných const nebo static a nelze jej použít pro referenční členy.Představte si například následující kód:
struct S { mutable int &r; };
Předchozí verze kompilátoru to přijali, ale teď kompilátor zobrazí následující chybu:
error C2071: 'S::r': illegal storage class
Pokud chcete chybu opravit, odeberte redundantní
mutable
klíčové slovo.char_16_t a char32_t
V systému
typedef
už nemůžete používatchar16_t
aliasy,char32_t
protože tyto typy jsou nyní považovány za předdefinované. Pro uživatele a autory knihoven bylo běžné definovatchar16_t
achar32_t
jako aliasyuint16_t
auint32_t
v uvedeném pořadí.#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; }
Chcete-li aktualizovat kód, odeberte
typedef
deklarace a přejmenujte všechny ostatní identifikátory, které s těmito názvy kolidují.Parametry šablony bez typu
Při zadávání explicitních argumentů šablony se teď správně kontroluje kompatibilita typů s určitým kódem, který zahrnuje parametry šablony jiného typu. Například následující kód se zkompiloval bez chyby v předchozích verzích sady Visual Studio.
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>(); }
Aktuální kompilátor správně zobrazí chybu, protože typ parametru šablony neodpovídá argumentu šablony (parametr je ukazatel na člen const, ale funkce f není const):
error C2893: Failed to specialize function template 'void S2::f(void)'note: With the following template arguments:note: 'C=S1'note: 'Function=S1::f'
Pokud chcete tuto chybu vyřešit v kódu, ujistěte se, že typ argumentu šablony, který používáte, odpovídá deklarovanému typu parametru šablony.
__declspec(align)
Kompilátor už nepřijímá
__declspec(align)
funkce. Tento konstruktor byl vždy ignorován, ale nyní vytvoří chybu kompilátoru.error C3323: 'alignas' and '__declspec(align)' are not allowed on function declarations
Chcete-li tento problém vyřešit, odeberte
__declspec(align)
z deklarace funkce. Vzhledem k tomu, že neměl žádný vliv, odebrání nic nemění.Ošetření výjimek
Zpracování výjimek má několik změn. Za prvé, objekty výjimek musí být buď kopírovatelné nebo pohyblivé. Následující kód zkompilovaný v sadě Visual Studio 2013, ale nekompiluje se v sadě Visual Studio 2015:
struct S { public: S(); private: S(const S &); }; int main() { throw S(); // error }
Problémem je, že konstruktor kopírování je soukromý, takže objekt nelze zkopírovat tak, jak se děje v normálním průběhu zpracování výjimky. Totéž platí při deklaraci
explicit
konstruktoru kopírování .struct S { S(); explicit S(const S &); }; int main() { throw S(); // error }
Chcete-li aktualizovat kód, ujistěte se, že copy konstruktor pro váš objekt výjimky je
public
a není označenexplicit
.Zachycení výjimky podle hodnoty také vyžaduje, aby objekt výjimky byl kopírovatelný. Následující kód zkompilovaný v sadě Visual Studio 2013, ale nekompiluje se v sadě Visual Studio 2015:
struct B { public: B(); private: B(const B &); }; struct D : public B {}; int main() { try { } catch (D d) // error { } }
Tento problém můžete vyřešit změnou typu parametru
catch
pro odkaz na odkaz.catch (D& d) { }
Řetězcové literály následované makry
Kompilátor teď podporuje uživatelsky definované literály. V důsledku toho se řetězcové literály následované makry bez jakéhokoli zásahu prázdných znaků interpretují jako literály definované uživatelem, což může vést k chybám nebo neočekávaným výsledkům. Například v předchozích kompilátorech se následující kód úspěšně zkompiloval:
#define _x "there" char* func() { return "hello"_x; } int main() { char * p = func(); return 0; }
Kompilátor interpretoval tento kód jako řetězcový literál "hello", za kterým následuje makro, které je rozbalené do "tam", a potom byly dva řetězcové literály zřetězeny do jednoho. V sadě Visual Studio 2015 kompilátor interpretuje tuto sekvenci jako literál definovaný uživatelem, ale protože neexistuje žádná odpovídající uživatelsky definovaná literála
_x
, zobrazí chybu.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?
Chcete-li tento problém vyřešit, přidejte mezeru mezi řetězcový literál a makro.
Sousední řetězcové literály
Podobně jako v předchozím případě se vzhledem ke souvisejícím změnám analýzy řetězců v sousedních řetězcových literálech (širokých nebo úzkých znakových literálech) bez prázdných znaků interpretovaly jako jediný zřetězený řetězec v předchozích verzích Visaul C++. V sadě Visual Studio 2015 teď musíte mezi dva řetězce přidat prázdné znaky. Například musí být změněn následující kód:
char * str = "abc""def";
Pokud chcete tento problém vyřešit, přidejte mezi tyto dva řetězce mezeru:
char * str = "abc" "def";
Nové umístění a odstranění
Operátor provedl
delete
změnu, aby ji mohl převést do souladu se standardem C++14. Podrobnosti o změně standardů najdete v sadě C++ Sized Deallocation. Změny přidávají formu globálníhodelete
operátoru, který přebírá parametr velikosti. Změna způsobující chybu spočívá v tom, že pokud jste dříve používali operátordelete
se stejným podpisem (aby odpovídal novému operátoru umístění), zobrazí se chyba kompilátoru (C2956, ke kterému dochází v okamžiku, kdy se použije nové umístění, protože se jedná o pozici v kódu, kde se kompilátor pokusí identifikovat odpovídajícídelete
operátor).Funkce
void operator delete(void *, size_t)
byla operátorem odstranění umístění, který odpovídá nové funkcivoid * operator new(size_t, size_t)
umístění v jazyce C++11. U zrušení přidělení velikosti C++14 je tato funkce delete nyní obvyklou funkcí deallocation (globálnídelete
operátor). Standard vyžaduje, aby pokud použití nové umístění vyhledá odpovídající funkci odstranění a najde obvyklou funkci přidělení, program je špatně vytvořen.Předpokládejme například, že váš kód definuje nové umístění i odstranění umístění:
void * operator new(std::size_t, std::size_t); void operator delete(void*, std::size_t) noexcept;
K problému dochází z důvodu shody v podpisech funkce mezi operátorem odstranění umístění, který jste definovali, a novým operátorem globální velikosti
delete
. Zvažte, jestli můžete použít jiný typ nežsize_t
pro jakékoli nové umístění adelete
operátory. Typ je závislý na kompilátorusize_t
typedef
; jetypedef
to prounsigned int
v MSVC. Dobrým řešením je použít výčtový typ, například tento:enum class my_type : size_t {};
Pak změňte definici umístění nové a
delete
použít tento typ jako druhý argument místosize_t
. Budete také muset aktualizovat volání nového umístění tak, aby předala nový typ (například pomocístatic_cast<my_type>
převodu z celočíselné hodnoty) a aktualizovat definicinew
adelete
přetypovat zpět na typ celého čísla. Pro tento typ není nutné použítenum
. Typ třídy ssize_t
členem by také fungoval.Alternativním řešením je, že můžete zcela eliminovat nové umístění . Pokud váš kód používá nové umístění pro implementaci fondu paměti, ve kterém je argument umístění velikost objektu přidělený nebo odstraněný, může být funkce přidělení velikosti vhodná k nahrazení vlastního kódu fondu paměti a můžete se zbavit funkcí umístění a použít pouze vlastní operátor dvou argumentů
delete
místo funkcí umístění.Pokud nechcete kód okamžitě aktualizovat, můžete se vrátit ke starému chování pomocí možnosti
/Zc:sizedDealloc-
kompilátoru . Pokud použijete tuto možnost, funkce odstranění se dvěma argumenty neexistují a nezpůsobí konflikt s operátorem odstranění umístění.Sjednocovat datové členy
Datové členy sjednocení už nemůžou mít odkazové typy. Následující kód byl úspěšně zkompilován v sadě Visual Studio 2013, ale v sadě Visual Studio 2015 dojde k chybě.
union U1 { const int i; }; union U2 { int & i; }; union U3 { struct { int & i; }; };
Předchozí kód generuje následující chyby:
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
Pokud chcete tento problém vyřešit, změňte odkazové typy buď na ukazatel, nebo na hodnotu. Změna typu na ukazatel vyžaduje změny v kódu, který používá sjednocovací pole. Změna kódu na hodnotu by změnila data uložená ve sjednocení, což má vliv na jiná pole, protože pole v typech sjednocení sdílejí stejnou paměť. V závislosti na velikosti hodnoty může také změnit velikost sjednocení.
Anonymní sjednocení jsou nyní v souladu se standardem. Předchozí verze kompilátoru vygenerovaly explicitní konstruktor a destruktor pro anonymní sjednocení. Tyto funkce generované kompilátorem se odstraní v sadě Visual Studio 2015.
struct S { S(); }; union { struct { S s; }; } u; // C2280
Předchozí kód vygeneruje v sadě Visual Studio 2015 následující chybu:
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
Pokud chcete tento problém vyřešit, zadejte vlastní definice konstruktoru nebo destruktoru.
struct S { // Provide a default constructor by adding an empty function body. S() {} }; union { struct { S s; }; } u;
Sjednocení s anonymními strukturami
Aby bylo možné splňovat standard, chování modulu runtime se změnilo pro členy anonymních struktur v sjednoceních. Konstruktor pro anonymní členy struktury ve sjednocení již není implicitně volána při vytvoření takové sjednocení. Destruktor pro anonymní členy struktury ve sjednocení se také implicitně nevolá, když sjednocení přejde mimo rozsah. Vezměte v úvahu následující kód, ve kterém sjednocení U obsahuje anonymní strukturu, která obsahuje pojmenovanou členskou strukturu S, která má destruktor.
#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; }
V sadě Visual Studio 2013 se při vytvoření sjednocení volá konstruktor pro S a při vyčištění zásobníku pro funkci f se volá destruktor pro S. V sadě Visual Studio 2015 se ale konstruktor a destruktor nevolá. Kompilátor zobrazí upozornění na tuto změnu chování.
warning C4587: 'U::s': behavior change: constructor is no longer implicitly calledwarning C4588: 'U::s': behavior change: destructor is no longer implicitly called
Chcete-li obnovit původní chování, dejte anonymní struktuře název. Chování modulu runtime neanonymních struktur je stejné bez ohledu na verzi kompilátoru.
#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; }
Případně zkuste přesunout konstruktor a destruktor kódu do nových funkcí a přidat volání těchto funkcí z konstruktoru a destruktoru pro sjednocení.
#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; }
Rozlišení šablon
Změny překladu názvů pro šablony byly provedeny. V jazyce C++ může při zvažování kandidátů na překlad jména dojít k tomu, že jedna nebo více jmen, které je třeba vzít v úvahu jako potenciální shody, vytvoří neplatnou instanci šablony. Tyto neplatné instance obvykle nezpůsobují chyby kompilátoru, princip označovaný jako SFINAE (selhání nahrazení není chyba).
Pokud teď SFINAE vyžaduje, aby kompilátor vytvořil instanci specializace šablony třídy, všechny chyby, ke kterým dojde během tohoto procesu, jsou chyby kompilátoru. V předchozích verzích by kompilátor takové chyby ignoroval. Představte si například následující kód:
#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); }
Pokud kompilujete s aktuálním kompilátorem, zobrazí se následující chyba:
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 ]
Důvodem je to, že v okamžiku prvního vyvolání is_base_of třída
D
ještě nebyla definována.V tomto případě je oprava nepoužívat takové vlastnosti typu, dokud není definována třída. Pokud přesunete definice
B
souboru kódu aD
na začátek souboru kódu, chyba se vyřeší. Pokud jsou definice v souborech hlaviček, zkontrolujte pořadí příkazů include pro soubory hlaviček a ujistěte se, že jsou všechny definice tříd zkompilovány před tím, než se použijí problematické šablony.Konstruktory kopírování
V sadě Visual Studio 2013 i Visual Studio 2015 kompilátor vygeneruje konstruktor kopírování pro třídu, pokud má tato třída konstruktor přesunutí definovaný uživatelem, ale žádný konstruktor kopírování definovaný uživatelem. V Dev14 je tento implicitně vygenerovaný konstruktor kopírování označen také jako "= delete".
main deklarovaný jako extern "C" nyní vyžaduje návratový typ.
Následující kód teď vytvoří C4430.
extern "C" __cdecl main(){} // C4430
Pokud chcete chybu opravit, přidejte návratový typ:
extern "C" int __cdecl main(){} // OK
Parametr typename není v inicializátoru člena povolený.
Následující kód teď vytvoří C2059:
template<typename T> struct S1 : public T::type { S1() : typename T::type() // C2059 { } }; struct S2 { typedef S2 type; }; S1<S2> s;
Pokud chcete chybu opravit, odeberte
typename
ji z inicializátoru:S1() : T::type() // OK ...
Třída úložiště u explicitních specializace se ignoruje.
V následujícím kódu je specifikátor třídy statického úložiště ignorován.
template <typename T> void myfunc(T h) { } template<> static void myfunc(double h) // static is ignored { }
Konstanta použitá v static_assert uvnitř šablony třídy vždy selže.
Následující kód způsobí, že
static_assert
vždy selže:template <size_t some_value> struct S1 { static_assert(false, "default not valid"); // always invoked }; //other partial specializations here
Chcete-li tento problém vyřešit, zabalte hodnotu do
struct
:template <size_t some_value> struct constant_false { static const bool value = false; }; template <size_t some_value> struct S1 { static_assert(constant_false<some_value>::value, "default not valid"); }; //other partial specializations here
Pravidla vynucená pro předávání deklarací (Platí pouze pro C.)
Následující kód teď vytvoří C2065:
struct token_s; typedef int BOOL; typedef int INT; typedef int(*PFNTERM)(PTOKEN, BOOL, INT); // C2065: 'PTOKEN' : undeclared identifier
Chcete-li tento problém vyřešit, přidejte správné předávací deklarace:
struct token_s; typedef int BOOL; typedef int INT; // forward declarations: typedef struct token_s TOKEN; typedef TOKEN *PTOKEN; typedef int(*PFNTERM)(PTOKEN, BOOL, INT);
Konzistentnější vynucování typů ukazatelů funkcí
Následující kód teď vytvoří C2197:
typedef int(*F1)(int); typedef int(*F2)(int, int); void func(F1 f, int v1, int v2) { f(v1, v2); // C2197 }
Nejednoznačná volání přetížených funkcí
Následující kód nyní vytvoří C266: "N::bind": nejednoznačné volání přetížené funkce.
template<typename R, typename T, typename T1, typename A1> void bind(R(T::*)(T1), A1&&); namespace N { template <typename T, typename R, typename ... Tx> void bind(R(T::*)(Tx...), T* ptr); } using namespace N; class Manager { public: void func(bool initializing); void mf() { bind(&Manager::func, this); //C2668 } };
Chcete-li chybu opravit, můžete plně kvalifikovat
bind: N::bind(...)
volání na . Pokud je však tato změna manifestována prostřednictvím nelarovaného identifikátoru (C2065), může být vhodné tuto změnu opravit pomocíusing
deklarace.K tomuto vzoru často dochází u ComPtr a dalších typů v
Microsoft::WRL
oboru názvů.Oprava nesprávné adresy
Následující kód nyní vytvoří C2440: '=': nemůže převést z 'type *' na 'type'. Chybu opravíte tak, že změníte &(typ) na (typ) a (&f()) na (f()).
// C typedef void (*type)(void); void f(int i, type p); void g(int); void h(void) { f(0, &(type)g); } // C++ typedef void(*type)(void); type f(); void g(type); void h() { g(&f()); }
Řetězcový literál je konstantní pole.
Následující kód nyní vytvoří C2664: 'void f(void )': nemůže převést argument 1 z const char ()[2] na void *.
void f(void *); void h(void) { f(&__FUNCTION__); void *p = &""; }
Pokud chcete chybu opravit, změňte typ parametru funkce na
const void*
, nebo změňte texth
tak, aby vypadal takto:void h(void) { char name[] = __FUNCTION__; f( name); void *p = &""; }
Řetězce UDL C++11
Následující kód nyní vytvoří chybu C3688: neplatná přípona literálu "L"; Literal operator or literal operator template 'operator ""L' not found
#define MACRO #define STRCAT(x, y) x\#\#y int main(){ auto *val1 = L"string"MACRO; auto *val2 = L"hello "L"world"; std::cout << STRCAT(L"hi ", L"there"); }
Pokud chcete chybu opravit, změňte kód tak, aby přidal mezeru:
#define MACRO // Remove ##. Strings are automatically // concatenated so they aren't needed #define STRCAT(x, y) x y int main(){ //Add space after closing quote auto *val1 = L"string" MACRO; auto *val2 = L"hello " L"world"; std::cout << STRCAT(L"hi ", L"there"); }
V předchozím
MACRO
příkladu už není analyzován jako dva tokeny (řetězec následovaný makrem). Teď se parsuje jako jeden token UDL. Totéž platí pro L"L", který byl analyzován dříve jako L a L" a nyní je analyzován jako L a "".Pravidla zřetězení řetězců byla rovněž přenesena do souladu se standardem, což znamená, že L"a" "b" je ekvivalentní L"ab". Předchozí edice sady Visual Studio nepřijaly zřetězení řetězců s jinou šířkou znaků.
Odebraný prázdný znak C++11
Následující kód nyní generuje chybu C2137: prázdná znaková konstanta
bool check(wchar_t c){ return c == L''; //implicit null character }
Pokud chcete chybu opravit, změňte kód tak, aby explicitně zobrazoval hodnotu null:
bool check(wchar_t c){ return c == L'\0'; }
Výjimky MFC nelze zachytit hodnotou, protože nejsou kopírovatelné.
Následující kód v aplikaci MFC nyní způsobuje chybu C2316: "D": nelze zachytit, protože destruktor a/nebo kopírovat konstruktor jsou nepřístupné nebo odstraněné.
struct B { public: B(); private: B(const B &); }; struct D : public B { }; int main() { try { } catch (D) // C2316 { } }
Pokud chcete kód opravit, můžete blok catch změnit na
catch (const D &)
, ale lepším řešením je obvykle použít makra MFC TRY/CATCH.alignof
je teď klíčové slovo.Následující kód nyní vytvoří chybu C2332: class: chybějící název značky. Chcete-li opravit kód, musíte přejmenovat třídu nebo, pokud třída provádí stejnou práci jako
alignof
, stačí nahradit třídu novým klíčovým slovem.class alignof{}
constexpr
je teď klíčové slovo.Následující kód nyní generuje chybu C2059: syntaktická chyba: ')'. Chcete-li opravit kód, musíte přejmenovat všechny názvy funkcí nebo proměnných, které jsou volána
constexpr
.int constexpr() {return 1;}
Pohyblivé typy nemohou být const
Pokud funkce vrátí typ, který má být přesunut, jeho návratový typ by neměl být
const
.Odstraněné konstruktory kopírování
Následující kód nyní vytvoří C2280 S::S(S &&): pokouší se odkazovat na odstraněnou funkci:
struct S{ S(int, int); S(const S&) = delete; S(S&&) = delete; }; S s2 = S(2, 3); //C2280
Pokud chcete chybu opravit, použijte přímou inicializaci pro
S2
:struct S{ S(int, int); S(const S&) = delete; S(S&&) = delete; }; S s2 = {2,3}; //OK
Převod na ukazatel funkce se vygeneruje pouze v případě, že se nezachytí lambda
Následující kód vytvoří C2664 v sadě Visual Studio 2015.
void func(int(*)(int)) {} int main() { func([=](int val) { return val; }); }
Pokud chcete chybu opravit, odeberte ji
=
ze seznamu zachycení.Nejednoznačná volání zahrnující operátory převodu
Následující kód nyní generuje chybu C2440: Přetypování typu: nelze převést z S2 na S1:
struct S1 { S1(int); }; struct S2 { operator S1(); operator int(); }; void f(S2 s2) { (S1)s2; }
Pokud chcete chybu opravit, explicitně volejte operátor převodu:
void f(S2 s2) { //Explicitly call the conversion operator s2.operator S1(); // Or S1((int)s2); }
Následující kód nyní vytvoří chybu C2593: operátor =je nejednoznačný:
struct S1 {}; struct S2 { operator S1&(); operator S1() const; }; void f(S1 *p, S2 s) { *p = s; }
Pokud chcete chybu opravit, explicitně volejte operátor převodu:
void f(S1 *p, S2 s) { *p = s.operator S1&(); }
Oprava neplatné inicializace kopírování v inicializaci nestatického datového členu (NSDMI)
Následující kód nyní generuje chybu C2664: S1::S1(S1 &&): Nemůže převést argument 1 z logické hodnoty na const S1 &:
struct S1 { explicit S1(bool); }; struct S2 { S1 s2 = true; // error };
Pokud chcete chybu opravit, použijte přímou inicializaci:
struct S2 { S1 s1{true}; // OK };
Přístup k konstruktorům uvnitř příkazů decltype
Následující kód nyní vytvoří C2248: S::S: nemůže získat přístup k privátnímu členu deklarovanému ve třídě S:
class S { S(); public: int i; }; class S2 { auto f() -> decltype(S().i); };
Chybu opravíte přidáním deklarace přítele pro
S2
:S
class S { S(); friend class S2; // Make S2 a friend public: int i; };
Výchozí ctor lambda se implicitně odstraní.
Následující kód nyní generuje chybu C3497: Nelze vytvořit instanci lambda:
void func(){ auto lambda = [](){}; decltype(lambda) other; }
Pokud chcete chybu opravit, odeberte potřebu volat výchozí konstruktor. Pokud lambda nic nezachytí, může se přetypovat na ukazatel funkce.
Lambdas s odstraněným operátorem přiřazení
Následující kód nyní vytvoří chybu C2280:
#include <memory> #include <type_traits> template <typename T, typename D> std::unique_ptr<T, typename std::remove_reference<D &&>::type> wrap_unique(T *p, D &&d); void f(int i) { auto encodedMsg = wrap_unique<unsigned char>(nullptr, [i](unsigned char *p) { }); encodedMsg = std::move(encodedMsg); }
Pokud chcete chybu opravit, nahraďte lambda třídou functoru nebo odeberte potřebu použití operátoru přiřazení.
Pokus o přesunutí objektu s odstraněným konstruktorem kopírování
Následující kód nyní generuje chybu C2280: moveable::moveable(const moveable &): pokus o odkaz na odstraněnou funkci
struct moveable { moveable() = default; moveable(moveable&&) = default; moveable(const moveable&) = delete; }; struct S { S(moveable && m) : m_m(m)//copy constructor deleted {} moveable m_m; };
Pokud chcete chybu opravit, použijte
std::move
místo toho:S(moveable && m) : m_m(std::move(m))
Místní třída nemůže odkazovat na jinou místní třídu definovanou později ve stejné funkci.
Následující kód nyní generuje chybu C2079: "s" používá nedefinovanou strukturu main::S2.
int main() { struct S2; struct S1 { void f() { S2 s; } }; struct S2 {}; }
Chybu opravíte tak, že přesunete definici
S2
:int main() { struct S2 { //moved up }; struct S1 { void f() { S2 s; } }; }
Nelze volat chráněný základní ctor v těle odvozeného ctoru.
Následující kód nyní generuje chybu C2248: S1::S1: Nemůže získat přístup k chráněnému členu deklarovanému ve třídě S1.
struct S1 { protected: S1(); }; struct S2 : public S1 { S2() { S1(); } };
Pokud chcete chybu opravit,
S2
odeberte voláníS1()
z konstruktoru a v případě potřeby ji vložte do jiné funkce.{} zabraňuje převodu na ukazatel
Následující kód nyní vytvoří C2439 S::p: člen nelze inicializovat.
struct S { S() : p({ 0 }) {} void *p; };
Pokud chcete chybu opravit, odeberte závorky z okolí
0
nebo jiného použitínullptr
, jak je znázorněno v tomto příkladu:struct S { S() : p(nullptr) {} void *p; };
Nesprávná definice a použití maker v závorkách
Následující příklad nyní vygeneruje chybu C2008: ;: neočekávaná v definici makra
#define A; //cause of error struct S { A(); // error };
Pokud chcete tento problém vyřešit, změňte horní čáru na
#define A();
Následující kód vytvoří chybu C2059: syntaktická chyba: ')'
//notice the space after 'A' #define A () ; struct S { A(); };
Pokud chcete kód opravit, odeberte mezeru mezi A a ().
Následující kód způsobí chybu C2091: funkce vrátí funkci:
#define DECLARE void f() struct S { DECLARE(); };
Chcete-li chybu opravit, odeberte závorky za deklarací v S:
DECLARE;
.Následující kód způsobí chybu C2062: typ int neočekávaně.
#define A (int) struct S { A a; };
Pokud chcete tento problém vyřešit, definujte
A
ho takto:#define A int
Extra parens v deklaracích
Následující kód způsobí chybu C2062: typ int neočekávaně.
struct S { int i; (int)j; };
Chcete-li chybu opravit, odeberte závorky kolem
j
. Pokud jsou závorky potřeba k přehlednosti, použijtetypedef
.Konstruktory generované kompilátorem a __declspec(novtable)
V sadě Visual Studio 2015 existuje větší pravděpodobnost, že kompilátor generované vložené konstruktory abstraktních tříd s virtuálními základními třídami mohou vystavit nesprávné použití
__declspec(novtable)
při použití v kombinaci s__declspec(dllimport)
.Auto vyžaduje v přímé inicializaci jeden výraz.
Následující kód nyní vytvoří chybu C3518: testPositions: v kontextu direct-list-initialization, který typ pro "auto" lze odvodit pouze z jednoho výrazu inicializátoru.
auto testPositions{ std::tuple<int, int>{13, 33}, std::tuple<int, int>{-23, -48}, std::tuple<int, int>{38, -12}, std::tuple<int, int>{-21, 17} };
Pokud chcete chybu opravit, jednou z možností je inicializace
testPositions
následujícím způsobem:std::tuple<int, int> testPositions[]{ std::tuple<int, int>{13, 33}, std::tuple<int, int>{-23, -48}, std::tuple<int, int>{38, -12}, std::tuple<int, int>{-21, 17} };
Kontrola typů a ukazatelů na typy pro is_convertible
Následující kód teď způsobí selhání statického kontrolního výrazu.
struct B1 { private: B1(const B1 &); }; struct B2 : public B1 {}; struct D : public B2 {}; static_assert(std::is_convertible<D, B2>::value, "fail");
Pokud chcete chybu opravit, změňte ji
static_assert
tak, aby porovnávala ukazatele naD
:B2
static_assert(std::is_convertible<D*, B2*>::value, "fail");
deklarace __declspec(novtable) musí být konzistentní
__declspec
deklarace musí být konzistentní ve všech knihovnách. Následující kód teď vytvoří porušení pravidla odr (one-definition rule)://a.cpp class __declspec(dllexport) A { public: A(); A(const A&); virtual ~A(); private: int i; }; A::A() {} A::~A() {} A::A(const A&) {} //b.cpp // compile with cl.exe /nologo /LD /EHsc /Osx b.cpp #pragma comment(lib, "A") class __declspec(dllimport) A { public: A(); A(const A&); virtual ~A(); private: int i; }; struct __declspec(novtable) __declspec(dllexport) B : virtual public A { virtual void f() = 0; }; //c.cpp #pragma comment(lib, "A") #pragma comment(lib, "B") class __declspec(dllimport) A { public: A(); A(const A&); virtual ~A(); private: int i; }; struct /* __declspec(novtable) */ __declspec(dllimport) B // Error. B needs to be novtable here also. : virtual public A { virtual void f() = 0; }; struct C : virtual B { virtual void f(); }; void C::f() {} C c;
Vylepšení shody v aktualizaci Update 1
Privátní virtuální základní třídy a nepřímá dědičnost
Předchozí verze kompilátoru umožnily odvozené třídě volat členské funkce jeho nepřímo odvozené
private virtual
základní třídy. Toto staré chování bylo nesprávné a neodpovídá standardu C++. Kompilátor už nepřijímá kód napsaný tímto způsobem a v důsledku toho vydává chybu kompilátoru C2280.error C2280: 'void *S3::__delDtor(unsigned int)': attempting to reference a deleted function
Příklad (před)
class base { protected: base(); ~base(); }; class middle : private virtual base {}; class top : public virtual middle {}; void destroy(top *p) { delete p; // }
Příklad (za)
class base; // as above class middle : protected virtual base {}; class top : public virtual middle {}; void destroy(top *p) { delete p; }
- nebo -
class base; // as above class middle : private virtual base {}; class top : public virtual middle, private virtual bottom {}; void destroy(top *p) { delete p; }
Přetížený operátor new and operator delete
Předchozí verze kompilátoru umožňovaly, aby byl nový a nečlenový operátor odstraněný jako statický a deklarován v jiných oborech názvů než globální obor názvů. Toto staré chování vytvořilo riziko, že program nebude volat
new
implementaci nebodelete
operátora, kterou program chtěl, což vede k tichému špatnému chování za běhu. Kompilátor už nepřijímá kód napsaný tímto způsobem a místo toho vydává chybu kompilátoru 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.
Příklad (před)
static inline void * __cdecl operator new(size_t cb, const std::nothrow_t&) // error C2323
Příklad (za)
void * __cdecl operator new(size_t cb, const std::nothrow_t&) // removed 'static inline'
Kromě toho, i když kompilátor neposkytuje konkrétní diagnostiku, vložený operátor
new
se považuje za špatně vytvořený.Volání operátoru type() (převod definovaný uživatelem) u jiných typů než tříd
Předchozí verze kompilátoru umožňovaly volat "operator type()" u typů, které nejsou třídami, zatímco bezobslužné ignorování. Toto staré chování vytvořilo riziko tichého špatného generování kódu, což vedlo k nepředvídatelným chování modulu runtime. Kompilátor už nepřijímá kód napsaný tímto způsobem a místo toho vydává chybu kompilátoru C2228.
error C2228: left of '.operator type' must have class/struct/union
Příklad (před)
typedef int index_t; void bounds_check(index_t index); void login(int column) { bounds_check(column.operator index_t()); // error C2228 }
Příklad (za)
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' }
Redundantní název typu v propracovaných specifikátorech typů
Předchozí verze kompilátoru byly povoleny
typename
ve specifikátoru propracovaného typu, ale kód napsaný tímto způsobem je sémanticky nesprávný. Kompilátor už nepřijímá kód napsaný tímto způsobem a místo toho vydává chybu kompilátoru C3406.error C3406: 'typename' cannot be used in an elaborated type specifier
Příklad (před)
template <typename class T> class container;
Příklad (za)
template <class T> // alternatively, could be 'template <typename T>'; 'typename' is not elaborating a type specifier in this case class container;
Odpočty typů polí ze seznamu inicializátorů
Předchozí verze kompilátoru nepodporují odpočty typů polí ze seznamu inicializátorů. Kompilátor teď podporuje tuto formu odpočtu typů a v důsledku toho může být volání šablon funkcí pomocí seznamů inicializátorů nejednoznačné nebo může být zvoleno jiné přetížení než v předchozích verzích kompilátoru. Chcete-li tyto problémy vyřešit, program teď musí explicitně určit přetížení, které program zamýšlen.
Když toto nové chování způsobí řešení přetížení zvážit další kandidáta, který je stejně dobrý jako historický kandidát, volání se stane nejednoznačným a kompilátor vydá chybu kompilátoru C2668 jako výsledek.
error C2668: 'function' : ambiguous call to overloaded function.
Příklad 1: Nejednoznačné volání přetížené funkce (před)
// 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 }
Příklad 1: nejednoznačné volání přetížené funkce (za)
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); }
Když toto nové chování způsobí, že řešení přetížení považuje za dalšího kandidáta, který je lepší než historický kandidát, volání jednoznačně vyřeší nový kandidát, což způsobí změnu chování programu, která se pravděpodobně liší od programátora.
Příklad 2: změna rozlišení přetížení (před)
// 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 }); }
Příklad 2: změna rozlišení přetížení (po)
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 }); }
Obnovení upozornění příkazu switch
Předchozí verze kompilátoru odebrala některá upozornění související s
switch
příkazy. Tato upozornění se teď obnovila. Kompilátor nyní vydává obnovená upozornění a upozornění související s konkrétními případy (včetně výchozího případu) jsou nyní vydána na řádku obsahujícím případ off-end, nikoli na posledním řádku příkazu switch. V důsledku toho, že nyní tato upozornění vydáváte na různých řádcích než v minulosti, upozornění, která byla dříve potlačena použitím#pragma warning(disable:####)
, už nemusí být potlačena tak, jak má. Chcete-li tato upozornění potlačit podle očekávání, může být nutné přesunout#pragma warning(disable:####)
direktivu na řádek nad prvním případem urychlování. Toto jsou obnovená upozornění: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
Příklad C4063 (před)
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; } };
Příklad C4063 (za)
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; } };
Příklady dalších obnovených upozornění jsou uvedeny v jejich dokumentaci.
#include: použití specifikátoru nadřazeného adresáře .. in pathname (pouze ovlivňuje
/Wall
/WX
)Předchozí verze kompilátoru nezjistily použití specifikátoru nadřazeného adresáře .. v pathname direktiv
#include
. Kód napsaný tímto způsobem je obvykle určen k zahrnutí hlaviček, které existují mimo projekt nesprávným použitím cest relativních k projektu. Toto staré chování vytvořilo riziko, že program může být kompilován zahrnutím jiného zdrojového souboru, než je zamýšlený programátor, nebo že tyto relativní cesty nebudou přenosné do jiných prostředí sestavení. Kompilátor teď rozpozná a upozorní programátora na kód napsaný tímto způsobem a v případě povolení vydá volitelné upozornění kompilátoru C4464.warning C4464: relative include path contains '..'
Příklad (před)
#include "..\headers\C4426.h" // emits warning C4464
Příklad (za)
#include "C4426.h" // add absolute path to 'headers\' to your project's include directories
Kromě toho, i když kompilátor neposkytuje konkrétní diagnostiku, doporučujeme, aby specifikátor nadřazeného adresáře "." neměl být použit k určení adresářů zahrnutí projektu.
#pragma optimize() rozšiřuje konec posledního souboru hlaviček (pouze ovlivňuje
/Wall
/WX
)Předchozí verze kompilátoru nezjistily změny nastavení příznaku optimalizace, které uchytí hlavičkový soubor zahrnutý v jednotce překladu. Kompilátor nyní zjistí a upozorní programátora na kód napsaný tímto způsobem a vydá volitelné upozornění kompilátoru C4426 v umístění přesměrování
#include
, pokud je povoleno. Toto upozornění se vydává pouze v případě, že změny kolidují s příznaky optimalizace nastavené argumenty příkazového řádku kompilátoru.warning C4426: optimization flags changed after including header, may be due to #pragma optimize()
Příklad (před)
// C4426.h #pragma optimize("g", off) ... // C4426.h ends // C4426.cpp #include "C4426.h" // warning C4426
Příklad (za)
// 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"
Neshoda #pragma warning(push) a #pragma warning(pop) (pouze ovlivňuje
/Wall
/WX
)Předchozí verze kompilátoru nezjistily
#pragma warning(push)
změny stavu spárované se#pragma warning(pop)
změnami stavu v jiném zdrojovém souboru, který je zřídka zamýšlený. Toto staré chování vytvořilo riziko, že by program byl zkompilován s jinou sadou upozornění povolených než programátor zamýšlený, což může mít za následek tiché špatné chování modulu runtime. Kompilátor nyní rozpozná a upozorní programátora kódu napsaného tímto způsobem a vydá volitelné upozornění kompilátoru C5031 v umístění odpovídajícího#pragma warning(pop)
kódu , pokud je povoleno. Toto upozornění obsahuje poznámku odkazující na umístění odpovídajícího #pragma warning(push).warning C5031: #pragma warning(pop): likely mismatch, popping warning state pushed in different file
Příklad (před)
// 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 ...
Příklad (za)
// 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" ...
I když je kód napsaný tímto způsobem často úmyslný. Kód napsaný tímto způsobem je citlivý na změny v
#include
pořadí. Pokud je to možné, doporučujeme, aby soubory zdrojového kódu spravily stav upozornění vlastním způsobem.Nedostupné #pragma upozornění (nabízení) (pouze ovlivňuje
/Wall
/WX
)Předchozí verze kompilátoru nezjistily chybějící
#pragma warning(push)
změny stavu na konci jednotky překladu. Kompilátor nyní rozpozná a upozorní programátora kódu napsaného tímto způsobem a vydá volitelné upozornění kompilátoru C5032 v umístění chybějícího#pragma warning(push)
souboru , pokud je povoleno. Toto upozornění se vydává pouze v případě, že v jednotce překladu nejsou žádné chyby kompilace.warning C5032: detected #pragma warning(push) with no corresponding #pragma warning(pop)
Příklad (před)
// 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
Příklad (za)
// 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)
V důsledku vylepšeného sledování stavu upozornění #pragma mohou být vydána další upozornění.
Předchozí verze kompilátoru sledovaly #pragma stavu upozornění, které nejsou dostatečně dobré k vydání všech zamýšlených upozornění. Toto chování vytvořilo riziko, že určitá upozornění by byla účinně potlačena za okolností odlišných od programátora. Kompilátor nyní sleduje
#pragma warning
stav robustněji – zejména související se#pragma warning
změnami stavu uvnitř šablon – a volitelně vydává nová upozornění C5031 a C5032, které jsou určeny k tomu, aby programátoru pomohl najít nezamýšlené použití#pragma warning(push)
a#pragma warning(pop)
.V důsledku vylepšeného
#pragma warning
sledování změn stavu mohou být nyní vydána upozornění, která dříve nesprávně potlačená nebo upozornění související s dříve chybně diagnostikovanými problémy.Vylepšená identifikace nedostupného kódu
Změny standardní knihovny jazyka C++ a vylepšená schopnost volání vložených funkcí v předchozích verzích kompilátoru může kompilátoru umožnit prokázat, že určitý kód je nyní nedostupný. Toto nové chování může vést k novým a častějším vydaným instancím upozornění C4720.
warning C4720: unreachable code
V mnoha případech může být toto upozornění vydáno pouze při kompilaci s povolenými optimalizacemi, protože optimalizace můžou vyřaizovat více volání funkcí, eliminovat redundantní kód nebo jinak zajistit, že určitý kód je nedostupný. Zjistili jsme, že nové instance upozornění C4720 se často vyskytly v blocích try/catch , zejména v souvislosti s použitím příkazu std::find.
Příklad (před)
try { auto iter = std::find(v.begin(), v.end(), 5); } catch (...) { do_something(); // ok }
Příklad (za)
try { auto iter = std::find(v.begin(), v.end(), 5); } catch (...) { do_something(); // warning C4702: unreachable code }
Vylepšení shody v aktualizaci Update 2
V důsledku částečné podpory výrazu SFINAE mohou být vydána další upozornění a chyby.
Předchozí verze kompilátoru neanalyzovali určité druhy výrazů uvnitř
decltype
specifikátorů kvůli nedostatku podpory výrazu SFINAE. Toto staré chování bylo nesprávné a neodpovídá standardu C++. Kompilátor teď tyto výrazy parsuje a má částečnou podporu výrazu SFINAE kvůli probíhajícím vylepšením shody. Kompilátor proto nyní vydává upozornění a chyby zjištěné ve výrazech, které předchozí verze kompilátoru neanalyly.Když toto nové chování analyzuje
decltype
výraz, který obsahuje typ, který ještě nebyl deklarován, kompilátor vydá chybu kompilátoru C2039 jako výsledek.error C2039: 'type': is not a member of 'global namespace'
Příklad 1: použití nedelarovaného typu (před)
struct s1 { template < typename T> auto f() - > decltype(s2< T> ::type::f()); // error C2039 template< typename> struct s2 {}; }
Příklad 1 (za)
struct s1 { template < typename> // forward declare s2struct s2; template < typename T> auto f() - > decltype(s2< T> ::type::f()); template< typename> struct s2 {}; }
Když toto nové chování analyzuje
decltype
výraz, který chybí nezbytné použití klíčovéhotypename
slova k určení, že závislý název je typ, kompilátor vydá upozornění kompilátoru C4346 společně s chybou kompilátoru 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'
Příklad 2: Závislý název není typem (před).
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 };
Příklad 2 (za)
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
členské proměnné brání implicitně definovaným konstruktorům a operátorům přiřazení.Předchozí verze kompilátoru povolily třídu, která má
volatile
členské proměnné, aby byly automaticky generovány výchozí konstruktory kopírování/přesunutí a výchozí operátory přiřazení kopírování/přesunutí. Toto staré chování bylo nesprávné a neodpovídá standardu C++. Kompilátor nyní považuje třídu, která mávolatile
členské proměnné, aby měly operátory konstrukce a přiřazení nesouvisejí s triviálními operátory, což brání automatickému generování výchozích implementací těchto operátorů. Pokud je taková třída členem sjednocení (nebo anonymní sjednocení uvnitř třídy), konstruktory kopírování/přesunutí a operátory přiřazení kopírování/přesunutí sjednocení (nebo třídy obsahující anonymní sjednocení) budou implicitně definovány jako odstraněné. Pokus o vytvoření nebo zkopírování sjednocení (nebo třídy obsahující anonymní sjednocení) bez explicitního definování je chyba a kompilátor vydává chybu kompilátoru C2280 v důsledku toho.error C2280: 'B::B(const B &)': attempting to reference a deleted function
Příklad (před)
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
Příklad (za)
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
Statické členské funkce nepodporují kvalifikátory cv.
Předchozí verze sady Visual Studio 2015 umožňovaly statické členské funkce mít kvalifikátory cv. Toto chování je způsobeno regresí v sadě Visual Studio 2015 a Visual Studio 2015 Update 1; Visual Studio 2013 a předchozí verze kompilátoru zamítají kód napsaný tímto způsobem. Chování sady Visual Studio 2015 a Visual Studio 2015 Update 1 je nesprávné a neodpovídá standardu C++. Visual Studio 2015 Update 2 odmítne kód napsaný tímto způsobem a místo toho vydá chybu kompilátoru C2511.
error C2511: 'void A::func(void) const': overloaded member function not found in 'A'
Příklad (před)
struct A { static void func(); }; void A::func() const {} // C2511
Příklad(za)
struct A { static void func(); }; void A::func() {} // removed const
Předávání deklarace výčtu není v kódu WinRT povolené (pouze ovlivňuje
/ZW
)Kód zkompilovaný pro prostředí Windows Runtime (WinRT) neumožňuje
enum
deklaraci typů, podobně jako při kompilaci spravovaného kódu C++ pro rozhraní .Net Framework pomocí přepínače kompilátoru/clr
. Toto chování zajišťuje, že velikost výčtu je vždy známá a lze ji správně promítat do systému typů WinRT. Kompilátor odmítne kód napsaný tímto způsobem a vydá chybu kompilátoru C2599 společně s chybou kompilátoru C3197.error C2599: 'CustomEnum': the forward declaration of a WinRT enum is not allowed
error C3197: 'public': can only be used in definitions
Příklad (před)
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; } };
Příklad (za)
// forward declaration of CustomEnum removed namespace A { public enum class CustomEnum : int32 { Value1 }; } public ref class Component sealed { public: CustomEnum f() { return CustomEnum::Value1; } };
Přetížený operátor bez člena nový a operátor delete nemusí být deklarován jako vložený (úroveň 1 (
/W1
) ve výchozím nastavení).Předchozí verze kompilátoru nevyvolají upozornění, pokud jsou vložené funkce pro odstranění operátoru, který není členem. Kód napsaný tímto způsobem je špatně vytvořený (nevyžaduje se diagnostika) a může způsobit problémy s pamětí způsobené neshodou nových operátorů a operátorů odstranění (zejména při použití společně s přidělením velikosti), které může být obtížné diagnostikovat. Kompilátor teď vydává upozornění kompilátoru C4595, aby pomohl identifikovat kód napsaný tímto způsobem.
warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline
Příklad (před)
inline void* operator new(size_t sz) // warning C4595 { ... }
Příklad (za)
void* operator new(size_t sz) // removed inline { ... }
Oprava kódu napsaného tímto způsobem může vyžadovat, aby definice operátorů byly přesunuty z hlavičkového souboru a do odpovídajícího zdrojového souboru.
Vylepšení shody v aktualizaci Update 3
std::is_convertable teď detekuje vlastní přiřazení (standardní knihovna).
Předchozí verze
std::is_convertable
vlastnosti typu nezjistily správně přiřazení typu třídy při odstranění nebo privátním konstruktoru kopírování.std::is_convertable<>::value
Nyní je správně nastaven nafalse
při použití na typ třídy s odstraněným nebo privátním konstruktorem kopírování.K této změně není přidružená žádná diagnostika kompilátoru.
Příklad
#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");
V předchozích verzích kompilátoru statické kontrolní výrazy v dolní části tohoto příkladu pass, protože
std::is_convertable<>::value
byl nesprávně nastaven natrue
.std::is_convertable<>::value
Nyní je správně nastaven nafalse
, což způsobuje selhání statických kontrolních výrazů.Výchozí nebo odstraněné triviální kopie a konstruktory přesunutí respektují specifikátory přístupu.
Předchozí verze kompilátoru nezkontrolovaly specifikátor přístupu výchozích nebo odstraněných triviálních konstruktorů kopírování a přesunutí před povolením jejich zavolání. Toto staré chování bylo nesprávné a neodpovídá standardu C++. V některých případech toto staré chování vytvořilo riziko tichého chybného generování kódu, což vede k nepředvídatelným chováním za běhu. Kompilátor teď zkontroluje specifikátor přístupu výchozího nebo odstraněného triviálního kopírování a konstruktory přesunutí, aby zjistil, jestli se dá volat, a pokud ne, vydá upozornění kompilátoru C2248 v důsledku toho.
error C2248: 'S::S' cannot access private member declared in class 'S'
Příklad (před)
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 }
Příklad (za)
class S { public: S() = default; private: S(const S&) = default; }; void f(const S&); // pass S by reference int main() { S s; f(s); }
Vyřazení podpory kódu ATL s atributy (úroveň 1 (
/W1
) ve výchozím nastavení)Předchozí verze kompilátoru podporovaly kód ATL s atributy. Jako další fáze odebrání podpory pro atributovaný kód ATL, který začal v sadě Visual Studio 2008, byl atributovaný kód ATL zastaralý. Kompilátor teď vydává upozornění kompilátoru C4467, aby pomohl identifikovat tento druh zastaralého kódu.
warning C4467: Usage of ATL attributes is deprecated
Pokud chcete pokračovat v používání kódu ATL s atributy, dokud nebude podpora odebrána z kompilátoru, můžete toto upozornění zakázat předáním
/Wv:18
/wd:4467
argumentů příkazového řádku kompilátoru nebo přidáním#pragma warning(disable:4467)
do zdrojového kódu.Příklad 1 (před)
[uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")] class A {};
Příklad 1 (za)
__declspec(uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")) A {};
Někdy možná budete potřebovat nebo chcete vytvořit soubor IDL, abyste se vyhnuli zastaralým atributům ATL, jako v ukázkovém kódu níže.
Příklad 2 (před)
[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 { // ... };
Nejprve vytvořte soubor *.idl; vygenerovaný soubor vc140.idl lze použít k získání souboru *.idl obsahujícího rozhraní a poznámky.
Dále do sestavení přidejte krok MIDL, abyste měli jistotu, že se vygenerují definice rozhraní C++.
Příklad 2 IDL (za)
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; }; }
Pak použijte ATL přímo v implementačním souboru, jak je znázorněno v ukázkovém kódu níže.
Příklad 2 Implementace (za)
#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() };
Předkompilované soubory hlaviček (PCH) a neshodované direktivy #include (pouze ovlivňuje
/Wall
/WX
)Předchozí verze kompilátoru přijímaly neshodné
#include
direktivy ve zdrojových souborech mezi-Yc
a-Yu
kompilacemi při použití předkompilovaných hlaviček (PCH). Kód napsaný tímto způsobem už kompilátor nepřijímá. Kompilátor teď vydává upozornění kompilátoru CC4598, které pomáhá identifikovat neshodované#include
direktivy při použití souborů PCH.warning C4598: 'b.h': included header file specified for Ycc.h at position 2 does not match Yuc.h at that position
Příklad (před):
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"
Příklad (za)
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"
Předkompilované soubory hlaviček (PCH) a neshodované adresáře zahrnutí (pouze ovlivňuje
/Wall
/WX
)Předchozí verze kompilátoru akceptovaly neshodu, včetně argumentů příkazového řádku () adresáře (
-I
) kompilátoru mezi-Yc
kompilacemi a-Yu
při použití předkompilovaných souborů hlaviček (PCH). Kód napsaný tímto způsobem už kompilátor nepřijímá. Kompilátor teď vydává upozornění kompilátoru CC4599, aby při použití souborů PCH pomohl identifikovat neshodované argumenty adresáře () v adresáři .-I
warning C4599: '-I..' : specified for Ycc.h at position 1 does not match Yuc.h at that position
Příklad (před)
cl /c /Wall /Ycc.h -I.. X.cpp cl /c /Wall /Yuc.h Z.cpp
Příklad (za)
cl /c /Wall /Ycc.h -I.. X.cpp cl /c /Wall /Yuc.h -I.. Z.cpp
Změny shody sady Visual Studio 2013
Compiler
Poslední klíčové slovo teď vygeneruje nevyřešenou chybu symbolu, kde by se zkompilovala dříve:
struct S1 { virtual void f() = 0; }; struct S2 final : public S1 { virtual void f(); }; int main(S2 *p) { p->f(); }
V dřívějších verzích se nevystavila chyba, protože volání bylo
virtual
volání. Program by ale za běhu chybově ukončil. Nyní je přiřazena chyba linkeru, protože třída je nyní označena jako konečná. V tomto příkladu, chcete-li opravit chybu, byste propojit s obj, který obsahuje definiciS2::f
.Při použití přátelských funkcí v oborech názvů je nutné před odkazem na tuto funkci znovu před odkazem na tuto funkci nebo se zobrazí chyba, protože kompilátor teď odpovídá standardu ISO C++. Například tento příklad se už nekompiluje:
namespace NS { class C { void func(int); friend void func(C* const) {} }; void C::func(int) { NS::func(this); // error } }
Chcete-li tento kód opravit, deklarujte
friend
funkci:namespace NS { class C { void func(int); friend void func(C* const) {} }; void func(C* const); // conforming fix void C::func(int) { NS::func(this); }
Standard C++ neumožňuje explicitní specializaci ve třídě. Přestože kompilátor jazyka Microsoft C++ umožňuje v některých případech, například v následujícím příkladu, je nyní vygenerována chyba, protože kompilátor nepovažuje druhou funkci za specializaci prvního.
template < int N> class S { public: template void f(T& val); template < > void f(char val); }; template class S< 1>;
Chcete-li tento kód opravit, upravte druhou funkci:
template <> void f(char& val);
Kompilátor se už nepokusí tyto dvě funkce v následujícím příkladu nejednoznačit a teď vygeneruje chybu:
template< typename T> void Func(T* t = nullptr); template< typename T> void Func(...); int main() { Func< int>(); // error }
Chcete-li tento kód opravit, upřesněte volání:
template< typename T> void Func(T* t = nullptr); template< typename T> void Func(...); int main() { Func< int>(nullptr); // ok }
Než kompilátor odpovídá standardu ISO C++11, následující kód by se zkompiloval a způsobil
x
překlad typuint
:auto x = {0}; int y = x;
Tento kód se nyní přeloží
x
na typstd::initializer_list<int>
a způsobí chybu na dalším řádku, který se pokusí přiřaditx
k typuint
. (Ve výchozím nastavení neexistuje žádný převod.) Chcete-li tento kód opravit, použijteint
k nahrazeníauto
:int x = {0}; int y = x;
Agregační inicializace již není povolena, pokud typ hodnoty vpravo neodpovídá typu inicializované hodnoty vlevo a je vydána chyba, protože standard ISO C++11 vyžaduje jednotné inicializace, aby fungovala bez zužování převodů. Pokud byl dříve k dispozici zužující převod, bylo místo chyby vydáno upozornění kompilátoru (úroveň 4) C4242 .
int i = 0; char c = {i}; // error
Chcete-li tento kód opravit, přidejte explicitní zužující převod:
int i = 0; char c = {static_cast<char>(i)};
Následující inicializace už není povolená:
void *p = {{0}};
Chcete-li tento kód opravit, použijte některou z těchto forem:
void *p = 0; // or void *p = {0};
Vyhledávání názvů se změnilo. Následující kód se v kompilátoru C++ v sadě Visual Studio 2012 a Visual Studio 2013 vyřeší jinak:
enum class E1 { a }; enum class E2 { b }; int main() { typedef E2 E1; E1::b; }
V sadě Visual Studio 2012
E1
se výrazE1::b
přeložil na::E1
globální obor. V sadě Visual Studio 2013E1
se ve výrazuE1::b
překládá natypedef E2
definici vmain()
a má typ::E2
.Změnilo se rozložení objektu. Na platformě x 64 se může v porovnání z předchozími verzemi změnit rozložení objektů třídy. Pokud má
virtual
funkci, ale nemá základní třídu, která mávirtual
funkci, objektový model kompilátoru vloží ukazatel navirtual
tabulku funkcí za rozložení datového člena. To znamená, že rozložení nemusí být ve všech případech optimální. V předchozích verzích by se optimalizace pro platformu x64 pokusila vylepšit rozložení za vás, ale protože v složitých situacích s kódem nefungovala správně, byla odebrána v sadě Visual Studio 2013. Podívejte se například na tento kód:__declspec(align(16)) struct S1 { }; struct S2 { virtual ~S2(); void *p; S1 s; };
V sadě Visual Studio 2013 je výsledek x64
sizeof(S2)
48, ale v předchozích verzích se vyhodnotí jako 32. Chcete-li provést toto vyhodnocení na hodnotu 32 v kompilátoru jazyka C++ sady Visual Studio 2013 pro x64, přidejte fiktivní základní třídu, která mávirtual
funkci:__declspec(align(16)) struct S1 { }; struct dummy { virtual ~dummy() {} }; struct S2 : public dummy { virtual ~S2(); void *p; S1 s; };
Pokud chcete najít místa v kódu, která by se dřívější verze pokusila optimalizovat, použijte kompilátor z této verze společně s možností kompilátoru
/W3
a zapněte upozornění C4370. Příklad:#pragma warning(default:4370) __declspec(align(16)) struct S1 { }; struct S2 { virtual ~S2(); void *p; S1 s; };
Před sadou Visual Studio 2013 tento kód vypíše tuto zprávu: "upozornění C4370: S2: rozložení třídy se změnilo z předchozí verze kompilátoru kvůli lepšímu balení".
Kompilátor x86 má stejný neoptimální problém s rozložením ve všech verzích kompilátoru. Pokud je například tento kód je zkompilován pro platformu x86:
struct S { virtual ~S(); int i; double d; };
Výsledek
sizeof(S)
je 24. Pokud ale použijete alternativní řešení uvedené pro platformu x64, můžete ho snížit na 16:struct dummy { virtual ~dummy() {} }; struct S : public dummy { virtual ~S(); int i; double d; };
Standardní knihovna
Kompilátor C++ v sadě Visual Studio 2013 detekuje neshody v _ITERATOR_DEBUG_LEVEL, které byly implementovány v sadě Visual Studio 2010 a neshody RuntimeLibrary. K těmto neshodám dochází, když jsou možnosti kompilátoru /MT
(statická verze), /MTd
(statické ladění), /MD
(dynamická verze) a /MDd
(dynamické ladění) smíšené.
Pokud váš kód uznává šablony simulovaných aliasů předchozí verze, musíte ho změnit. Například místo
allocator_traits<A>::rebind_alloc<U>::other
, teď musíte říctallocator_traits<A>::rebind_alloc<U>
. I kdyžratio_add<R1, R2>::type
už to není nutné a nyní doporučujeme, abyste řekliratio_add<R1, R2>
, že se první zkompiluje, protožeratio<N, D>
je nutné mít "typ" pro snížený poměr, což bude stejný typ, pokud je již snížen.Musíte použít
#include <algorithm>
při volánístd::min()
nebostd::max()
.Pokud váš stávající kód používá simulovaný výčty s oborem v předchozí verzi – tradiční neskopované výčty zabalené v oborech názvů – musíte ho změnit. Pokud jste například odkazovali na typ
std::future_status::future_status
, teď musíte říctstd::future_status
. Většina kódu ale nemá vliv – napříkladstd::future_status::ready
se stále kompiluje.explicit operator bool()
je přísnější než operátor unspecified-bool-type().explicit operator bool()
umožňuje explicitní převody na logickou hodnotu ( například vzhledem k tomushared_ptr<X> sp
, že jsoustatic_cast<bool>(sp)
platné abool b(sp)
jsou platné) a logické testovatelné "kontextové převody" na logickou hodnotu – napříkladif (sp)
,!sp
,sp &&
cokoliv.explicit operator bool()
Zakáže však implicitní převody na logickou hodnotu, takže nemůžete řícibool b = sp;
a dát logický návratový typ, nemůžete řícireturn sp
.Teď, když jsou implementované skutečné variadické šablony, _VARIADIC_MAX a související makra nemají žádný vliv. Pokud stále definujete _VARIADIC_MAX, bude ignorován. Je-li potvrzen náš nástroj maker určený k podpoře simulovaných variadic šablon jiným způsobem, je nutné změnit váš kód.
Kromě běžných klíčových slov teď hlavičky standardní knihovny jazyka C++ zakázaly nahrazení makra přepsání a konečných klíčových slov citlivých na kontext.
reference_wrapper
,ref()
acref()
nyní zakázat vazbu na dočasné objekty.<random>
nyní přísně vynucuje své předpoklady pro kompilaci.Různé vlastnosti standardní knihovny jazyka C++ mají předběžnou podmínku "T musí být úplný typ". Přestože kompilátor nyní tuto předběžnou podmínku vynucuje přísněji, nemusí ji vynutit ve všech situacích. (Vzhledem k tomu, že porušení předpokladů standardní knihovny C++ aktivují nedefinované chování, standard nezaručuje vynucení.)
Standardní knihovna C++ nepodporuje
/clr:oldSyntax
.Specifikace C++11 měla
common_type<>
neočekávané a nežádoucí důsledky, zejména vracícommon_type<int, int>::type
.int&&
Kompilátor proto implementuje navrhované řešení problému pracovní skupiny knihovny 2141, který vracícommon_type<int, int="">::type
int
.Jako vedlejší účinek této změny už případ identity nefunguje (
common_type<T>
ne vždy vede k typuT
). Toto chování odpovídá navrhovanému řešení, ale přeruší veškerý kód, který se spoléhal na předchozí chování.Pokud požadujete vlastnost typu identity, nepoužívejte nestandardní
std::identity
vlastnost, která je definována,<type_traits>
protože nebude fungovat pro<void>
. Místo toho implementujte vlastní typovou vlastnost identity tak, aby vyhovovala vašim potřebám. Tady je příklad:template < typename T> struct Identity { typedef T type; };
Rozhraní MFC a knihovna ATL
Pouze Visual Studio 2013: Knihovna MFC MBCS není součástí sady Visual Studio, protože Unicode je tak populární a použití služby MBCS se výrazně odmítlo. Tato změna také udržuje MFC lépe zarovnané s Windows SDK, protože mnoho ovládacích prvků a zpráv má pouze kódování Unicode. Pokud však budete muset i nadále používat knihovnu MFC MBCS, můžete ji stáhnout z webu Stažení softwaru společnosti Microsoft na vícebajtové knihovně MFC pro Visual Studio 2013. Distribuovatelný balíček Visual C++ stále zahrnuje i tuto knihovnu. (Poznámka: Knihovna MBCS DLL je součástí součástí instalačních komponent jazyka C++ v sadě Visual Studio 2015 a novějších verzích).
Přístupnost pásu karet MFC se změní. Místo jednoúrovňové architektury je teď hierarchická architektura. Staré chování můžete stále používat voláním
CRibbonBar::EnableSingleLevelAccessibilityMode()
.CDatabase::GetConnect
metoda je odebrána. Aby se zlepšilo zabezpečení, připojovací řetězec se teď ukládají zašifrované a dešifrují se jenom podle potřeby. Nedá se vrátit jako prostý text. Řetězec lze získat pomocíCDatabase::Dump
metody.CWnd::OnPowerBroadcast
Podpis se změní. Podpis tohoto popisovače zprávy se změní na LPARAM jako druhý parametr.Podpisy se změní tak, aby vyhovovaly obslužné rutině zpráv. Seznamy parametrů u následujících funkcí se změnily a používají nově přidané popisovače zpráv ON_WM_ *:
CWnd::OnDisplayChange
namísto (WPARAM, LPARAM) na (UINT, int, int) tak, aby bylo možné nové ON_WM_DISPLAYCHANGE makro použít v mapě zpráv.CFrameWnd::OnDDEInitiate
namísto (WPARAM, LPARAM) na (CWnd*, UINT, UNIT), aby bylo možné v mapě zpráv použít nové ON_WM_DDE_INITIATE makro.CFrameWnd::OnDDEExecute
namísto (WPARAM, LPARAM) se změnila na (CWnd*, HANDLE), aby bylo možné v mapě zpráv použít nové ON_WM_DDE_EXECUTE makro.CFrameWnd::OnDDETerminate
změna na (CWnd*) jako parametr místo (WPARAM, LPARAM), aby bylo možné nové ON_WM_DDE_TERMINATE makro použít v mapě zpráv.CMFCMaskedEdit::OnCut
změna na žádné parametry místo (WPARAM, LPARAM), aby bylo možné nové ON_WM_CUT makro použít v mapě zpráv.CMFCMaskedEdit::OnClear
změna na žádné parametry místo (WPARAM, LPARAM), aby bylo možné nové ON_WM_CLEAR makro použít v mapě zpráv.CMFCMaskedEdit::OnPaste
změna na žádné parametry místo (WPARAM, LPARAM), aby bylo možné nové ON_WM_PASTE makro použít v mapě zpráv.
#ifdef
direktivy v souborech hlaviček MFC jsou odebrány. V souborech hlaviček MFC souvisejících s nepodporovanými verzemi systému Windows (WINVER < 0x0501
) jsou odebrány různé#ifdef
direktivy.Knihovna DLL ATL (atl120.dll) se odebere. Knihovna ATL je nyní poskytována jako záhlaví a statická knihovna (atls.lib).
Atlsd.lib, atlsn.lib a atlsnd.lib jsou odebrány. Knihovna Atls.lib již nemá závislosti na znakové sadě ani kód specifický pro ladění/vydání. Protože princip funkce je stejný pro Unicode/ANSI i ladění/vydání, je vyžadována pouze jedna verze knihovny.
Nástroj ATL/MFC Trace se odebere společně s knihovnou DLL KNIHOVNY ATL a mechanismus trasování je zjednodušený. Konstruktor
CTraceCategory
teď přebírá jeden parametr (název kategorie) a makra TRACE volají funkce generování sestav ladění CRT.
Zásadní změny sady Visual Studio 2012
Compiler
Možnost kompilátoru
/Yl
se změnila. Kompilátor ve výchozím nastavení používá tuto možnost, což může vést k LNK2011 chybám za určitých podmínek. Další informace naleznete v tématu /Yl (vložení odkazu PCH pro knihovnu ladění).V kódu, který je zkompilován pomocí
/clr
,enum
klíčové slovo třídy definuje výčt C++11, nikoli výčet CLR (Common Language Runtime). Pokud chcete definovat výčet CLR, musíte mít explicitní informace o jeho přístupnosti.Pomocí klíčového slova šablony můžete explicitně zrušit nejednoznačný název závislého názvu (shoda se standardem jazyka C++). V následujícím příkladu je zvýrazněné klíčové slovo šablony povinné k vyřešení nejednoznačnosti. Další informace naleznete v tématu Překlad názvů pro závislé typy.
template < typename X = "", typename = "" AY = ""> struct Container { typedef typename AY::template Rebind< X> ::Other AX; };
Konstantní výraz typu float již není povolen jako argument šablony, jak je znázorněno v následujícím příkladu.
template<float n=3.14> struct B {}; // error C2993: 'float': illegal type for non-type template parameter 'n'
Kód, který je zkompilovaný pomocí možnosti příkazového
/GS
řádku a který má ohrožení zabezpečení mimo jeden, může vést k ukončení procesu za běhu, jak je znázorněno v následujícím příkladu pseudokódu.char buf[MAX]; int cch; ManipulateString(buf, &cch); // ... buf[cch] = '\0'; // if cch >= MAX, process will terminate
Výchozí architektura sestavení x86 se změní na SSE2; kompilátor proto může generovat instrukce SSE a použije registru XMM k provádění výpočtů s plovoucí desetinou čárkou. Pokud se chcete vrátit k předchozímu chování, použijte příznak kompilátoru
/arch:IA32
k určení architektury jako IA32.Kompilátor může vydávat upozornění Upozornění kompilátoru (úroveň 4) C4703 a C4701, pokud předtím ne. Kompilátor používá silnější kontroly použití neinicializovaných místních proměnných typu ukazatele.
Pokud je zadán nový příznak
/HIGHENTROPYVA
linkeru, Systém Windows 8 obvykle způsobí, že přidělení paměti vrátí 64bitovou adresu. (Před Windows 8 se takové přidělení častěji vracely adresy, které byly menší než 2 GB.) Tato změna může vystavit chyby zkrácení ukazatele v existujícím kódu. Ve výchozím nastavení je tento přepínač zapnutý. Chcete-li toto chování zakázat, zadejte/HIGHENTROPYVA:NO
.Spravovaný kompilátor (Visual Basic/C#) také podporuje
/HIGHENTROPYVA
spravované sestavení. V tomto případě/HIGHENTROPYVAswitch
je ale ve výchozím nastavení vypnutý.
IDE
- Přestože doporučujeme nevytvořit model Windows Forms aplikace v C++/CLI, podporuje se údržba stávajících aplikací uživatelského rozhraní C++/CLI. Pokud potřebujete vytvořit model Windows Forms aplikaci nebo jinou aplikaci uživatelského rozhraní .NET, použijte jazyk C# nebo Visual Basic. Pro účely interoperability používejte pouze C++/CLI.
Knihovna paralelních vzorů a knihovna Concurrency Runtime
Výčet SchedulerType
UmsThreadDefault
je zastaralý. UmsThreadDefault
Specifikace vytvoří zastaralé upozornění a interně se mapuje zpět na ThreadScheduler
.
Standardní knihovna
Po změně způsobující chybu mezi standardy C++98/03 a C++11 pomocí explicitních argumentů šablony, které se mají volat
make_pair()
– stejně jako vmake_pair<int, int>(x, y)
– se obvykle nekompiluje v sadě Visual C++ v sadě Visual Studio 2012. Řešením je vždy volatmake_pair()
bez explicitních argumentů šablony – jako vmake_pair(x, y)
. Poskytnutí explicitníchargumentch Pokud požadujete přesnou kontrolu nad výsledným typem, použijtepair
místomake_pair
- jako vpair<short, short>(int1, int2)
.Další zásadní změna mezi standardy C++98/03 a C++11: Pokud se A implicitně konvertibilní na B a B implicitně převede na jazyk C, ale A není implicitně převést na C, C++98/03 a Visual Studio 2010 je povoleno
pair<A, X>
převádět (implicitně nebo explicitně) napair<C, X>
. (Druhý typ X, tady není zajímavý a není specifický pro první typ v páru.) Kompilátor C++ v sadě Visual Studio 2012 zjistí, že A není implicitně převoditelný na jazyk C, a odebere převod páru z rozlišení přetížení. Tato změna je pro mnoho scénářů pozitivní. Například přetíženífunc(const pair<int, int>&)
afunc(const pair<string, string>&)
volánífunc()
spair<const char *, const char *>
touto změnou se zkompiluje. Tato změna však přeruší kód, který se spoléhal na agresivní převody párů. Takový kód lze obvykle opravit provedením jedné části převodu explicitně – například předánímmake_pair(static_cast<B>(a), x)
funkce, která očekávápair<C, X>
.Simulované variadické šablony sady Visual Studio 2010 , například
make_shared<T>(arg1, arg2, argN)
– až do limitu 10 argumentů, pomocí razítka přetížení a specializace pomocí preprocesorových strojů. V sadě Visual Studio 2012 je tento limit omezen na pět argumentů, aby se zlepšila doba kompilace a spotřeba paměti kompilátoru pro většinu uživatelů. Předchozí limit ale můžete nastavit explicitním definováním _VARIADIC_MAX jako 10 na úrovni projektu.C++11 17.6.4.3.1 [macro.names]/2 zakáže nahrazení klíčových slov při zahrnutí hlaviček standardní knihovny C++. Hlavičky teď generují chyby kompilátoru, pokud detekují klíčová slova nahrazená makrem. (Definování _ALLOW_KEYWORD_MACROS umožňuje kompilaci takového kódu, ale důrazně nedoporučujeme toto použití.) Jako výjimka je ve výchozím nastavení povolena forma
new
makra, protože hlavičky se komplexně chrání pomocí/#pragma push_macro("new")
#undef new
/#pragma pop_macro("new")
. Definování _ENFORCE_BAN_OF_MACRO_NEW dělá přesně to, co jeho název napovídá.Pokud chcete implementovat různé optimalizace a kontroly ladění, implementace standardní knihovny C++ záměrně přeruší binární kompatibilitu mezi verzemi sady Visual Studio (2005, 2008, 2010, 2012). Pokud se používá standardní knihovna C++, zakáže kombinování souborů objektů a statických knihoven kompilovaných pomocí různých verzí do jednoho binárního souboru (EXE nebo DLL) a zakáže předávání objektů standardní knihovny jazyka C++ mezi binárními soubory kompilovanými pomocí různých verzí. Kombinace souborů objektů a statických knihoven (pomocí standardní knihovny jazyka C++, která byla zkompilována pomocí sady Visual Studio 2010 s knihovnami, které byly zkompilovány pomocí kompilátoru jazyka C++ v sadě Visual Studio 2012, generuje chyby linkeru o neshodě _MSC_VER, kde _MSC_VER je makro obsahující hlavní verzi kompilátoru (1700 pro Visual C++ v sadě Visual Studio 2012). Tato kontrola nedokáže rozpoznat kombinování knihoven DLL a nedokáže rozpoznat kombinování, které zahrnuje Visual Studio 2008 nebo starší.
Kromě zjišťování neshod _ITERATOR_DEBUG_LEVEL, které byly implementovány v sadě Visual Studio 2010, kompilátor jazyka C++ v sadě Visual Studio 2012 detekuje neshody knihoven runtime. K těmto neshodám dochází, když jsou možnosti kompilátoru
/MT
(statická verze),/MTd
(statické ladění),/MD
(dynamická verze) a/MDd
(dynamické ladění) smíšené.operator<()
, ,operator<=()
operator>()
aoperator>=()
byly dříve k dispozici prostd::unordered_map
astdext::hash_map
rodiny kontejnerů, i když jejich implementace nebyly užitečné. Tyto nestandardní operátory byly v sadě Visual C++ v sadě Visual Studio 2012 odebrány. Kromě toho byla implementaceoperator==()
aoperator!=()
prostd::unordered_map
rodinu rozšířena tak, aby pokrývalastdext::hash_map
rodinu. (Doporučujeme, abyste se vyhnuli použitístdext::hash_map
rodiny v novém kódu.)C++11 22.4.1.4 [locale.codecvt] určuje, že
codecvt::length()
acodecvt::do_length()
měl by přijímat upravitelnéstateT&
parametry, ale Visual Studio 2010 trvaloconst stateT&
. Kompilátor jazyka C++ v sadě Visual Studio 2012 přebírástateT&
podle mandátu standardu. Tento rozdíl je významný pro každého, kdo se pokouší přepsat virtuální funkcido_length()
.
CRT
Halda C Runtime (CRT), která se používá pro nové a malloc(), už není soukromá. CRT teď používá haldu procesu. To znamená, že halda není zničena při uvolnění knihovny DLL, takže knihovny DLL, které se staticky propojí s CRT, musí zajistit, aby paměť přidělená kódem knihovny DLL byla vyčištěna před jeho uvolněním.
Funkce
iscsymf()
se používá se zápornými hodnotami.Struktura
threadlocaleinfostruct
se změnila tak, aby vyhovovala změnám funkcí národního prostředí.Funkce CRT, které mají odpovídající vnitřní funkce, jako
memxxx()
je například ,strxxx()
jsou odebrány z intrin.h. Pokud jste intrin.h zahrnuli pouze pro tyto funkce, musíte nyní zahrnout odpovídající hlavičky CRT.
Rozhraní MFC a knihovna ATL
Odebrání podpory fusion (afxcomctl32.h); proto byly odebrány všechny metody, které jsou definovány v
<afxcomctl32.h>
. Soubory<afxcomctl32.h>
hlaviček a<afxcomctl32.inl>
byly odstraněny.Změnil se název
CDockablePane::RemoveFromDefaultPaneDividier
naCDockablePane::RemoveFromDefaultPaneDivider
.Změna podpisu
CFileDialog::SetDefExt
pro použití LPCTSTR, proto jsou ovlivněny buildy Unicode.Odebrání zastaralých kategorií trasování ATL
Změna podpisu
CBasePane::MoveWindow
tak, aby přebísněl znak .const CRect
Změnil se podpis .
CMFCEditBrowseCtrl::EnableBrowseButton
Byly odebrány vlastnosti
m_fntTabs
am_fntTabsBold
ze třídyCMFCBaseTabCtrl
.Přidání parametru
CMFCRibbonStatusBarPane
do konstruktorů (Jedná se o výchozí parametr, a proto se nejedná o zásadní zdroj.)Přidání parametru do konstruktoru
CMFCRibbonCommandsListBox
(Jedná se o výchozí parametr, a proto se nejedná o zásadní zdroj.)Odebrali
AFXTrackMouse
jsme rozhraní API (a související časovač). Místo toho použijte rozhraní API Win32TrackMouseEvent
.Přidání parametru do konstruktoru
CFolderPickerDialog
(Jedná se o výchozí parametr, a proto se nejedná o zásadní zdroj.)CFileStatus
změna velikosti struktury: Členm_attribute
se změnil z BYTE na DWORD (aby odpovídal hodnotě vrácené zGetFileAttributes
).CRichEditCtrl
aCRichEditView
v buildech Unicode používejte MSFTEDIT_CLASS (ovládací prvek RichEdit 4.1) místo RICHEDIT_CLASS (ovládací prvek RichEdit 3.0).Odebráno
AFX_GLOBAL_DATA::IsWindowsThemingDrawParentBackground
, protože je vždy TRUE ve Windows Vista, Windows 7 a Windows 8.Odebráno
AFX_GLOBAL_DATA::IsWindowsLayerSupportAvailable
, protože je vždy TRUE ve Windows Vista, Windows 7 a Windows 8.Odebrané
AFX_GLOBAL_DATA::DwmExtendFrameIntoClientArea
. Volání rozhraní API systému Windows přímo ve Windows Vista, Windows 7 a Windows 8.Odebrané
AFX_GLOBAL_DATA::DwmDefWindowProc
. Volání rozhraní API systému Windows přímo ve Windows Vista, Windows 7 a Windows 8.Přejmenováno
AFX_GLOBAL_DATA::DwmIsCompositionEnabled
tak, abyIsDwmCompositionEnabled
se vyloučila kolize názvů.Změněné identifikátory pro řadu interních časovačů MFC a přesunuté definice do afxres.h (AFX_TIMER_ID_*).
Změna podpisu
OnExitSizeMove
metody tak, aby souhlasila s makrem ON_WM_EXITSIZEMOVE:CFrameWndEx
CMDIFrameWndEx
CPaneFrameWnd
Změna názvu a podpisu souhlasu
OnDWMCompositionChanged
s makrem ON_WM_DWMCOMPOSITIONCHANGED:CFrameWndEx
CMDIFrameWndEx
CPaneFrameWnd
Změna podpisu
OnMouseLeave
metody tak, aby souhlasila s makrem ON_WM_MOUSELEAVE:CMFCCaptionBar
CMFCColorBar
CMFCHeaderCtrl
CMFCProperySheetListBox
CMFCRibbonBar
CMFCRibbonPanelMenuBar
CMFCRibbonRichEditCtrl
CMFCSpinButtonCtrl
CMFCToolBar
ReplaceThisTextCMFCToolBarComboBoxEdit
CMFCToolBarEditCtrl
CMFCAutoHideBar
Změna podpisu souhlasu
OnPowerBroadcast
s makrem ON_WM_POWERBROADCAST:CFrameWndEx
CMDIFrameWndEx
Změna podpisu souhlasu
OnStyleChanged
s makrem ON_WM_STYLECHANGED:CMFCListCtrl
CMFCStatusBar
Přejmenování interní metody
FontFamalyProcFonts
naFontFamilyProcFonts
.Odebrali jsme mnoho globálních statických
CString
objektů, aby se v některých situacích vyloučilo nevracení paměti (nahrazeno #defines) a následující členské proměnné třídy:CKeyBoardManager::m_strDelimiter
CMFCPropertyGridProperty::m_strFormatChar
CMFCPropertyGridProperty::m_strFormatShort
CMFCPropertyGridProperty::m_strFormatLong
CMFCPropertyGridProperty::m_strFormatUShort
CMFCPropertyGridProperty::m_strFormatULong
CMFCPropertyGridProperty::m_strFormatFloat
CMFCPropertyGridProperty::m_strFormatDouble
CMFCToolBarImages::m_strPngResType
CMFCPropertyGridProperty::m_strFormat
Změnili jsme podpis parametru oddělovače akcelerátoru a odebrali ho
CKeyboardManager::ShowAllAccelerators
.Přidána
CPropertyPage::GetParentSheet
, a veCPropertyPage
třídě, zavolejte ji namístoGetParent
získání správného nadřazeného okna listu, který může být nadřazený nebo grandparent okno .CPropertyPage
Možná budete muset změnit kód tak, aby volalGetParentSheet
místoGetParent
.Opravili jsme nevyvážené #pragma warning(push) v ATLBASE. H, což způsobilo nesprávné zakázání upozornění. Tato upozornění jsou teď po ATLBASE správně povolená. H byl analyzován.
Přesunuté metody související s D2D z AFX_GLOBAL_DATA do _AFX_D2D_STATE:
GetDirectD2dFactory
GetWriteFactory
GetWICFactory
InitD2D
ReleaseD2DRefs
IsD2DInitialized
D2D1MakeRotateMatrix
Místo volání, například
afxGlobalData.IsD2DInitialized
, voláníAfxGetD2DState->IsD2DInitialized
.
Odebrání zastaralé knihovny ATL*. Soubory CPP ze složky \atlmfc\include\.
Inicializace byla přesunuta
afxGlobalData
na vyžádání místo v době inicializace CRT, aby splňovalaDLLMain
požadavky.RemoveButtonByIndex
Přidání metody doCMFCOutlookBarPane
třídy.Opraveno
CMFCCmdUsageCount::IsFreqeuntlyUsedCmd
naIsFrequentlyUsedCmd
.Opravili jsme několik výskytů
RestoreOriginalstate
RestoreOriginalState (CMFCToolBar, CMFCMenuBar, CMFCOutlookBarPane)
.Odebrané nepoužité metody z
CDockablePane
:SetCaptionStyle
,IsDrawCaption
,IsHideDisabledButtons
,GetRecentSiblingPaneInfo
, aCanAdjustLayout
.Odebrané
CDockablePane
statické členské proměnném_bCaptionText
am_bHideDisabledButtons
.Přidání metody přepsání
DeleteString
doCMFCFontComboBox
.Odebrané nepoužívané metody z
CPane
:GetMinLength
aIsLastPaneOnLastRow
.Přejmenováno
CPane::GetDockSiteRow(CDockingPanesRow *)
naCPane::SetDockSiteRow
.
Zásadní změny sady Visual Studio 2010
Compiler
Klíčové
auto
slovo má nový výchozí význam. Vzhledem k tomu, že použití starého významu je vzácné, většina aplikací nebude touto změnou ovlivněna.static_assert
Nové klíčové slovo je zavedeno, což způsobí konflikt názvů, pokud v kódu již existuje identifikátor podle daného názvu.Podpora nového zápisu lambda vylučuje podporu kódování necitovaného identifikátoru GUID v atributu uuid IDL.
Rozhraní .NET Framework 4 zavádí koncept poškozených výjimek stavu, což jsou výjimky, které opouštějí proces v neopravitelném poškozeném stavu. Ve výchozím nastavení nelze zachytit výjimku poškozeného stavu ani s možností kompilátoru /EHa, která zachytí všechny ostatní výjimky. Pokud chcete explicitně zachytit výjimku poškozeného stavu, použijte příkazy __try-__except. Nebo použijte atribut [HandledProcessCorruptedStateExceptions], který funkci umožní zachytit výjimky poškozeného stavu. Tato změna má vliv především na programátory systému, kteří mohou muset zachytit výjimku poškozeného stavu. Osm výjimek jsou STATUS_ACCESS_VIOLATION, STATUS_STACK_OVERFLOW, EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_IN_PAGE_ERROR, EXCEPTION_INVALID_DISPOSITION, EXCEPTION_NONCONTINUABLE_EXCEPTION, EXCEPTION_PRIV_INSTRUCTION, STATUS_UNWIND_CONSOLIDATE. Další informace o těchto výjimkách naleznete v makre GetExceptionCode .
Revidovaná
/GS
možnost kompilátoru chrání před přetečením vyrovnávací paměti komplexněji než v předchozích verzích. Tato verze může do zásobníku vložit další kontroly zabezpečení, které můžou snížit výkon. Pomocí nového__declspec(safebuffers)
klíčového slova instruujte kompilátoru, aby nevkládaly kontroly zabezpečení pro konkrétní funkci.Pokud kompilujete s možnostmi
/GL
kompilátoru/GL
(Optimalizace celého programu) i/clr
(kompilace modulu Common Language Runtime), bude tato možnost ignorována. Tato změna byla provedena, protože kombinace možností kompilátoru poskytovala malou výhodu. V důsledku této změny se zlepší výkon sestavení.Ve výchozím nastavení je podpora trigrafů v sadě Visual Studio 2010 zakázaná. Pomocí možnosti kompilátoru
/Zc:trigraphs
povolte podporu trigrafů. Trigraf se skládá ze dvou po sobě jdoucích otazník (??") následovaných jedinečným třetím znakem. Kompilátor nahradí trigraf odpovídajícím interpunkčním znakem. Kompilátor například nahradí??=
trigraf znakem #. Ve zdrojovýchsouborchLinker už nepodporuje optimalizaci pro Windows 98. Možnost
/OPT
(Optimalizace) vytvoří chybu v době kompilace, pokud zadáte/OPT:WIN98
nebo/OPT:NOWIN98
.Byly změněny výchozí možnosti kompilátoru určené vlastnostmi systému sestavení RuntimeLibrary a DebugInformationFormat. Ve výchozím nastavení jsou tyto vlastnosti sestavení zadány v projektech vytvořených verzí visual C++ 7.0 až 10.0. Pokud migrujete projekt vytvořený visual C++ 6.0, zvažte, zda chcete zadat hodnotu pro tyto vlastnosti.
V sadě Visual Studio 2010, RuntimeLibrary = MultiThreaded (
/MD
) a DebugInformationFormat = ProgramDatabase (/Zi
). Ve Visual C++ 9.0, RuntimeLibrary = MultiThreaded (/MT
) a DebugInformationFormat = Disabled.
CLR
- Kompilátory jazyka Microsoft C# a Visual Basic teď můžou vytvořit žádné primární sestavení vzájemné spolupráce (no-PIA). Sestavení bez PIA může používat typy MODELU COM bez nasazení relevantního primárního sestavení vzájemné spolupráce (PIA). Při využívání sestavení bez PIA vytvořených v jazyce Visual C# nebo Visual Basic je nutné odkazovat na sestavení PIA na příkaz kompilace před odkazem na jakékoli sestavení no-PIA, které používá knihovnu.
Projekty jazyka C++ sady Visual Studio a MSBuild
Projekty visual Studio C++ jsou teď založené na nástroji MSBuild. Soubory projektu proto používají nový formát souboru XML a příponu souboru .vcxproj. Visual Studio 2010 automaticky převede soubory projektu ze starších verzí sady Visual Studio do nového formátu souborů. Existující projekt se týká, pokud závisí na předchozím nástroji sestavení, VCBUILD.exe nebo příponě souboru projektu .vcproj.
V dřívějších verzích podporuje Visual C++ pozdní vyhodnocení seznamů vlastností. Například nadřazený seznam vlastností by mohl importovat podřízený seznam vlastností a nadřazený objekt může k definování dalších proměnných použít proměnnou definovanou v podřízené části. Pozdní vyhodnocení umožnilo nadřazené použití podřízené proměnné i před importem podřízeného seznamu vlastností. V sadě Visual Studio 2010 nelze proměnnou listu projektu použít dříve, než je definována, protože nástroj MSBuild podporuje pouze předčasné vyhodnocení.
IDE
Dialogové okno ukončení aplikace už aplikaci neskoncuje. V předchozích verzích se při
abort()
terminate()
zavření maloobchodního sestavení aplikace v knihovně C Run-Time zobrazila zpráva ukončení aplikace v okně konzoly nebo dialogovém okně. Zpráva částečně řekla: "Tato aplikace požádala modul runtime, aby ho ukončil neobvyklým způsobem. Další informace vám poskytne tým podpory aplikace. Zpráva o ukončení aplikace byla redundantní, protože systém Windows následně zobrazil aktuální obslužnou rutinu ukončení, což byla obvykle dialogové okno Zasílání zpráv o chybách systému Windows (Dr. Watson) nebo ladicí program sady Visual Studio. Počínaje sadou Visual Studio 2010 se zpráva nezobrazuje v knihovně runtime jazyka C. Modul runtime navíc brání ukončení aplikace před spuštěním ladicího programu. Jedná se o zásadní změnu pouze v případě, že závisíte na předchozím chování zprávy o ukončení aplikace.Technologie IntelliSense konkrétně pro Visual Studio 2010 nefunguje pro kód nebo atributy C++/CLI, funkce Najít všechny odkazy nefunguje pro místní proměnné a model kódu nenačítá názvy typů z importovaných sestavení nebo překládá typy na plně kvalifikované názvy.
Knihovny
Třída SafeInt je součástí jazyka Visual C++ a již není součástí samostatného stahování. Jedná se o zásadní změnu pouze v případě, že jste vyvinuli třídu s názvem "SafeInt".
Model nasazení knihoven už nepoužívá manifesty k vyhledání konkrétní verze dynamické knihovny odkazů. Místo toho název každé dynamické knihovny odkazů obsahuje její číslo verze a tento název použijete k vyhledání knihovny.
V předchozích verzích sady Visual Studio můžete znovu sestavit knihovny běhu. Visual Studio 2010 už nepodporuje vytváření vlastních kopií souborů knihovny runtime jazyka C.
Standardní knihovna
Hlavička
<iterator>
už není zahrnuta automaticky mnoha dalšími soubory hlaviček. Místo toho tuto hlavičku explicitně zahrňte, pokud potřebujete podporu samostatných iterátorů definovaných v hlavičce. Existující projekt se týká, pokud závisí na předchozím nástroji sestavení, VCBUILD.exe nebo příponě souboru projektu , .vcproj.iterator.<algorithm>
V záhlavíchecked_*
se odeberou funkceunchecked_*
. A v<iterator>
> záhlavíchecked_iterator
se třída odebere aunchecked_array_iterator
třída byla přidána.Konstruktor
CComPtr::CComPtr(int)
je odebrán. Tento konstruktor umožnil vytvoření objektuCComPtr
z makra NULL, ale byl nepotřebný a umožňoval nesmyslné konstrukce z nenulových celých čísel.Hodnota A
CComPtr
je stále možné vytvořit z hodnoty NULL, která je definována jako 0, ale pokud se vytvoří z jiného čísla než literál 0, selže. Místo toho použijtenullptr
.Byly odebrány následující
ctype
členské funkce:ctype::_Do_narrow_s
,ctype::_Do_widen_s
,ctype::_narrow_s
,ctype::_widen_s
. Pokud aplikace používá některou z těchto členských funkcí, musíte ji nahradit odpovídající nezabezpečenou verzí:ctype::do_narrow
,ctype::do_widen
,ctype::narrow
.ctype::widen
Knihovny CRT, MFC a ATL
Uživatelům byla odebrána podpora pro vytváření knihoven CRT, MFC a ATL. Například není k dispozici žádný vhodný soubor NMAKE. Uživatelé ale stále mají přístup ke zdrojovému kódu těchto knihoven. A dokument, který popisuje možnosti nástroje MSBuild, které Microsoft používá k sestavení těchto knihoven, bude pravděpodobně publikován v blogu týmu Visual C++.
Podpora MFC pro IA64 byla odebrána. Podpora CRT a ATL v IA64 je však stále k dispozici.
Ordinaly se už nepoužívají v souborech definice modulu MFC (.def). Tato změna znamená, že se ordinaly nebudou lišit mezi podverzemi a binární kompatibilitou pro aktualizace Service Pack a bude vylepšena technická verze pro rychlé opravy.
Do
CDocTemplate
třídy byla přidána nová virtuální funkce. Tato nová virtuální funkce je CDocTemplate – třída. Předchozí verzeOpenDocumentFile
měla dva parametry. Nová verze má tři parametry. Pro podporu správce restartování musí každá třída odvozená zCDocTemplate
implementovat verzi, která má tři parametry. Nový parametr jebAddToMRU
.
Makra a proměnné prostředí
- Proměnná prostředí __MSVCRT_HEAP_SELECT se už nepodporuje. Tato proměnná prostředí se odebere a nenahradí se.
Microsoft Macro Assembler – referenční dokumentace
- Z referenčního kompilátoru Microsoft Macro Assembler bylo odebráno několik direktiv. Odebrané direktivy jsou
.186
,.8086
.286
.287
.286P
,.8087
, a ..NO87
Zásadní změny sady Visual Studio 2008
Compiler
Platformy Windows 95, Windows 98, Windows ME a systém Windows NT se už nepodporují. Tyto operační systémy byly odebrány ze seznamu cílových platforem.
Kompilátor již nepodporuje více atributů, které byly přímo přidružené k ATL Serveru. Následující atributy se už nepodporují:
perf_counter
perf_object
perfmon
request_handler
soap_handler
soap_header
soap_method
tag_name
Projekty Visual Studio C++
Při upgradu projektů z předchozích verzí sady Visual Studio možná budete muset upravit makra WINVER a _WIN32_WINNT tak, aby byla větší nebo rovna 0x0500.
Počínaje sadou Visual Studio 2008 nemá průvodce novým projektem možnost vytvořit projekt SQL Serveru C++. Projekty SQL Serveru vytvořené pomocí starší verze sady Visual Studio budou stále kompilovat a fungovat správně.
Soubor hlaviček rozhraní WINDOWS API Winable.h byl odebrán. Místo toho zahrňte Winuser.h.
Knihovna rozhraní Windows API Rpcndr.lib byla odebrána. Odkazujte místo toho pomocí rpcrt4.lib.
CRT
Byla odebrána podpora pro Windows 95, Windows 98, Windows Millennium Edition a systém Windows NT 4.0.
Byly odebrány následující globální proměnné:
_osplatform
_osver
_winmajor
_winminor
_winver
Následující funkce byly odebrány. Použijte funkce
GetVersion
rozhraní WINDOWS API neboGetVersionEx
místo toho:_get_osplatform
_get_osver
_get_winmajor
_get_winminor
_get_winver
Syntaxe poznámek SAL se změnila. Další informace najdete v tématu Poznámky SAL.
Filtr IEEE teď podporuje instrukční sadu SSE 4.1. Další informace najdete v tématu _fpieee_flt_fpieee_flt.
Knihovny runtime jazyka C, které jsou dodávány se sadou Visual Studio, již nejsou závislé na systémové knihovně DLL msvcrt.dll.
Standardní knihovna
Byla odebrána podpora pro Windows 95, Windows 98, Windows Millennium Edition a systém Windows NT 4.0.
Při kompilaci v režimu ladění pomocí _HAS_ITERATOR_DEBUGGING definované (nahrazeno _ITERATOR_DEBUG_LEVEL po sadě Visual Studio 2010), aplikace se teď bude uplatňovat, když se iterátor pokusí zvýšit nebo dekrementovat přes hranice podkladového kontejneru.
Členová proměnná c třídy zásobníku je nyní deklarována chráněna. Dříve byla tato členová proměnná deklarována jako veřejná.
Chování
money_get::do_get
se změnilo. Dříve při analýze peněžní částky s více desetinnými číslicemi, než je volá ,frac_digits
do_get
používá se k jejich spotřebě.do_get
Teď po použití většinyfrac_digits
znaků přestane parsovat.
ATL
AtL nejde sestavit bez závislosti na CRT. V dřívějších verzích sady Visual Studio můžete pomocí #define ATL_MIN_CRT vytvořit projekt ATL minimálně závislý na CRT. V sadě Visual Studio 2008 jsou všechny projekty ATL minimálně závislé na CRT bez ohledu na to, jestli je definován ATL_MIN_CRT.
Základ kódu ATL Serveru byl vydán jako sdílený zdrojový projekt v CodePlexu a není nainstalován jako součást sady Visual Studio. Třídy kódování a dekódování dat z atlenc.h a utility funkcí a tříd z atlutil.h a atlpath.h byly zachovány a jsou nyní součástí knihovny ATL. Několik souborů přidružených k ATL Serveru již není součástí sady Visual Studio.
Některé funkce už nejsou součástí knihovny DLL. Jsou stále umístěné v knihovně importu. To neovlivní kód, který staticky používá funkce. Ovlivní pouze kód, který tyto funkce používá dynamicky.
Makra PROP_ENTRY a PROP_ENTRY_EX jsou zastaralá a nahrazena makry PROP_ENTRY_TYPE a PROP_ENTRY_TYPE_EX z bezpečnostních důvodů.
Sdílené třídy ATL/MFC
AtL nejde sestavit bez závislosti na CRT. V dřívějších verzích sady Visual Studio můžete použít k minimálnímu
#define ATL_MIN_CRT
závislosti projektu ATL na CRT. V sadě Visual Studio 2008 jsou všechny projekty ATL minimálně závislé na CRT bez ohledu na to, jestli je definován ATL_MIN_CRT.Základ kódu ATL Serveru byl vydán jako sdílený zdrojový projekt v CodePlexu a není nainstalován jako součást sady Visual Studio. Třídy kódování a dekódování dat z atlenc.h a utility funkcí a tříd z atlutil.h a atlpath.h byly zachovány a jsou nyní součástí knihovny ATL. Několik souborů přidružených k ATL Serveru již není součástí sady Visual Studio.
Některé funkce už nejsou součástí knihovny DLL. Jsou stále umístěné v knihovně importu. To neovlivní kód, který staticky používá funkce. Ovlivní pouze kód, který tyto funkce používá dynamicky.
MFC
CTime
Třída: TřídaCTime
nyní přijímá kalendářní data od 1. 1. 1900 C.E. namísto 1.1.1970 C.E.Pořadí ovládacích prvků v dialogových oknech MFC: Správné pořadí ovládacích prvků více ovládacích prvků v dialogovém okně MFC je narušeno, pokud je ovládací prvek ACTIVEX knihovny MFC vložen do pořadí ovládacích prvků. Tato změna tento problém opraví.
Můžete například vytvořit aplikaci dialogového okna MFC, která má ovládací prvek ActiveX a několik ovládacích prvků pro úpravy. Umístěte ovládací prvek ActiveX doprostřed pořadí ovládacích prvků pro úpravy. Spusťte aplikaci, klikněte na ovládací prvek pro úpravy, jehož pořadí ovládacích prvků je za ovládacím prvku ActiveX, a potom na kartu. Před touto změnou se fokus dostal na ovládací prvek pro úpravy, který následuje za ovládacím prvku ActiveX, a ne na další ovládací prvek pro úpravy v pořadí ovládacích prvků.
CFileDialog
Třída: Vlastní šablony proCFileDialog
třídu nelze automaticky přenést do systému Windows Vista. Jsou stále použitelné, ale nebudou mít další funkce nebo vzhled dialogových oken windows Vista.CWnd
Třída aCFrameWnd
třída: MetodaCWnd::GetMenuBarInfo
byla odebrána.Tato
CFrameWnd::GetMenuBarInfo
metoda je nyní ne virtuální metodou. Další informace naleznete v tématu GetMenuBarInfo Funkce v sadě Windows SDK.Podpora ROZHRANÍ MFC ISAPI: MFC už nepodporuje vytváření aplikací pomocí rozhraní ISAPI (Internet Server Application Programming Interface). Pokud chcete vytvořit aplikaci ISAPI, volejte rozšíření ISAPI přímo.
Zastaralá rozhraní API ANSI: Verze ANSI několika metod MFC jsou zastaralé. V budoucích aplikacích používejte verze unicode těchto metod. Další informace naleznete v tématu Požadavky na sestavení pro windows Vista Běžné ovládací prvky.
Zásadní změny sady Visual Studio 2005
CRT
Řada funkcí je zastaralá. Viz zastaralé funkce CRT.
Mnoho funkcí teď ověřuje jejich parametry a zastaví provádění, pokud jsou zadané neplatné parametry. Toto ověření může přerušit kód, který předává neplatné parametry, a spoléhá na to, že je funkce ignoruje nebo pouze vrací kód chyby. Viz ověření parametru.
Hodnota popisovače souboru -2 se teď používá k označení, že
stdout
výstupstderr
není k dispozici, například v aplikaci pro Windows, která nemá okno konzoly. Použitá předchozí hodnota byla -1. Další informace najdete v tématu _fileno.Knihovny CRT s jedním vláknem (libc.lib a libcd.lib) byly odebrány. Použijte knihovny CRT s více vlákny. Příznak kompilátoru
/ML
se už nepodporuje. V případech, kdy je rozdíl mezi vícevláknovým kódem a kódem s jedním vláknem potenciálně významný, byly přidány neblokované verze některých funkcí.Přetížení pow, double pow(int, int), bylo odstraněno, aby lépe odpovídalo standardu.
Specifikátor formátu %n už není ve výchozím nastavení podporován v žádné skupině funkcí printf, protože je ze své podstaty nezabezpečený. Pokud je zjištěna hodnota %n, výchozím chováním je vyvolání neplatné obslužné rutiny parametru. Pokud chcete povolit %n podpory, použijte
_set_printf_count_output
(viz_get_printf_count_output
také).sprintf
Nyní vytiskne záporné znaménko nuly se znaménkem znaménkoswprintf
byla změněna tak, aby odpovídala standardu; teď vyžaduje parametr velikosti. Formulář bez parametruswprintf
velikosti je zastaralý._set_security_error_handler
byla odebrána. Odeberte všechna volání této funkce; Výchozí obslužná rutina je mnohem bezpečnější způsob řešení chyb zabezpečení.time_t
je teď 64bitová hodnota (pokud není definována _USE_32BIT_TIME_T).Funkce
_spawn
,_wspawn
nyní ponecháerrno
nedotčený úspěch, jak je určeno standardem C.RtC teď ve výchozím nastavení používá široké znaky.
Funkce podpory ovládacích slov s plovoucí desetinou čárkou jsou zastaralé pro aplikace zkompilované pomocí
/CLR
nebo/CLR:PURE
. Ovlivněné funkce jsou_clear87
,_clearfp
._control87
_statusfp
_controlfp
_fpreset
_status87
Upozornění na vyřazení můžete zakázat definováním _CRT_MANAGED_FP_NO_DEPRECATE, ale použití těchto funkcí ve spravovaném kódu je nepředvídatelné a nepodporované.Některé funkce teď vrací ukazatele const. Staré, non-const chování lze obnovit definováním _CONST_RETURN. Ovlivněné funkce jsou
memchr, wmemchr
strchr, wcschr, _mbschr, _mbschr_l
strpbrk, wcspbrk, _mbspbrk, _mbspbrk_l
strrchr, wcsrchr, _mbsrchr, _mbsrchr_l
strstr, wcsstr, _mbsstr, _mbsstr_l
Při propojení s Setargv.obj nebo Wsetargv.obj už není možné potlačit rozšíření zástupného znaku na příkazovém řádku uzavřením do dvojitých uvozovek. Další informace naleznete v tématu Rozbalení argumentů zástupných znaků.
Standardní knihovna (2005)
Třída výjimky (umístěná v
<exception>
hlavičce) byla přesunuta dostd
oboru názvů. V předchozích verzích byla tato třída v globálním oboru názvů. Pokud chcete vyřešit případné chyby, které značí, že třídu výjimek nelze najít, přidejte do kódu následující příkaz using:using namespace std;
Při volání
valarray::resize()
dojde ke ztrátě obsahuvalarray
a nahradí se výchozími hodnotami. Metodaresize()
je určena k opětovné inicializacivalarray
namísto dynamického růstu jako vektor.Ladicí iterátory: Aplikace vytvořené pomocí ladicí verze knihovny C-Runtime a které používají iterátory nesprávně, mohou začít zobrazovat kontrolní výrazy za běhu. Chcete-li tyto výrazy zakázat, je nutné definovat _HAS_ITERATOR_DEBUGGING (nahrazeno
_ITERATOR_DEBUG_LEVEL
po sadě Visual Studio 2010) na 0. Další informace naleznete v tématu Podpora iterátoru ladění
Zásadní změny visual C++ .NET 2003
Compiler
Uzavírací závorky se teď vyžadují pro definovanou direktivu preprocesoru (C2004).
Explicitní specializace už nenaleznou parametry šablony z primární šablony (Chyba kompilátoru C2146).
Chráněný člen (n) je přístupný pouze prostřednictvím členské funkce třídy (B), která dědí z třídy (A), z níž (n) je členem (Chyba kompilátoru C2247).
Vylepšené kontroly přístupnosti v kompilátoru teď detekují nepřístupné základní třídy (chyba kompilátoru C2248).
Výjimku nelze zachytit, pokud je destruktor nebo konstruktor kopírování nepřístupný (C2316).
Výchozí argumenty u ukazatelů na funkce už nejsou povolené (Chyba kompilátoru C2383).
Statický datový člen nelze inicializovat prostřednictvím odvozené třídy (Chyba kompilátoru C2477).
Inicializace
typedef
standardu není povolená a teď generuje chybu kompilátoru (Chyba kompilátoru C2513).bool
je teď správný typ (chyba kompilátoru C2632).UDC teď může vytvořit nejednoznačnost s přetíženými operátory (C2666).
Další výrazy jsou nyní považovány za platné konstanty ukazatele null (Chyba kompilátoru C2668).
Šablona<> se teď vyžaduje na místech, kde by kompilátor dříve znamenal (chyba kompilátoru C2768).
Explicitní specializace členské funkce mimo třídu není platná, pokud už je funkce explicitně specializovaná prostřednictvím specializace podle třídy šablony (Chyba kompilátoru C2910).
Parametry šablony bez typu s plovoucí desetinou čárkou už nejsou povolené (Chyba kompilátoru C2993).
Šablony tříd nejsou povolené jako argumenty typu šablony (C3206).
Názvy přátelských funkcí už nejsou zavedeny do obsahujícího oboru názvů (Chyba kompilátoru C3767).
Kompilátor už nebude přijímat nadbytečné čárky v makru (C4002).
Objekt typu POD vytvořený inicializátorem formuláře () bude ve výchozím nastavení inicializován (C4345).
Název typename se teď vyžaduje, pokud se závislý název považuje za typ (upozornění kompilátoru (úroveň 1) C4346).
Funkce, které byly nesprávně považovány za specializace šablon, se už nepovažují za (C4347).
Statické datové členy nelze inicializovat prostřednictvím odvozené třídy (C4356).
Před použitím v návratovém typu (upozornění kompilátoru (úroveň 3) C4686 je potřeba definovat specializaci šablony třídy.
Kompilátor teď hlásí nedostupný kód (C4702).