Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln beskriver alla brytande ändringar i Visual Studio från 2015 ända tillbaka till 2003, och här refererar termerna "nytt beteende" eller "nu" till Visual Studio 2015 och senare. Termerna "old behavior" och "before" refererar till Visual Studio 2013 och tidigare versioner.
Information om den senaste versionen av Visual Studio finns i Nyheter för C++ i Visual Studio och C++-efterlevnadsförbättringar i Visual Studio.
Anmärkning
Det finns inga binära ändringar som bryter kompatibilitet mellan Visual Studio 2015 och Visual Studio 2017.
När du uppgraderar till en ny version av Visual Studio kan det uppstå kompilerings- och/eller körningsfel i kod som tidigare kompilerats och körts korrekt. Ändringar i den nya versionen som orsakar sådana problem kallas icke-bakåtkompatibla ändringar, och vanligtvis krävs de av ändringar i C++-språkstandarden, funktionssignaturer eller layouten för objekt i minnet.
För att undvika körningsfel som är svåra att identifiera och diagnostisera rekommenderar vi att du aldrig statiskt länkar till binärfiler som kompilerats med hjälp av en annan version av kompilatorn. När du uppgraderar ett EXE- eller DLL-projekt måste du också uppgradera de bibliotek som det länkar till. Skicka inte CRT-typer (C Runtime) eller C++ Standard Library (C++ Standard Library) mellan binärfiler, inklusive DLL:er, som kompilerats med hjälp av olika versioner av kompilatorn. Mer information finns i Potentiella fel som skickar CRT-objekt över DLL-gränser.
Du bör aldrig skriva kod som är beroende av en viss layout för ett objekt som inte är ett COM-gränssnitt eller ett POD-objekt. Om du skriver sådan kod måste du se till att den fungerar efter uppgraderingen. Mer information finns i Portabilitet vid ABI-gränser.
Dessutom kan pågående förbättringar av kompilatorns efterlevnad ibland ändra hur kompilatorn förstår din befintliga källkod. Du kan till exempel hitta nya eller olika fel under bygget, eller till och med beteendeskillnader i kod som tidigare skapats och som verkade köras korrekt. Även om dessa förbättringar inte bryter mot ändringar som de som beskrivs i det här dokumentet, kan du behöva göra ändringar i källkoden för att lösa följande problem:
Ändringar i Visual Studio 2015-överensstämmelse
C Runtime Library (CRT)
Allmänna ändringar
- Omstrukturerade binärfiler - CRT-biblioteket har omstrukturerats till två olika binärfiler: en Universell CRT (ucrtbase), som innehåller de flesta standardfunktionerna och ett VC Runtime-bibliotek (vcruntime). vcruntime-biblioteket innehåller kompilatorrelaterade funktioner som undantagshantering och inbyggda funktioner. Om du använder standardinställningarna för projekt påverkar inte den här ändringen dig eftersom länkaren använder de nya standardbiblioteken automatiskt. Om du har angett projektets Linker-egenskapIgnorera alla standardbibliotek till Ja eller om du använder - /NODEFAULTLIBalternativet länkare på kommandoraden måste du uppdatera listan med bibliotek (i egenskapen Ytterligare beroenden ) för att inkludera de nya, omstrukturerade biblioteken. Ersätt det gamla CRT-biblioteket (- libcmt.lib,- libcmtd.lib,- msvcrt.lib,- msvcrtd.lib) med motsvarande omstrukturerade bibliotek. För vart och ett av de två omstrukturerade biblioteken finns det statiska (.lib) och dynamiska (.dll) versioner, samt releaseversioner (utan suffix) och felsökningsversioner (med suffixet "d"). De dynamiska versionerna har ett importbibliotek som du länkar till. De två omstrukturerade biblioteken är Universal CRT, särskilt ucrtbase.dll eller ucrtbase.lib, ucrtbased.dll eller ucrtbased.lib och VC-körningsbiblioteket,- libvcruntime.lib,vcruntime-versionen.dll,- libvcruntimed.liboch vcruntimed-versionen.dll. Versionen i både Visual Studio 2015 och Visual Studio 2017 är 140. Se CRT-biblioteksfunktioner.
<locale.h>
- localeconv- Funktionen - localeconvsom deklareras i locale.h fungerar nu korrekt när språkvarianten per tråd är aktiverad. I tidigare versioner av biblioteket returnerade funktionen- lconvdata för den globala locale:n, inte trådens locale.- Om du använder nationella inställningar per tråd bör du kontrollera din användning av - localeconv. Om koden förutsätter att de- lconvdata som returneras är för det globala språket bör du korrigera dem.
<math.h>
- C++ överlagringar av matematiska biblioteksfunktioner - I tidigare versioner - <math.h>definierade vissa, men inte alla, C++-överlagringar för matematiska biblioteksfunktioner. Resten av överbelastningarna fanns i den- <cmath>rubriken. Kod som endast innehåller- <math.h>kan få problem med funktionsöverlagringslösning. Nu har C++-överlagringarna tagits bort från- <math.h>och finns bara i- <cmath>.- Lös fel genom att inkludera - <cmath>för att hämta deklarationerna för de funktioner som har tagits bort från- <math.h>. Dessa funktioner har flyttats:- 
              double abs(double)ochfloat 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)
- 
              floatochlong doubleversioner av flyttalsfunktioneracos,acosh,asin,asinh,atan,atanh,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,sqrt,tan,tanh,tgammaochtrunc
 - Om du har kod som använder - absmed en flyttalstyp som bara innehåller- <math.h>rubriken, kommer flyttalsversionerna inte längre att vara tillgängliga. Anropet löser sig nu till- abs(int), även med ett flyttalsargument, vilket genererar felet:- warning C4244: 'argument' : conversion from 'float' to 'int', possible loss of data- Korrigeringen för den här varningen är att ersätta anropet till - absmed en flyttalsversion av- abs, till exempel- fabsför ett dubbelargument eller- fabsfför ett flyttalargument, eller inkludera- <cmath>huvudfilen och fortsätta att använda- abs.
- 
              
- Flyttalsöverensstämmelse - Många ändringar i matematikbiblioteket har gjorts för att förbättra överensstämmelsen med specifikationerna för IEEE-754 och C11 bilaga F med avseende på specialfallsindata som NaN och infinities. Till exempel behandlas tysta NaN-indata, som ofta behandlades som fel i tidigare versioner av biblioteket, inte längre som fel. Se IEEE 754 Standard och bilaga F till C11-standarden. - Dessa ändringar orsakar inte kompileringsfel, men kan leda till att program fungerar annorlunda och mer korrekt enligt standarden. 
- FLT_ROUNDS - I Visual Studio 2013 expanderade FLT_ROUNDS makrot till ett konstant uttryck, vilket var felaktigt eftersom avrundningsläget kan konfigureras vid körning, till exempel genom att anropa fesetround. Det FLT_ROUNDS makrot är nu dynamiskt och återspeglar det aktuella avrundningsläget korrekt. 
              <new> och <new.h>
- newoch- delete- I tidigare versioner av biblioteket exporterades de implementeringsdefinierade 'new' och 'delete'-operatorfunktionerna från körningsbibliotekets DLL (till exempel msvcr120.dll). Dessa operatorfunktioner är nu alltid statiskt länkade till dina binärfiler, även när du använder DLL:er för körningsbiblioteket. - Detta är ingen brytande förändring för native eller blandad kod ( - /clr), men för kod som kompileras som /clr:pure kan denna ändring göra att din kod misslyckas med att kompilera. Om du kompilerar kod som- /clr:pure, kan du behöva lägga till- #include <new>eller- #include <new.h>för att kringgå byggfel på grund av den här ändringen. Alternativet- /clr:pureär inaktuellt i Visual Studio 2015 och stöds inte i Visual Studio 2017. Kod som måste vara "ren" ska portas till C#.
<process.h>
- _beginthreadoch- _beginthreadex- Funktionerna - _beginthreadoch- _beginthreadexinnehåller nu en referens till modulen där trådproceduren definieras under trådens varaktighet. Detta hjälper till att säkerställa att modulerna inte avlastas förrän en tråd har körts färdig.
<stdarg.h>
- va_startoch referenstyper- När du kompilerar C++-kod - va_startverifierar du nu vid kompileringstiden att argumentet som skickas till den inte är av referenstyp. Argument av referenstyp är förbjudna enligt C++ Standard.
 
              <stdio.h> och <conio.h>
- Printf- och scanf-funktionsfamiljen definieras nu inline. - Definitionerna för alla funktionerna - printfoch- scanfhar placerats inline i- <stdio.h>,- <conio.h>, och andra CRT-huvuden. Den här icke-bakåtkompatibla ändringen leder till ett länkfel (LNK2019, olösta externa symboler) för alla program som deklarerade dessa funktioner lokalt utan att inkludera lämpliga CRT-huvudfiler. Om det är möjligt bör du uppdatera koden så att den innehåller CRT-huvudena (d.v.s. lägg till- #include <stdio.h>) och infogade funktioner, men om du inte vill ändra koden så att den innehåller dessa huvudfiler är en alternativ lösning att lägga- legacy_stdio_definitions.libtill i dina länkningsindata.- Om du vill lägga till det här biblioteket i länkningsindata i IDE öppnar du snabbmenyn för projektnoden, väljer Egenskaper. I dialogrutan Projektegenskaper väljer du Länka och redigerar Linker-indata för att lägga - legacy_stdio_definitions.libtill i den semikolonavgränsade listan.- Om projektet länkar till statiska bibliotek som kompilerats med en version av Visual Studio tidigare än 2015 kan länkaren rapportera en olöst extern symbol. Dessa fel kan referera till interna definitioner för - _iob,- _iob_funceller relaterade importer för vissa- <stdio.h>funktioner i form av imp*. Microsoft rekommenderar att du kompilerar om alla statiska bibliotek med den senaste versionen av C++-kompilatorn och biblioteken när du uppgraderar ett projekt. Om biblioteket är ett bibliotek från tredje part för vilket källan inte är tillgänglig bör du antingen begära en uppdaterad binärfil från tredje part eller kapsla in din användning av biblioteket i en separat DLL som du kompilerar med den äldre versionen av kompilatorn och biblioteken.- Varning - Om du länkar till Windows SDK 8.1 eller tidigare kan det uppstå dessa olösta externa symbolfel. I så fall bör du lösa felet genom att lägga till legacy_stdio_definitions.lib i länkningsindata enligt beskrivningen tidigare. - Om du vill felsöka olösta symbolfel kan du prova att använda - dumpbin.exeför att undersöka de symboler som definierats i en binär fil. Prova följande kommandorad för att visa symboler som definierats i ett bibliotek.- dumpbin.exe /LINKERMEMBER somelibrary.lib
- hämtar och _getws - Funktionerna hämtar och _getws har tagits bort. Funktionen gets har tagits bort från C Standard Library i C11 eftersom den inte kan användas på ett säkert sätt. Funktionen _getws var ett Microsoft-tillägg som var likvärdigt med gets men för bredsträngar. Som alternativ till dessa funktioner bör du överväga att använda fgets, fgetws, gets_s och _getws_s. 
- _cgets och _cgetws - Funktionerna _cgets och _cgetws har tagits bort. Som alternativ till dessa funktioner bör du överväga att använda _cgets_s och _cgetws_s. 
- Oändlighet och NaN-formatering - I tidigare versioner skulle infinities och NaN formateras med hjälp av en uppsättning MSVC-specifika sentinel-strängar. - Oändlighet: 1.#INF 
- Tyst NaN: 1.#QNAN 
- Signalerar NaN: 1.#SNAN 
- Obestämd NaN: 1.#IND 
 - Något av dessa format kan ha prefixats av ett tecken och kan ha formaterats något annorlunda beroende på fältbredd och precision (ibland med ovanliga effekter skulle till exempel - printf("%.2f\n", INFINITY)skriva ut 1.#J eftersom #INF skulle "avrundas" till en 2-siffrig precision). C99 införde nya krav på hur infinities och NaN ska formateras. MSVC-implementeringen uppfyller nu dessa krav. De nya strängarna är följande:- Oändlighet: inf 
- Tyst NaN: nan 
- Signalerande NaN: nan(snan) 
- Obestämd NaN: nan(ind) 
 - Något av dessa kan föregås av ett tecken. Om en formatspecificerare med versaler används (%F i stället för %f) skrivs strängarna ut med versaler ( - INFi stället för- inf), enligt vad som krävs.- scanf-funktionerna har ändrats för att parsa dessa nya strängar, så att dessa strängar nu gör en återresa genom - printfoch- scanf.
- Flyttalsformatering och parsning - Ny flyttalsformatering och parsningsalgoritmer har introducerats för att förbättra korrektheten. Den här ändringen påverkar utskrifts- och skanningsfamiljerna för funktioner och funktioner som strtod. - De gamla formateringsalgoritmerna skulle bara generera ett begränsat antal siffror och skulle sedan fylla de återstående decimalerna med noll. De kan vanligtvis generera strängar som går tillbaka till det ursprungliga flyttalvärdet, men som inte är bra om du vill ha det exakta värdet (eller den närmaste decimalrepresentationen av det). De nya formateringsalgoritmerna genererar så många siffror som krävs för att representera värdet (eller för att fylla den angivna precisionen). Som ett exempel på förbättringen: överväg resultatet när du skriver ut en stor kraft av två. - printf("%.0f\n", pow(2.0, 80))- Gamla utdata: - 1208925819614629200000000- Nya utdata: - 1208925819614629174706176- De gamla parsningsalgoritmerna skulle endast överväga upp till 17 signifikanta siffror från indatasträngen och ta bort resten av siffrorna. Den här metoden räcker för att generera en nära uppskattning av värdet som representeras av strängen, och resultatet är vanligtvis mycket nära det korrekt avrundade resultatet. Den nya implementeringen tar hänsyn till alla nuvarande siffror och ger ett korrekt avrundat resultat för alla indata (upp till 768 siffror långa). Dessutom respekterar dessa funktioner nu avrundningsläget (vilket kan styras med hjälp av fesetround). Detta kan vara en icke-bakåtkompatibel beteendeförändring eftersom dessa funktioner kan ge olika resultat. De nya resultaten är alltid mer korrekta än de gamla resultaten. 
- Hexadecimal och oändlighet/NaN-flyttal parsning - Algoritmerna för parsning av flyttal kommer nu att parsa hexadecimala flyttalssträngar (till exempel de som genereras av %a och %A printf-formatspecifikatorer) och alla oändlighet- och NaN-strängar som genereras av - printf-funktionerna, såsom beskrivet ovan.
- %A och %a noll utfyllnad - Formatspecificerarna %a och %A formaterar ett flyttalsnummer som hexadecimal mantissa och binär exponent. I tidigare versioner - printfhäftade funktionerna felaktigt strängar med nollor. Till exempel skulle- printf("%07.0a\n", 1.0)skriva ut 00x1p+0, där det ska bli 0x01p+0. Den här bristen har åtgärdats.
- %A- och %a-noggrannhet - Standardprecisionen för %A och %a formatspecificerare var 6 i tidigare versioner av biblioteket. Standardprecisionen är nu 13 för överensstämmelse med C Standard. - Det här är en körningsbeteendeändring i utdata för alla funktioner som använder en formatsträng med %A eller %a. I det gamla beteendet kan utdata som använder %A-specificeraren vara "1.1A2B3Cp+111". Nu är utdata för samma värde "1.1A2B3C4D5E6F7p+111". För att få det gamla beteendet kan du ange precisionen, till exempel %.6A. Se Precisionsspecifikation. 
- %F-specifier - Nu stöds %F format- och konverteringsspecifierare. Det är funktionellt likvärdigt med formatspecificeraren %f, förutom att oändligheter och NaN formateras med versaler. - I tidigare versioner användes implementeringen för att parsa F och N som längdmodifierare. Det här beteendet dateras tillbaka till åldern för segmenterade adressutrymmen: dessa längdmodifierare användes för att indikera långt respektive nära pekare, som i %Fp eller %Ns. Det här beteendet har tagits bort. Om %F påträffas behandlas den nu som %F formatspecificerare. Om %N påträffas behandlas den nu som en ogiltig parameter. 
- Exponentformatering - Formatspecificerarna %e och %E formaterar ett flyttalsnummer som decimalmantissa och exponent. De %g- och %G- formatkoderna formaterar även tal i detta format i vissa fall. I tidigare versioner skulle CRT alltid generera strängar med tresiffriga exponenter. Skulle till exempel - printf("%e\n", 1.0)skriva ut 1.000000e+000, vilket var felaktigt. C kräver att om exponenten endast kan representeras med en eller två siffror ska endast två siffror skrivas ut.- I Visual Studio 2005 lades en global överensstämmelseväxel till: _set_output_format. Ett program kan anropa den här funktionen med argumentet _TWO_DIGIT_EXPONENT för att aktivera överensstämmande exponentutskrifter. Standardbeteendet har ändrats till standardkonform exponentutskriftsläge. 
- Validering av formatsträng - I tidigare versioner skulle funktionerna - printfoch- scanftyst acceptera många ogiltiga formatsträngar, ibland med ovanliga effekter. Till exempel skulle %hlhlhld behandlas som %d. Alla ogiltiga formatsträngar behandlas nu som ogiltiga parametrar.
- strängvalidering i fopenläge - I tidigare versioner accepterade funktionsfamiljen - fopentyst vissa ogiltiga lägessträngar, till exempel- r+b+. Ogiltiga lägessträngar identifieras nu och behandlas som ogiltiga parametrar.
- _O_U8TEXT-läge - Funktionen _setmode rapporterar nu korrekt läge för strömmar som öppnats i O_U8TEXT-läge. I tidigare versioner av biblioteket skulle det rapportera sådana strömmar som öppnas i _O_WTEXT. - Det här är en avbrottsförändring om din kod tolkar _O_WTEXT-läget för strömmar där kodningen är UTF-8. Om programmet inte stöder UTF_8 kan du överväga att lägga till stöd för den här allt vanligare kodningen. 
- snprintf och vsnprintf - Funktionerna snprintf och vsnprintf implementeras nu. Äldre kod gav ofta definitioner av makroversioner av dessa funktioner eftersom de inte implementerades av CRT-biblioteket, men de behövs inte längre i nyare versioner. Om snprintf eller vsnprintf definieras som ett makro innan du inkluderar - <stdio.h>misslyckas kompilering nu med ett fel som anger var makrot har definierats.- Normalt är korrigeringen av det här problemet att ta bort eventuella deklarationer av - snprintfeller- vsnprintfi användarkod.
- tmpnam genererar användbara filnamn - I tidigare versioner genererade funktionerna - tmpnamoch- tmpnam_sfilnamn i roten på enheten (till exempel \sd3c.). Dessa funktioner genererar nu användbara filnamnssökvägar i en tillfällig katalog.
- Filinkapsling - I tidigare versioner definierades den fullständiga FILtypen offentligt i - <stdio.h>, så det var möjligt för användarkod att nå till en FIL och ändra dess interna. Biblioteket har ändrats för att dölja implementeringsinformation. Som en del av den här ändringen är FIL enligt definitionen i- <stdio.h>nu en ogenomskinlig typ och dess medlemmar är otillgängliga utanför själva CRT.
- _outp och _inp - Funktionerna _outp, _outpw, _outpd, _inp, _inpw och _inpd har tagits bort. 
              <stdlib.h>, <malloc.h> och <sys/stat.h>
- strtof och wcstof - Funktionerna - strtofoch- wcstofkunde inte anges- errnotill ERANGE när värdet inte kunde representeras som en flyttal. Det här felet var specifikt för dessa två funktioner. funktionerna- strtod,- wcstod,- strtoldoch- wcstoldpåverkades inte. Det här problemet har åtgärdats och är en icke-bakåtkompatibel ändring.
- Justerade allokeringsfunktioner - I tidigare versioner skulle de justerade allokeringsfunktionerna ( - _aligned_malloc,- _aligned_offset_mallocosv.) tyst acceptera begäranden om ett block med justeringen 0. Den begärda justeringen måste vara en potens av två, vilket inte gäller för noll. En begärd justering av 0 behandlas nu som en ogiltig parameter. Det här problemet har åtgärdats och är en icke-bakåtkompatibel ändring.
- Heap-funktioner - Funktionerna - _heapadd,- _heapsetoch- _heapusedhar tagits bort. Dessa funktioner har varit icke fungerande sedan CRT uppdaterades för att använda Windows-heapen.
- smallheap - Länkalternativet - smallheaphar tagits bort. Se Länkalternativ.
- _stat - Serien - _statmed funktioner används- CreateFilei Visual Studio 2015, i stället för- FindFirstFilesom i Visual Studio 2013 och tidigare. Det innebär att- _statpå en sökväg som slutar med ett snedstreck lyckas om sökvägen refererar till en katalog, till skillnad från tidigare när funktionen skulle fel med- errnoinställt på- ENOENT.
<string.h>
- wcstok- Funktionens - wcstoksignatur har ändrats för att matcha vad som krävs av C Standard. I tidigare versioner av biblioteket var signaturen för den här funktionen:- wchar_t* wcstok(wchar_t*, wchar_t const*)- Den använde en intern kontext per tråd för att spåra tillstånd mellan anrop, vilket är gjort för - strtok. Funktionen har nu signaturen- wchar_t* wcstok(wchar_t*, wchar_t const*, wchar_t**)och kräver att anroparen skickar kontexten som ett tredje argument till funktionen.- En ny - _wcstokfunktion har lagts till med den gamla signaturen för att underlätta porteringen. När du kompilerar C++-kod finns det också en intern överlagring av- wcstoksom har den gamla signaturen. Den här överlagringen deklareras som inaktuell. I C-kod kan du definiera define_CRT_NON_CONFORMING_WCSTOK för att orsaka att- _wcstokanvänds i stället för- wcstok.
<time.h>
- klocka - I tidigare versioner - clockimplementerades funktionen med hjälp av Windows API- GetSystemTimeAsFileTime. Med den här implementeringen var klockfunktionen känslig för systemtiden och var därför inte nödvändigtvis monoton. Klockfunktionen har omimplementerats i termer av- QueryPerformanceCounteroch är nu monoton.
- fstat och _utime - I tidigare versioner hanterar funktionerna - _stat,- fstatoch- _utimesommartid felaktigt. Före Visual Studio 2013 justerade alla dessa funktioner felaktigt standardtidstiderna som om de befann sig i dagsljus.- I Visual Studio 2013 har problemet åtgärdats i funktionsfamiljen - _stat, men liknande problem i funktionsfamiljerna- fstatoch- _utimehar inte åtgärdats. Den här partiella korrigeringen ledde till problem på grund av inkonsekvensen mellan funktionerna.- fstat- och- _utime-funktionernas familjer har nu åtgärdats, så alla dessa funktioner hanterar sommartid korrekt och konsekvent.
- asctime - I tidigare versioner skulle funktionen - asctimefylla på ensiffriga dagar med en inledande nolla, till exempel:- Fri Jun 06 08:00:00 2014. Specifikationen kräver att sådana dagar fylls med ett inledande mellanslag, som i- Fri Jun 6 08:00:00 2014. Det här problemet har åtgärdats.
- strftime och wcsftime - Funktionerna - strftimeoch- wcsftimestöder nu formatspecificerarna %C, %D, %e, %F, %g, %G, %h, %n, %r, %R, %t, %T, %uoch %V format. Dessutom parsas E- och O-modifierarna men ignoreras.- Den %c formatsspecifikatorn anges som att producera en "lämplig datum- och tidsrepresentation" för den aktuella orten. I C-språkinställningen måste den här representationen vara samma som - %a %b %e %T %Y, samma form som produceras av- asctime. I tidigare versioner har %c formatspecificeraren felaktigt formaterat tider med en- MM/DD/YY HH:MM:SSrepresentation. Det här problemet har åtgärdats.
- timespec och TIME_UTC - <time.h>-huvudet definierar nu- timespec-typen och- timespec_get-funktionen från C11-standard. Dessutom har det TIME_UTC makrot definierats för användning med- timespec_getfunktionen. Den här uppdateringen är en icke-bakåtkompatibel ändring för kod som har en motstridig definition för någon av dessa identifierare.
- CLOCKS_PER_SEC - Det CLOCKS_PER_SEC makrot expanderas nu till ett heltal av typen - clock_t, vilket krävs av C-språket.
C++-standardbibliotek
För att aktivera nya optimeringar och felsökningskontroller bryter Visual Studio-implementeringen av C++-standardbiblioteket avsiktligt binär kompatibilitet från en version till en annan. När C++-standardbiblioteket används kan därför objektfiler och statiska bibliotek som kompileras med hjälp av olika versioner inte blandas i en binär fil (EXE eller DLL) och C++ Standard Library-objekt kan inte skickas mellan binärfiler som kompileras med hjälp av olika versioner. Sådan blandning genererar länkfel om _MSC_VER matchningar. (_MSC_VER är makrot som innehåller kompilatorns huvudversion, till exempel 1800 för Visual Studio 2013.) Den här kontrollen kan inte identifiera DLL-blandning och kan inte identifiera blandning som omfattar Visual Studio 2008 eller tidigare.
- C++ Standard Library innehåller filer - Vissa ändringar har gjorts i inkluderingsstrukturen i C++-standardbiblioteksrubrikerna. C++ standardbibliotekets huvudfiler tillåts inkludera varandra på ospecificerade sätt. I allmänhet bör du skriva din kod så att den noggrant innehåller alla rubriker som den behöver enligt C++-standarden och inte förlitar sig på vilka C++ Standard Library-huvuden som innehåller andra C++ Standard Library-huvuden. Detta gör koden portabel mellan versioner och plattformar. Minst två sidhuvudändringar i Visual Studio 2015 påverkar användarkoden. För det första, - <string>innehåller inte längre- <iterator>. För det andra deklarerar- <tuple>nu utan att inkludera alla- std::array, vilket kan leda till kodbrott genom följande kombination av kodkonstruktioner: din kod har en variabel med namnet "array", och du har ett användningsdirektiv "using namespace std;", och du inkluderar en C++ Standard Library-rubrik (till exempel- <array>) som innehåller- <functional>, som nu deklarerar- <tuple>.
- steady_clock - Implementeringen - <chrono>av- steady_clockhar ändrats för att uppfylla C++ Standard-kraven för stabilitet och monotonitet.- steady_clockär nu baserad på- QueryPerformanceCounteroch- high_resolution_clockär nu en typedef för- steady_clock. Därför är i Visual Studio- steady_clock::time_pointnu en typedef för- chrono::time_point<steady_clock>, men detta är inte nödvändigtvis fallet för andra implementeringar.
- allokerare och konstanter - Vi kräver nu jämförelse av allokeringsjämlikhet/ojämlikhet för att acceptera const-argument på båda sidor. Om dina allokerare definierar dessa operatorer så här, - bool operator==(const MyAlloc& other)- sedan bör du uppdatera dem och deklarera dem som const-medlemmar: - bool operator==(const MyAlloc& other) const
- const-element - C++-standarden har alltid förbjudna containrar med const-element (till exempel - vector<const T>eller- set<const T>). Visual Studio 2013 och tidigare accepterade sådana containrar. I den aktuella versionen kan sådana containrar inte kompileras.
- std::allocator::d eallocate - I Visual Studio 2013 och tidigare ignorerades argumentet som skickades in för - std::allocator::deallocate(p, n). C++-standarden har alltid krävt att n måste vara lika med det värde som skickas som det första argumentet till anropet av- allocate, som returnerade p. I den aktuella versionen inspekteras dock värdet för n . Kod som skickar argument för n som skiljer sig från vad standarden kräver kan krascha vid körning.
- hash_map och hash_set - Huvudfilerna - <hash_map>som inte är standard och- <hash_set>är inaktuella i Visual Studio 2015 och tas bort i en framtida version. Använd- <unordered_map>och- <unordered_set>i stället.
- komparatorer och operator() - Associativa containrar ( - <map>familjen) kräver nu att deras jämförelseobjekt har anropsbara funktionsanropsoperatorer. Följande kod i en jämförelseklassdeklaration kan nu inte kompileras:- bool operator()(const X& a, const X& b)- Lös det här felet genom att ändra funktionsdeklarationen till: - bool operator()(const X& a, const X& b) const
- typegenskaper - De gamla namnen för typegenskaper från en tidigare version av C++-utkaststandarden har tagits bort. Dessa ändrades i C++11 och har uppdaterats till C++11-värdena i Visual Studio 2015. I följande tabell visas de gamla och nya namnen. - Gammalt namn - Nytt namn - lägg_till_referens - add_lvalue_reference - har_standardkonstruktor - is_default_konstruerbar - har_kopieringskonstruktor - är_kopierings_konstruerbar - har_move_constructor - är_konstruerbar_vid_överföring - har_ingen_undantagskonstruktor - is_nothrow_default_constructible - has_nothrow_default_constructor (har standardkonstruktor utan undantag) - is_nothrow_default_constructible - har_kopiering_utan_undantag - is_nothrow_copy_constructible - har_nothrow_kopieringskonstruktor - is_nothrow_copy_constructible - har_nothrow_move_konstruktör - is_nothrow_move_constructible - has_nothrow_assign - is_nothrow_copy_assignable - has_nothrow_copy_assign - is_no_throw_copy_assignable (kan kopieras utan undantag) - har_ingen_undantags_flytt_tilldelning - Det är lämpligt att behålla "is_nothrow_move_assignable" i sin ursprungliga form för att säkerställa att den förstås korrekt i programmeringssammanhang. - har_trivial_konstruktor - är_trivialt_standardkonstruerbar - har_trivial_standardkonstruktor - är_trivialt_standardkonstruerbar - har_trivial_kopia - is_trivially_copy_constructible (if retaining the original English term is standard practice) - har_enkel_flyttkonstruktor - är trivialiskt flytt-konstrukterbar - har_trivial_tilldelning - is_trivially_copy_assignable - har_trivial_flyttilldelning - Är_trivially_move_assignable - har trivial destruktör - is_trivialt_destructibel 
- launch::any och launch::sync-policyer - Icke-standardprinciperna - launch::anyoch- launch::syncprinciperna har tagits bort. Använd i stället för- launch::any.- launch:async | launch:deferredFör- launch::syncanvänder du- launch::deferred. Se initiera uppräkning.
MFC och ATL
- Microsoft Foundation-klasser (MFC) - ingår inte längre i en "typisk" installation av Visual Studio på grund av dess stora storlek. Om du vill installera MFC väljer du alternativet Anpassad installation i Visual Studio 2015-installationen. Om du redan har Visual Studio 2015 installerat kan du installera MFC genom att köra Visual Studio-installationen igen. Välj alternativet Anpassad installation och välj sedan Microsoft Foundation-klasser. Du kan köra Visual Studio-installationen från Kontrollpanelenskontrollprogram och funktioner eller från installationsmediet. - Visual C++ Redistributable Package innehåller fortfarande det här biblioteket. 
Parallellkörning
- Yield-makro från Windows.h i konflikt med concurrency::context::yield - Concurrency Runtime använde tidigare - #undefför att odefiniera makrot Yield, för att undvika konflikter mellan det Yield-makro som definierats i Windows.h och- concurrency::Context::Yield-funktionen. Detta- #undefhar tagits bort och ett nytt icke-konfliktskapande motsvarande API-anrop concurrency::Context::YieldExecution har lagts till. Om du vill undvika konflikter med Yield kan du antingen uppdatera koden för att anropa- YieldExecutionfunktionen i stället, eller omge- Yieldfunktionsnamnet med parenteser på anropsplatser, som i följande exempel:- (concurrency::Context::Yield)();
Förbättringar av kompilatorns överensstämmelse i Visual Studio 2015
När du uppgraderar kod från tidigare versioner kan du också stöta på kompilatorfel som beror på överensstämmelseförbättringar som gjorts i Visual Studio 2015. Dessa förbättringar bryter inte binär kompatibilitet från tidigare versioner av Visual Studio, men de kan generera kompilatorfel där ingen har genererats tidigare. Mer information finns i Visual C++ Nyheter 2003 till och med 2015.
I Visual Studio 2015 kan pågående förbättringar av kompilatorefterlevnad ibland ändra hur kompilatorn förstår din befintliga källkod. Därför kan du stöta på nya eller olika fel under bygget, eller till och med beteendeskillnader i kod som tidigare skapats och som verkade köras korrekt.
Lyckligtvis har dessa skillnader liten eller ingen inverkan på de flesta av din källkod. När källkoden eller andra ändringar behövs för att åtgärda dessa skillnader tenderar korrigeringarna att vara små och raka. Vi har inkluderat många exempel på tidigare godtagbar källkod som kan behöva ändras (före) och korrigeringarna för att korrigera dem (efter).
Även om dessa skillnader kan påverka källkoden eller andra byggartefakter påverkar de inte binär kompatibilitet mellan uppdateringar av Visual Studio-versioner. En brytande ändring är allvarligare och kan påverka binär kompatibilitet, men den här typen av kompatibilitetsbrott sker bara mellan större versioner av Visual Studio, till exempel mellan Visual Studio 2013 och Visual Studio 2015. För information om de ändringar som skedde mellan Visual Studio 2013 och Visual Studio 2015, se Visual Studio 2015 Conformance Changes.
Anpassningsförbättringar i Visual Studio 2015
- /Zc:forScope- alternativ - Kompilatoralternativet - /Zc:forScope-är inaktuellt och tas bort i en framtida version.- Command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release- Vanligtvis användes det här alternativet för att tillåta icke-standardkod som använder loopvariabler efter den punkt där de enligt standarden borde ha gått utanför omfånget. Det var bara nödvändigt när du kompilerade med - /Zaalternativet eftersom det alltid är tillåtet att använda en for-loopvariabel efter slutet av loopen utan- /Za. Om du inte bryr dig om standardefterlevnad (till exempel om koden inte är avsedd att vara portabel för andra kompilatorer) kan du inaktivera- /Zaalternativet (eller ange egenskapen Inaktivera språktillägg till Nej). Om du bryr dig om att skriva portabel, standardkonform kod bör du skriva om koden så att den överensstämmer med standarden genom att flytta deklarationen av sådana variabler till en punkt utanför loopen.- // 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 }
- /Zgkompilatoralternativ- Kompilatoralternativet - /Zg(Generera funktionsprototyper) är inte längre tillgängligt. Det här kompilatoralternativet var tidigare inaktuellt.
- Du kan inte längre köra enhetstester med C++/CLI från kommandoraden med mstest.exe. Använd i stället vstest.console.exe. Se VSTest.Console.exe kommandoradsalternativ. 
- nyckelordet 'mutable' - Lagringsklassspecificeraren - mutabletillåts inte längre på platser där den tidigare kompilerades utan fel. Nu ger kompilatorn felet C2071 (ogiltig lagringsklass). Enligt standarden- mutablekan specificeraren endast tillämpas på namn på klassdatamedlemmar och kan inte tillämpas på namn som deklarerats som const eller statiska och kan inte tillämpas på referensmedlemmar.- Tänk till exempel på följande kod: - struct S { mutable int &r; };- Tidigare versioner av kompilatorn accepterade detta, men nu ger kompilatorn följande fel: - error C2071: 'S::r': illegal storage class- Åtgärda felet genom att ta bort det redundanta - mutablenyckelordet.
- char_16_t och char32_t - Du kan inte längre använda - char16_teller- char32_tsom alias i en- typedef, eftersom dessa typer nu behandlas som inbyggda. Det var vanligt att användare och biblioteksförfattare definierade- char16_toch- char32_tsom alias- uint16_tför respektive- uint32_t.- #include <cstdint> typedef uint16_t char16_t; //C2628 typedef uint32_t char32_t; //C2628 int main(int argc, char* argv[]) { uint16_t x = 1; uint32_t y = 2; char16_t a = x; char32_t b = y; return 0; }- Om du vill uppdatera koden tar du bort deklarationerna - typedefoch byter namn på andra identifierare som kolliderar med dessa namn.
- Mallparametrar som inte är av typen - Viss kod som omfattar mallparametrar som inte är av typen kontrolleras nu korrekt för typkompatibilitet när du anger explicita mallargument. Följande kod kompileras till exempel utan fel i tidigare versioner av 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>(); }- Den nuvarande kompilatorn ger korrekt ett felmeddelande eftersom mallparametertypen inte matchar mallargumentet (parametern är en pekare till en konstant medlem, men funktionen f är inte konstant): - error C2893: Failed to specialize function template 'void S2::f(void)'note: With the following template arguments:note: 'C=S1'note: 'Function=S1::f'- Om du vill åtgärda det här felet i koden kontrollerar du att typen av mallargument som du använder matchar mallparameterns deklarerade typ. 
- __declspec(align)- Kompilatorn accepterar inte längre - __declspec(align)vid funktioner. Den här konstruktionen ignorerades alltid, men nu genererar den ett kompilatorfel.- error C3323: 'alignas' and '__declspec(align)' are not allowed on function declarations- Åtgärda problemet genom att ta bort - __declspec(align)från funktionsdeklarationen. Eftersom det inte hade någon effekt ändras ingenting om du tar bort det.
- Undantagshantering - Det finns ett par ändringar i undantagshantering. För det första måste undantagsobjekt vara antingen kopierbara eller flyttbara. Följande kod kompileras i Visual Studio 2013, men kompileras inte i Visual Studio 2015: - struct S { public: S(); private: S(const S &); }; int main() { throw S(); // error }- Problemet är att kopieringskonstruktorn är privat, så objektet kan inte kopieras på samma sätt som vid normal hantering av ett undantag. Detsamma gäller när kopieringskonstruktorn deklareras - explicit.- struct S { S(); explicit S(const S &); }; int main() { throw S(); // error }- Om du vill uppdatera koden kontrollerar du att kopieringskonstruktorn för undantagsobjektet är - publicoch inte har markerats- explicit.- Att fånga ett undantag efter värde kräver också att undantagsobjektet kan kopieras. Följande kod kompileras i Visual Studio 2013, men kompileras inte i Visual Studio 2015: - struct B { public: B(); private: B(const B &); }; struct D : public B {}; int main() { try { } catch (D d) // error { } }- Du kan åtgärda det här problemet genom att ändra parametertypen för - catchtill en referens.- catch (D& d) { }
- Strängliteraler följda av makron - Kompilatorn stöder nu användardefinierade literaler. Därför tolkas strängliteraler följt av makron utan mellanliggande blanksteg som användardefinierade literaler, vilket kan ge fel eller oväntade resultat. I tidigare kompilatorer kompilerades till exempel följande kod: - #define _x "there" char* func() { return "hello"_x; } int main() { char * p = func(); return 0; }- Kompilatorn tolkade den här koden som en strängliteral "hello" följt av ett makro, som expanderas till "där", och sedan sammanfogades de två strängliteralerna till en. I Visual Studio 2015 tolkar kompilatorn den här sekvensen som en användardefinierad literal, men eftersom det inte finns någon matchande användardefinierad literal - _xdefinierad ger den ett fel.- 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?- Åtgärda problemet genom att lägga till ett blanksteg mellan strängkonstanten och makrot. 
- Intilliggande strängliteraler - På samma sätt som i föregående, på grund av relaterade ändringar i strängparsning, tolkades angränsande strängliteraler (antingen breda eller smala teckensträngliteraler) utan blanksteg som en enda sammanfogad sträng i tidigare versioner av Visual C++. I Visual Studio 2015 måste du nu lägga till blanksteg mellan de två strängarna. Följande kod måste till exempel ändras: - char * str = "abc""def";- För att åtgärda problemet, lägg till ett blanksteg mellan de två strängarna: - char * str = "abc" "def";
- Placering ny och ta bort - En ändring har gjorts i operatorn - deleteför att anpassa den till C++14-standarden. Information om standardändringen finns på C++ Size Deallocation. Ändringarna lägger till en form av den globala- deleteoperatorn som tar en storleksparameter. Den brytande ändringen är att om du tidigare använde en operator- deletemed samma signatur (för att motsvara en placement new-operator) får du ett kompilatorfel (C2956, som inträffar när den nya placeringen används, eftersom det är där i koden kompilatorn försöker identifiera en lämplig matchande- delete-operator).- Funktionen - void operator delete(void *, size_t)var en placement delete-operator som motsvarar placement new-funktionen- void * operator new(size_t, size_t)i C++11. Med C++14-storleksbaserad avallokering är den här borttagningsfunktionen nu en vanlig frigöringsfunktion (global- deleteoperator). Standarden kräver att om användningen av en ny placering söker upp en motsvarande borttagningsfunktion och hittar en vanlig frigöringsfunktion är programmet felaktigt utformat.- Anta till exempel att koden definierar både en ny placering och en placeringsborttagning: - void * operator new(std::size_t, std::size_t); void operator delete(void*, std::size_t) noexcept;- Problemet uppstår på grund av matchningen i funktionssignaturer mellan en placement delete-operator som du har definierat och den nya globale sized-operatorn . Fundera på om du kan använda en annan typ än - size_tför någon placement new och- delete-operatorer. Typen av- size_t- typedefär kompilatorberoende. Det är ett- typedefför- unsigned inti MSVC. En bra lösning är att använda en uppräkningstyp som den här:- enum class my_type : size_t {};- Ändra sedan definitionen av placering ny och - deleteanvänd den här typen som det andra argumentet i stället för- size_t. Du måste också uppdatera anropen till "placement new" för att passera den nya typen (till exempel genom att använda- static_cast<my_type>för att konvertera från heltalsvärdet) och uppdatera definitionen av- newoch- deleteför att återkonvertera till heltalstypen. Du behöver inte använda en- enumför detta. En klasstyp med en- size_tmedlem fungerar också.- En alternativ lösning är att du kan eliminera placement new helt och hållet. Om koden använder en ny placering för att implementera en minnespool där placeringsargumentet är storleken på objektet som allokeras eller tas bort, kan funktionen för storleksfördelning vara lämplig för att ersätta din egen kod för den anpassade minnespoolen, och du kan bli av med placeringsfunktionerna och bara använda din egen tvåargumentsoperator - deletei stället för placeringsfunktionerna.- Om du inte vill uppdatera koden omedelbart kan du återgå till det gamla beteendet med hjälp av kompilatoralternativet - /Zc:sizedDealloc-. Om du använder det här alternativet finns inte borttagningsfunktionerna med två argument och kommer inte att orsaka någon konflikt med din placerings-borttagningsoperator.
- Unionsdatamedlemmar - Datamedlemmar i fackföreningar kan inte längre ha referenstyper. Följande kod kompilerades korrekt i Visual Studio 2013, men genererar ett fel i Visual Studio 2015. - union U1 { const int i; }; union U2 { int & i; }; union U3 { struct { int & i; }; };- Föregående kod genererar följande fel: - 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- Åtgärda problemet genom att ändra referenstyperna till en pekare eller ett värde. Om du ändrar typen till en pekare krävs ändringar i koden som använder union-fältet. Om du ändrar koden till ett värde ändras data som lagras i unionen, vilket påverkar andra fält eftersom fält i unionstyper delar samma minne. Beroende på värdets storlek kan det också ändra storleken på unionen. 
- Anonyma fackföreningar är nu mer överensstämmande med standarden. Tidigare versioner av kompilatorn genererade en explicit konstruktor och destructor för anonyma fackföreningar. Dessa kompilatorgenererade funktioner tas bort i Visual Studio 2015. - struct S { S(); }; union { struct { S s; }; } u; // C2280- Föregående kod genererar följande fel i Visual Studio 2015: - error C2280: '<unnamed-type-u>::<unnamed-type-u>(void)': attempting to reference a deleted function note: compiler has generated '<unnamed-type-u>::<unnamed-type-u>' here- Lös problemet genom att ange egna definitioner av konstruktorn och/eller destruktor. - struct S { // Provide a default constructor by adding an empty function body. S() {} }; union { struct { S s; }; } u;
- Fackföreningar med anonyma structs - För att uppfylla standarden har körningsbeteendet ändrats för medlemmar i anonyma strukturer i fackföreningar. Konstruktorn för anonyma strukturmedlemmar i en union anropas inte längre implicit när en sådan union skapas. Dessutom kallas inte längre destruktorn för anonyma strukturmedlemmar i en union implicit när unionen går utanför sitt omfång. Tänk på följande kod, där en union U innehåller en anonym struktur med en namngiven medlemsstruktur S, som har en 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; }- I Visual Studio 2013 anropas konstruktorn för S när unionen skapas och destruktören för S anropas när stacken för funktionen f rensas. Men i Visual Studio 2015 anropas inte konstruktorn och destruktören. Kompilatorn varnar om den här beteendeändringen. - warning C4587: 'U::s': behavior change: constructor is no longer implicitly calledwarning C4588: 'U::s': behavior change: destructor is no longer implicitly called- Om du vill återställa det ursprungliga beteendet ger du den anonyma strukturen ett namn. Körningsbeteendet för icke-anonyma strukturer är detsamma, oavsett kompilatorversion. - #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; }- Alternativt kan du prova att flytta koden för konstruktorn och destruktorn till nya funktioner och lägga till anrop till dessa funktioner från konstruktorn och destruktorn för unionen. - #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; }
- Mallupplösning - Ändringar har gjorts i namnupplösning för mallar. I C++, när du överväger kandidater för lösning av ett namn, kan det vara så att ett eller flera namn som övervägs som potentiella matchningar skapar en ogiltig mallinstansiering. Dessa ogiltiga instanser orsakar normalt inte kompilatorfel, en princip som kallas SFINAE (substitutionsfel är inte ett fel). - Om SFINAE kräver att kompilatorn instansierar specialiseringen av en klassmall är nu eventuella fel som inträffar under den här processen kompilatorfel. I tidigare versioner skulle kompilatorn ignorera sådana fel. Tänk till exempel på följande kod: - #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); }- Om du kompilerar med den aktuella kompilatorn får du följande fel: - 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 ]- Detta beror på att klassen - Dinte har definierats ännu vid tidpunkten för det första anropet av is_base_of.- I det här fallet är korrigeringen att inte använda sådana typegenskaper förrän klassen har definierats. Om du flyttar definitionerna för - Boch- Dtill början av kodfilen löses felet. Om definitionerna finns i huvudfiler kontrollerar du ordningen på include-instruktionerna för huvudfilerna för att se till att alla klassdefinitioner kompileras innan de problematiska mallarna används.
- Kopia-konstruktorer - I både Visual Studio 2013 och Visual Studio 2015 genererar kompilatorn en kopieringskonstruktor för en klass om klassen har en användardefinierad flyttkonstruktor men ingen användardefinierad kopieringskonstruktor. I Dev14 är den här implicit genererade kopieringskonstruktorn också märkt "= delete". 
- main som deklarerats som extern "C" kräver nu en returtyp. - Följande kod genererar nu C4430. - extern "C" __cdecl main(){} // C4430- Åtgärda felet genom att lägga till returtypen: - extern "C" int __cdecl main(){} // OK
- typename är inte tillåtet i en medlemsinitialiserare - Följande kod genererar nu C2059: - template<typename T> struct S1 : public T::type { S1() : typename T::type() // C2059 { } }; struct S2 { typedef S2 type; }; S1<S2> s;- Åtgärda felet genom att ta bort - typenamefrån initieraren:- S1() : T::type() // OK ...
- Lagringsklassen för explicita specialiseringar ignoreras. - I följande kod ignoreras den statiska lagringsklassspecificeraren - template <typename T> void myfunc(T h) { } template<> static void myfunc(double h) // static is ignored { }
- En konstant som används i en static_assert i en klassmall misslyckas alltid. - Följande kod gör att det - static_assertalltid misslyckas:- template <size_t some_value> struct S1 { static_assert(false, "default not valid"); // always invoked }; //other partial specializations here- Du kan kringgå det här problemet genom att omsluta värdet i en - 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
- Regler som tillämpas för framåtriktade deklarationer. (Gäller endast för C.) - Följande kod genererar nu C2065: - struct token_s; typedef int BOOL; typedef int INT; typedef int(*PFNTERM)(PTOKEN, BOOL, INT); // C2065: 'PTOKEN' : undeclared identifier- Åtgärda problemet genom att lägga till rätt framåtdeklarationer: - 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);
- Mer konsekvent tillämpning av funktionspekartyper - Följande kod genererar nu C2197: - typedef int(*F1)(int); typedef int(*F2)(int, int); void func(F1 f, int v1, int v2) { f(v1, v2); // C2197 }
- Tvetydiga anrop till överbelastade funktioner - Följande kod genererar nu C266: "N::bind": tvetydigt anrop till överbelastad funktion - 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 } };- För att åtgärda felet kan du helt kvalificera anropet till - bind: N::bind(...). Men om den här ändringen visas via en odeklarerad identifierare (C2065) kan det vara lämpligt att åtgärda detta med en- usingdeklaration i stället.- Det här mönstret sker ofta med ComPtr och andra typer i - Microsoft::WRLnamnområdet.
- Åtgärda felaktig adress för - Följande kod genererar nu C2440: '=': kan inte konvertera från "typ *" till "typ". Åtgärda felet genom att ändra &(typ) till (typ) och (&f()) till (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()); }
- Strängliteral är en konstant matris - Följande kod genererar nu C2664: "void f(void )": kan inte konvertera argument 1 från "const char ()[2]" till "void *" - void f(void *); void h(void) { f(&__FUNCTION__); void *p = &""; }- Åtgärda felet genom att ändra funktionsparametertypen till - const void*, eller ändra brödtexten- hför så att den ser ut som i det här exemplet:- void h(void) { char name[] = __FUNCTION__; f( name); void *p = &""; }
- C++11 UDL-strängar - Följande kod genererar nu felet C3688: det ogiltiga literalsuffixet "L"; literaloperatorn eller literaloperatormallen "operatorn ""L" hittades inte - #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"); }- Åtgärda felet genom att ändra koden för att lägga till ett blanksteg: - #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"); }- I exemplet ovan - MACROparsas inte längre som två token (en sträng följt av ett makro). Nu parsas den som en enda token-UDL. Samma sak gäller för L""L", som tidigare parsades som L"" och L", och som nu parsas som L""L och "".- Reglerna för strängsammanfogning har också bragts i överensstämmelse med standarden, vilket innebär att L"a" "b" är ekvivalent med L"ab". Tidigare utgåvor av Visual Studio accepterade inte sammanfogning av strängar med olika teckenbredd. 
- C++11 tomt tecken har tagits bort - Följande kod genererar nu felet C2137: tom teckenkonstant - bool check(wchar_t c){ return c == L''; //implicit null character }- Åtgärda felet genom att ändra koden så att null-värdet blir explicit: - bool check(wchar_t c){ return c == L'\0'; }
- MFC-undantag kan inte fångas upp av värde eftersom de inte kan kopieras - Följande kod i ett MFC-program orsakar nu felet C2316: "D": kan inte fångas eftersom destruktorn och/eller kopieringskonstruktorn är otillgänglig eller borttagen - struct B { public: B(); private: B(const B &); }; struct D : public B { }; int main() { try { } catch (D) // C2316 { } }- För att åtgärda koden kan du ändra catch-blocket till - catch (const D &), men den bättre lösningen är vanligtvis att använda MFC TRY/CATCH-makron.
- alignofär nu ett nyckelord- Följande kod genererar nu felet C2332: "class": saknade taggnamn. Om du vill åtgärda koden måste du byta namn på klassen eller, om klassen utför samma arbete som - alignof, bara ersätta klassen med det nya nyckelordet.- class alignof{}
- constexprär nu ett nyckelord- Följande kod genererar nu felet C2059: syntaxfel: ')'. Om du vill åtgärda koden måste du byta namn på alla funktions- eller variabelnamn som kallas - constexpr.- int constexpr() {return 1;}
- Flyttbara typer kan inte vara beständiga - När en funktion returnerar en typ som är avsedd att flyttas ska dess returtyp inte vara - const.
- Borttagna kopieringskonstruktorer - Följande kod genererar nu C2280 'S::S(S &&)': försöker referera till en borttagen funktion: - struct S{ S(int, int); S(const S&) = delete; S(S&&) = delete; }; S s2 = S(2, 3); //C2280- Åtgärda felet genom att använda direktinitiering för - S2:- struct S{ S(int, int); S(const S&) = delete; S(S&&) = delete; }; S s2 = {2,3}; //OK
- Konvertering till funktionspekare sker endast när ingen lambda-capture finns - Följande kod genererar C2664 i Visual Studio 2015. - void func(int(*)(int)) {} int main() { func([=](int val) { return val; }); }- Åtgärda felet genom att ta bort - =från avbildningslistan.
- Tvetydiga anrop som involverar konverteringsoperatorer - Följande kod genererar nu felet C2440: "type cast": kan inte konvertera från "S2" till "S1": - struct S1 { S1(int); }; struct S2 { operator S1(); operator int(); }; void f(S2 s2) { (S1)s2; }- Om du vill åtgärda felet anropar du uttryckligen konverteringsoperatorn: - void f(S2 s2) { //Explicitly call the conversion operator s2.operator S1(); // Or S1((int)s2); }- Följande kod genererar nu felet C2593: operatorn =är tvetydig: - struct S1 {}; struct S2 { operator S1&(); operator S1() const; }; void f(S1 *p, S2 s) { *p = s; }- Om du vill åtgärda felet anropar du uttryckligen konverteringsoperatorn: - void f(S1 *p, S2 s) { *p = s.operator S1&(); }
- Åtgärda ogiltig kopieringsinitiering i initiering av icke-statiska datamedlemmar (NSDMI) - Följande kod genererar nu felet C2664: S1::S1(S1 &&): kan inte konvertera argument 1 från "bool" till "const S1 &": - struct S1 { explicit S1(bool); }; struct S2 { S1 s2 = true; // error };- Åtgärda felet genom att använda direktinitiering: - struct S2 { S1 s1{true}; // OK };
- Komma åt konstruktorer i decltype-instruktioner - Följande kod genererar nu C2248: "S::S": kan inte komma åt den privata medlem som deklareras i klassen "S": - class S { S(); public: int i; }; class S2 { auto f() -> decltype(S().i); };- Åtgärda felet genom att lägga till en vändeklaration för - S2i- S:- class S { S(); friend class S2; // Make S2 a friend public: int i; };
- Standard-ctor för lambda tas implicit bort - Följande kod genererar nu felet C3497: du kan inte skapa en instans av en lambda: - void func(){ auto lambda = [](){}; decltype(lambda) other; }- Åtgärda felet genom att ta bort behovet av att anropa standardkonstruktorn. Om lambda inte fångar något kan det kastas till en funktionspekare. 
- Lambdas med en borttagen tilldelningsoperator - Följande kod genererar nu felet 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); }- Åtgärda felet genom att ersätta lambda med en functor-klass eller ta bort behovet av att använda tilldelningsoperatorn. 
- Försöker flytta ett objekt med borttagen kopieringskonstruktor - Följande kod genererar nu felet C2280: "moveable::moveable(const moveable &)": försöker referera till en borttagen funktion - 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; };- Åtgärda felet genom att använda - std::movei stället:- S(moveable && m) : m_m(std::move(m))
- Lokal klass kan inte referera till andra lokala klasser som definierats senare i samma funktion - Följande kod genererar nu felet C2079: "s" använder odefinierad struct "main::S2" - int main() { struct S2; struct S1 { void f() { S2 s; } }; struct S2 {}; }- Åtgärda felet genom att flytta upp definitionen av - S2:- int main() { struct S2 { //moved up }; struct S1 { void f() { S2 s; } }; }
- Det går inte att anropa en skyddad baskonstruktor i en härledd konstruktors kropp. - Följande kod genererar nu felet C2248: "S1::S1": kan inte komma åt skyddad medlem som deklarerats i klassen "S1" - struct S1 { protected: S1(); }; struct S2 : public S1 { S2() { S1(); } };- Åtgärda felet genom att ta - S2bort anropet till- S1()från konstruktorn och vid behov placera det i en annan funktion.
- {} förhindrar konvertering till pekare - Följande kod genererar nu C2439 'S::p': medlemmen kunde inte initieras - struct S { S() : p({ 0 }) {} void *p; };- Åtgärda felet genom att ta bort klammerparenteserna från runt - 0eller annars använda- nullptri stället, som du ser i det här exemplet:- struct S { S() : p(nullptr) {} void *p; };
- Felaktig makrodefinition och användning med parenteser - Följande exempel genererar nu felet C2008: ';': oväntat i makrodefinitionen - #define A; //cause of error struct S { A(); // error };- Åtgärda problemet genom att ändra den översta raden till - #define A();- Följande kod genererar felet C2059: syntaxfel: ')' - //notice the space after 'A' #define A () ; struct S { A(); };- Åtgärda koden genom att ta bort utrymmet mellan A och (). - Följande kod genererar felet C2091: funktionen returnerar funktionen: - #define DECLARE void f() struct S { DECLARE(); };- Åtgärda felet genom att ta bort parenteserna efter DECLARE i S: - DECLARE;.- Följande kod genererar felet C2062: skriv "int" oväntat - #define A (int) struct S { A a; };- Du kan åtgärda problemet genom att definiera - Aså här:- #define A int
- Extra parens i deklarationer - Följande kod genererar felet C2062: skriv "int" oväntat - struct S { int i; (int)j; };- Åtgärda felet genom att ta bort parenteserna runt - j. Om parenteserna behövs för tydlighetens skull använder du en- typedef.
- Kompilatorgenererade konstruktorer och __declspec(novtable) - I Visual Studio 2015 finns det en ökad sannolikhet att kompilatorgenererade infogade konstruktorer av abstrakta klasser med virtuella basklasser kan exponera felaktig användning av - __declspec(novtable)när de används i kombination med- __declspec(dllimport).
- auto kräver ett enda uttryck i direct-list-initialization - Följande kod genererar nu felet C3518: "testPositions": i en kontext för direkt listinitiering kan typen för "auto" bara härledas från ett enda initialiseraruttryck - 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} };- För att åtgärda felet är en möjlighet att initiera - testPositionspå följande sätt:- 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} };
- Att kontrollera typer versus pekare till typer för is_convertible - Följande kod gör nu att den statiska försäkran misslyckas. - struct B1 { private: B1(const B1 &); }; struct B2 : public B1 {}; struct D : public B2 {}; static_assert(std::is_convertible<D, B2>::value, "fail");- Åtgärda felet genom att ändra - static_assertså att pekarna jämförs med- Doch- B2:- static_assert(std::is_convertible<D*, B2*>::value, "fail");
- __declspec(novtable) deklarationer måste vara konsekventa - __declspecdeklarationer måste vara konsekventa i alla bibliotek. Följande kod skapar en ODR-överträdelse (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;
Överensstämmelseförbättringar i uppdatering 1
- Privata virtuella basklasser och indirekt arv - Tidigare versioner av kompilatorn tillät en härledd klass att anropa medlemsfunktioner i dess indirekt härledda - private virtualbasklasser. Det här gamla beteendet var felaktigt och överensstämmer inte med C++-standarden. Kompilatorn accepterar inte längre kod som skrivits på det här sättet och utfärdar kompilatorfel C2280 som ett resultat.- error C2280: 'void *S3::__delDtor(unsigned int)': attempting to reference a deleted function- Exempel (före) - class base { protected: base(); ~base(); }; class middle : private virtual base {}; class top : public virtual middle {}; void destroy(top *p) { delete p; // }- Exempel (efter) - class base; // as above class middle : protected virtual base {}; class top : public virtual middle {}; void destroy(top *p) { delete p; }- -eller- - class base; // as above class middle : private virtual base {}; class top : public virtual middle, private virtual bottom {}; void destroy(top *p) { delete p; }
- Överlagrade operatorn new och operator delete - Tidigare versioner av kompilatorn tillät att icke-medlemsoperatorn new och icke-medlemsoperatorn delete kunde deklareras som statiska och i andra namnområden än det globala namnområdet. Det här gamla beteendet skapade en risk för att programmet inte skulle anropa den operatorimplementering - neweller- deletesom programmeraren avsåg, vilket resulterade i tysta problem under körning. Kompilatorn accepterar inte längre kod som skrivits på det här sättet och utfärdar kompilatorfel C2323 i stället.- 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.- Exempel (före) - static inline void * __cdecl operator new(size_t cb, const std::nothrow_t&) // error C2323- Exempel (efter) - void * __cdecl operator new(size_t cb, const std::nothrow_t&) // removed 'static inline'- Även om kompilatorn inte ger någon specifik diagnostik anses den infogade operatorn - newdessutom vara dåligt utformad.
- Anropa " operatortyp()" (användardefinierad konvertering) för icke-klasstyper - Tidigare versioner av kompilatorn tillät att " operatortyp()" anropas på icke-klasstyper samtidigt som den ignoreras tyst. Det gamla beteendet skapade en risk för tyst felaktig kodgenerering, vilket resulterade i oförutsägbart exekveringsbeteende. Kompilatorn accepterar inte längre kod som skrivits på det här sättet och utfärdar kompilatorfel C2228 i stället. - error C2228: left of '.operator type' must have class/struct/union- Exempel (före) - typedef int index_t; void bounds_check(index_t index); void login(int column) { bounds_check(column.operator index_t()); // error C2228 }- Exempel (efter) - 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' }
- Redundant typename i utarbetade typspecificerare - Tidigare versioner av kompilatorn tillät - typenamei en utarbetad typspecifikation, men koden som skrevs på detta sätt är semantiskt felaktig. Kompilatorn accepterar inte längre kod som skrivits på det här sättet och utfärdar kompilatorfel C3406 i stället.- error C3406: 'typename' cannot be used in an elaborated type specifier- Exempel (före) - template <typename class T> class container;- Exempel (efter) - template <class T> // alternatively, could be 'template <typename T>'; 'typename' is not elaborating a type specifier in this case class container;
- Skriv avdrag för matriser från en initialiserarlista - Tidigare versioner av kompilatorn hade inte stöd för typavdrag av matriser från en initialiserarlista. Kompilatorn stöder nu den här typen av typavdrag och därför kan anrop till funktionsmallar som använder initieringslistor nu vara tvetydiga eller så kan en annan överbelastning väljas än i tidigare versioner av kompilatorn. För att lösa dessa problem måste programmet nu uttryckligen ange den överlagring som programmeraren avsåg. - När det här nya beteendet gör att överbelastningslösningen överväger ytterligare en kandidat som är lika bra som den historiska kandidaten blir anropet tvetydigt och kompilatorn utfärdar kompilatorfelet C2668 som ett resultat. - error C2668: 'function' : ambiguous call to overloaded function.- Exempel 1: Tvetydigt anrop till överbelastad funktion (före) - // 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 }- Exempel 1: tvetydigt anrop till överbelastad funktion (efter) - 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); }- När det här nya beteendet gör att överbelastningslösningen överväger ytterligare en kandidat som är en bättre matchning än den historiska kandidaten, löses samtalet entydigt mot den nya kandidaten, vilket orsakar en förändring i programmets beteende som förmodligen skiljer sig från programmerarens avsedda. - Exempel 2: ändring i överlagringsupplösning (före) - // 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 }); }- Exempel 2: ändring i överbelastningslösning (efter) - 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 }); }
- Återställning av switch-instruktionsvarningar - En tidigare version av kompilatorn tog bort några varningar relaterade till - switch-instruktioner. Dessa varningar har nu återställts. Kompilatorn utfärdar nu de återställde varningarna och varningar relaterade till specifika fall (inklusive standardfallet) utfärdas nu på raden som innehåller det felaktiga ärendet, i stället för på den sista raden i switch-instruktionen. Som ett resultat av att dessa varningar nu utfärdas på andra rader än tidigare kan varningar som tidigare undertryckts med hjälp av- #pragma warning(disable:####)inte längre undertryckas som man tänkt sig. Det kan vara nödvändigt att flytta- #pragma warning(disable:####)-direktivet till en rad ovanför det första felaktiga fallet för att undanröja dessa varningar så som avsett. Följande är de återställde varningarna:- 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- Exempel på C4063 (före) - 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; } }- Exempel på C4063 (efter) - 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; } };- Exempel på andra återställde varningar finns i dokumentationen. 
- #include: användning av överordnad katalogspecificerare '..' i sökväg (påverkar - /Wall- /WXendast )- Tidigare versioner av kompilatorn identifierade inte användningen av den överordnade katalogspecificeraren .. i direktivens - #includesökväg. Kod som skrivs på det här sättet är vanligtvis avsedd att innehålla rubriker som finns utanför projektet genom att felaktigt använda projektrelativa sökvägar. Det här gamla beteendet skapade en risk för att programmet kunde kompileras genom att inkludera en annan källfil än programmeraren avsåg, eller att dessa relativa sökvägar inte skulle vara portabla för andra byggmiljöer. Kompilatorn identifierar och meddelar nu programmeraren av kod som skrivits på det här sättet och utfärdar en valfri kompilatorvarning C4464, om den är aktiverad.- warning C4464: relative include path contains '..'- Exempel (före) - #include "..\headers\C4426.h" // emits warning C4464- Exempel (efter) - #include "C4426.h" // add absolute path to 'headers\' to your project's include directories- Även om kompilatorn inte ger någon specifik diagnostik rekommenderar vi också att den överordnade katalogspecificeraren ".." inte ska användas för att ange projektets inkluderingskataloger. 
- #pragma optimize() sträcker sig bortom slutet av huvudfilen (påverkar endast - /Wall- /WX)- Tidigare versioner av kompilatorn identifierade inte ändringar i optimeringsflaggans inställningar som undflyr en rubrikfil som ingår i en översättningsenhet. Kompilatorn identifierar och meddelar nu programmeraren av kod som skrivits på det här sättet och utfärdar en valfri kompilatorvarning C4426 på platsen för den felaktiga - #include, om den är aktiverad. Den här varningen utfärdas endast om ändringarna står i konflikt med de optimeringsflaggor som angetts av kommandoradsargument till kompilatorn.- warning C4426: optimization flags changed after including header, may be due to #pragma optimize()- Exempel (före) - // C4426.h #pragma optimize("g", off) ... // C4426.h ends // C4426.cpp #include "C4426.h" // warning C4426- Exempel (efter) - // 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"
- Felmatchad #pragma warning(push) och #pragma warning(pop) (påverkar endast - /Wall- /WX)- Tidigare versioner av kompilatorn identifierade - #pragma warning(push)inte tillståndsändringar som paras ihop med- #pragma warning(pop)tillståndsändringar i en annan källfil, vilket sällan är avsett. Det här gamla beteendet skapade en risk för att programmet skulle kompileras med en annan uppsättning varningar aktiverade än programmeraren avsåg, vilket kan leda till tyst felaktigt körningsbeteende. Kompilatorn identifierar och meddelar nu programmeraren av kod som skrivits på det här sättet och utfärdar en valfri kompilatorvarning C5031 på platsen för matchande- #pragma warning(pop), om den är aktiverad. Den här varningen innehåller en anteckning som refererar till platsen för motsvarande #pragma varning(push).- warning C5031: #pragma warning(pop): likely mismatch, popping warning state pushed in different file- Exempel (före) - // 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 ...- Exempel (efter) - // 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" ...- Även om det är ovanligt är kod skriven på det här sättet ibland avsiktlig. Kod som skrivs på det här sättet är känslig för ändringar i - #includeordning. När det är möjligt rekommenderar vi att källkodsfiler hanterar varningstillståndet på ett självständigt sätt.
- Omatchad #pragma varning(push) (påverkar endast - /Wall- /WX)- Tidigare versioner av kompilatorn identifierade inte omatchade tillståndsändringar - #pragma warning(push)i slutet av en översättningsenhet. Kompilatorn identifierar nu och meddelar programmeraren om kod skriven på det här sättet och utfärdar en valfri kompilatorvarning C5032 vid platsen för den omatchade- #pragma warning(push), om den är aktiverad. Den här varningen utfärdas endast om det inte finns några kompileringsfel i översättningsenheten.- warning C5032: detected #pragma warning(push) with no corresponding #pragma warning(pop)- Exempel (före) - // 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- Exempel (efter) - // 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)
- Ytterligare varningar kan utfärdas till följd av förbättrad spårning av #pragma varningstillstånd - Tidigare versioner av kompilatorn spårade inte tillräckligt noggrant när #pragma varningsläge ändrades för att utfärda alla avsedda varningar. Det här beteendet skapade en risk för att vissa varningar effektivt skulle undertryckas under andra omständigheter än programmeraren avsåg. Kompilatorn spårar nu - #pragma warning-tillståndet mer robust, särskilt i relation till tillståndsändringar på- #pragma warninginom mallar, och utfärdar vid behov de nya varningarna C5031 och C5032, som är avsedda att hjälpa programmeraren att identifiera oavsiktliga användningar av- #pragma warning(push)och- #pragma warning(pop).- Som ett resultat av förbättrad - #pragma warningspårning av tillståndsändringar kan varningar som tidigare felaktigt undertryckts eller varningar relaterade till problem som tidigare var feldiagnostiserade nu utfärdas.
- Förbättrad identifiering av oåtkomlig kod - Ändringar i C++-standardbiblioteket och förbättrad möjlighet att anropa infogade funktioner jämfört med tidigare versioner av kompilatorn kan göra det möjligt för kompilatorn att bevisa att viss kod nu inte kan nås. Det här nya beteendet kan resultera i nya och vanligare utfärdade instanser av varning C4720. - warning C4720: unreachable code- I många fall kan den här varningen endast utfärdas när kompilering med optimeringar är aktiverade, eftersom optimeringar kan infoga fler funktionsanrop, eliminera redundant kod eller på annat sätt göra det möjligt att fastställa att viss kod inte kan nås. Vi har observerat att nya instanser av varning C4720 ofta har inträffat i try/catch-block, särskilt när det gäller användning av std::find. - Exempel (före) - try { auto iter = std::find(v.begin(), v.end(), 5); } catch (...) { do_something(); // ok }- Exempel (efter) - try { auto iter = std::find(v.begin(), v.end(), 5); } catch (...) { do_something(); // warning C4702: unreachable code }
Överensstämmelseförbättringar i uppdatering 2
- Ytterligare varningar och fel kan utfärdas till följd av partiellt stöd för uttrycket SFINAE - Tidigare versioner av kompilatorn parsade inte vissa typer av uttryck i - decltypespecificerare på grund av bristande stöd för uttrycket SFINAE. Det här gamla beteendet var felaktigt och överensstämmer inte med C++-standarden. Kompilatorn parsar nu dessa uttryck och har delvis stöd för uttrycket SFINAE på grund av pågående anpassningsförbättringar. Därför utfärdar kompilatorn nu varningar och fel som hittades i uttryck som tidigare versioner av kompilatorn inte parsade.- När det här nya beteendet parsar ett - decltypeuttryck som innehåller en typ som inte har deklarerats ännu, utfärdar kompilatorn kompilatorfelet C2039 som ett resultat.- error C2039: 'type': is not a member of 'global namespace'- Exempel 1: Användning av en odeklarerad typ (före) - struct s1 { template < typename T> auto f() - > decltype(s2< T> ::type::f()); // error C2039 template< typename> struct s2 {}; }- Exempel 1 (efter) - struct s1 { template < typename> // forward declare s2struct s2; template < typename T> auto f() - > decltype(s2< T> ::type::f()); template< typename> struct s2 {}; }- När det här nya beteendet parsar ett - decltypeuttryck som saknar nödvändig användning av nyckelordet- typenameför att ange att ett beroende namn är en typ, utfärdar kompilatorn kompilatorn varning C4346 tillsammans med kompilatorfel 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'- Exempel 2: Beroende namn är inte en typ (före) - 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 };- Exempel 2 (efter) - 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> ())); };
- volatilemedlemsvariabler förhindrar implicit definierade konstruktorer och tilldelningsoperatorer- Tidigare versioner av kompilatorn tillät en klass som har - volatilemedlemsvariabler att ha standardkonstruktorer för kopiering/flytt och standardoperatorer för kopierings-/flytttilldelning automatiskt genererade. Det här gamla beteendet var felaktigt och överensstämmer inte med C++-standarden. Kompilatorn anser nu att en klass som har- volatilemedlemsvariabler har icke-triviala bygg- och tilldelningsoperatorer, vilket förhindrar att standardimplementeringar av dessa operatorer genereras automatiskt. När en sådan klass är medlem i en union (eller en anonym union i en klass) definieras kopierings-/flyttkonstruktorerna och kopierings-/flytttilldelningsoperatorerna för facket (eller klassen som innehåller den anonyma unionen) implicit som borttagna. Att försöka konstruera eller kopiera unionen (eller klassen som innehåller den anonyma unionen) utan att uttryckligen definiera dem är ett fel och kompilatorn utfärdar kompilatorfelet C2280 som ett resultat.- error C2280: 'B::B(const B &)': attempting to reference a deleted function- Exempel (före) - 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- Exempel (efter) - 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
- Statiska medlemsfunktioner stöder inte cv-kvalificeringar. - Tidigare versioner av Visual Studio 2015 tillät statiska medlemsfunktioner kunna ha cv-kvalificerare. Det här beteendet beror på en regression i Visual Studio 2015 och Visual Studio 2015 Update 1. Visual Studio 2013 och tidigare versioner av kompilatorn avvisar kod som skrivits på det här sättet. Beteendet för Visual Studio 2015 och Visual Studio 2015 Update 1 är felaktigt och överensstämmer inte med C++-standarden. Visual Studio 2015 Update 2 avvisar kod som skrivits på det här sättet och utfärdar kompilatorfel C2511 i stället. - error C2511: 'void A::func(void) const': overloaded member function not found in 'A'- Exempel (före) - struct A { static void func(); }; void A::func() const {} // C2511- Exempel(efter) - struct A { static void func(); }; void A::func() {} // removed const
- Framåtdeklaration av enum-typ tillåts inte i WinRT-kod (påverkar endast - /ZW)- Kod som kompilerats för Windows Runtime (WinRT) tillåter inte att typer framdeklareras, på samma sätt som när hanterad C++-kod kompileras för .Net Framework med hjälp av kompilatorswitchen - enum. Det här beteendet säkerställer att storleken på en uppräkning alltid är känd och kan projiceras korrekt till WinRT-typsystemet. Kompilatorn avvisar kod som skrivits på det här sättet och utfärdar kompilatorfel C2599 tillsammans med kompilatorfel C3197.- error C2599: 'CustomEnum': the forward declaration of a WinRT enum is not allowed- error C3197: 'public': can only be used in definitions- Exempel (före) - 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; } };- Exempel (efter) - // forward declaration of CustomEnum removed namespace A { public enum class CustomEnum : int32 { Value1 }; } public ref class Component sealed { public: CustomEnum f() { return CustomEnum::Value1; } };
- Överlagrad icke-medlemsoperator ny och operatörsborttagning kanske inte deklareras infogad (nivå 1 ( - /W1) on-by-default)- Tidigare versioner av kompilatorn utfärdar ingen varning när icke-medlemsoperatorns nya och operatörsborttagningsfunktioner deklareras infogade. Kod som skrivs på det här sättet är dåligt utformad (ingen diagnostik krävs) och kan orsaka minnesproblem till följd av felmatchning av new- och delete-operatorer (särskilt när de används tillsammans med deallokering baserad på storlek) som kan vara svår att upptäcka. Kompilatorn utfärdar nu kompilatorvarning C4595 för att identifiera kod som skrivits på det här sättet. - warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline- Exempel (före) - inline void* operator new(size_t sz) // warning C4595 { ... }- Exempel (efter) - void* operator new(size_t sz) // removed inline { ... }- Att åtgärda kod som skrivs på det här sättet kan kräva att operatordefinitionerna flyttas från en rubrikfil och till en motsvarande källfil. 
Överensstämmelseförbättringar i uppdatering 3
- std::is_convertable identifierar nu självtilldelning (standardbibliotek) - Tidigare versioner av typdraget - std::is_convertableidentifierade inte korrekt självtilldelning av en klasstyp när dess kopieringskonstruktor tas bort eller är privat. Nu ställs- std::is_convertable<>::valuekorrekt in på- falsenär den tillämpas på en klasstyp med en borttagen eller privat kopieringskonstruktor.- Det finns ingen kompilatordiagnostik associerad med den här ändringen. - Exempel - #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");- I tidigare versioner av kompilatorn passerar de statiska påståendena längst ned i det här exemplet eftersom - std::is_convertable<>::valuefelaktigt ställdes in som- true.- std::is_convertable<>::valueär nu korrekt inställd på- false, vilket gör att de statiska påståendena misslyckas.
- Standard- eller borttagna triviala kopierings- och flyttkonstruktorer respekterar åtkomstspecifierare - Tidigare versioner av kompilatorn kontrollerade inte åtkomstspecificeraren för standardmässiga eller borttagna triviala kopierings- och flyttkonstruktorer innan de kunde anropas. Det här gamla beteendet var felaktigt och överensstämmer inte med C++-standarden. I vissa fall skapade det här gamla beteendet en risk för tyst felaktig kodgenerering, vilket resulterade i oförutsägbart körningsbeteende. Kompilatorn kontrollerar nu åtkomstspecificeraren för standardmässiga eller borttagna triviala kopierings- och flyttkonstruktorer för att avgöra om den kan anropas, och om inte, utfärdar kompilatorn varning C2248 som ett resultat. - error C2248: 'S::S' cannot access private member declared in class 'S'- Exempel (före) - 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 }- Exempel (efter) - class S { public: S() = default; private: S(const S&) = default; }; void f(const S&); // pass S by reference int main() { S s; f(s); }
- Utfasning av tilldelat ATL-kodstöd (nivå 1 ( - /W1) on-by-default)- Tidigare versioner av kompilatorn stödde tillskriven ATL-kod. Som nästa fas för att ta bort stöd för tillskriven ATL-kod som började i Visual Studio 2008 har den tillskrivna ATL-koden blivit inaktuell. Kompilatorn utfärdar nu kompilatorvarning C4467 för att identifiera den här typen av inaktuell kod. - warning C4467: Usage of ATL attributes is deprecated- Om du vill fortsätta använda tilldelad ATL-kod tills supporten har tagits bort från kompilatorn kan du inaktivera den här varningen genom att skicka argumenten - /Wv:18eller- /wd:4467kommandoradsargumenten till kompilatorn eller genom att lägga till- #pragma warning(disable:4467)i källkoden.- Exempel 1 (före) - [uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")] class A {};- Exempel 1 (efter) - __declspec(uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")) A {};- Ibland kanske du behöver eller vill skapa en IDL-fil för att undvika att använda inaktuella ATL-attribut, som i exempelkoden nedan - Exempel 2 (före) - [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 { // ... };- Skapa först filen *.idl; den vc140.idl-genererade filen kan användas för att hämta en *.idl-fil som innehåller gränssnitten och anteckningarna. - Lägg sedan till ett MIDL-steg i bygget för att se till att C++-gränssnittsdefinitionerna genereras. - Exempel 2 IDL (efter) - 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; }; }- Använd sedan ATL direkt i implementeringsfilen, som i exempelkoden nedan. - Genomförande av exempel 2 (efter) - #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() };
- Förkompilerade huvudfiler (PCH) och felmatchade #include direktiv (påverkar - /Wall- /WXendast )- Tidigare versioner av kompilatorn accepterade felmatchade - #includedirektiv i källfiler mellan- -Ycoch- -Yukompileringar när PCH-filer (precompiled header) används. Kod som skrivs på det här sättet accepteras inte längre av kompilatorn. Kompilatorn utfärdar nu kompilatorvarning CC4598 för att identifiera felmatchade- #includedirektiv när PCH-filer används.- warning C4598: 'b.h': included header file specified for Ycc.h at position 2 does not match Yuc.h at that position- Exempel (före): - 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"- Exempel (efter) - 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"
- Förkompilerade huvudfiler (PCH) och felmatchade inkluderingskataloger (påverkar endast - /Wall- /WX)- Tidigare versioner av kompilatorn accepterade felmatchade är katalog - -I() kommandoradsargument till kompilatorn mellan- -Ycoch- -Yukompileringar när du använder förkompilerade sidhuvudfiler (PCH). Kod som skrivs på det här sättet accepteras inte längre av kompilatorn. Kompilatorn utfärdar nu kompilatorvarning CC4599 för att identifiera felmatchade kommandoradsargument för katalog (- -I) när PCH-filer används.- warning C4599: '-I..' : specified for Ycc.h at position 1 does not match Yuc.h at that position- Exempel (före) - cl /c /Wall /Ycc.h -I.. X.cpp cl /c /Wall /Yuc.h Z.cpp- Exempel (efter) - cl /c /Wall /Ycc.h -I.. X.cpp cl /c /Wall /Yuc.h -I.. Z.cpp
Ändringar i Visual Studio 2013-överensstämmelse
Kompilator
- Det sista nyckelordet genererar nu ett olöst symbolfel där det skulle ha kompilerats tidigare: - struct S1 { virtual void f() = 0; }; struct S2 final : public S1 { virtual void f(); }; int main(S2 *p) { p->f(); }- I tidigare versioner utfärdades inte ett fel eftersom anropet var ett - virtualanrop. Programmet skulle ändå krascha vid körning. Nu utfärdas ett länkfel eftersom klassen är känd för att vara slutgiltig. I det här exemplet, för att åtgärda felet, skulle du länka mot obj som innehåller definitionen av- S2::f.
- När du använder vänfunktioner i namnområden måste du omdeklarera funktionen vän innan du refererar till den, annars får du ett fel eftersom kompilatorn nu överensstämmer med ISO C++ Standard. Det här exemplet kompilerar till exempel inte längre: - namespace NS { class C { void func(int); friend void func(C* const) {} }; void C::func(int) { NS::func(this); // error } }- Om du vill korrigera den här koden deklarerar du - friendfunktionen:- 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); }
- C++ Standard tillåter inte explicit specialisering i en klass. Även om Microsoft C++-kompilatorn tillåter det i vissa fall genereras ett fel, till exempel i följande exempel, eftersom kompilatorn inte anser att den andra funktionen är en specialisering av den första. - template < int N> class S { public: template void f(T& val); template < > void f(char val); }; template class S< 1>;- Ändra den andra funktionen för att korrigera den här koden: - template <> void f(char& val);
- Kompilatorn försöker inte längre att tvetydiga de två funktionerna i följande exempel och genererar nu ett fel: - template< typename T> void Func(T* t = nullptr); template< typename T> void Func(...); int main() { Func< int>(); // error }- För att korrigera den här koden förtydligar du anropet: - template< typename T> void Func(T* t = nullptr); template< typename T> void Func(...); int main() { Func< int>(nullptr); // ok }
- Innan kompilatorn hade överensstämt med ISO C++11 skulle följande kod ha kompilerats och lett till att - xresolverade till typen- int.- auto x = {0}; int y = x;- Den här koden löser - xtill en typ av- std::initializer_list<int>och ger ett fel på nästa rad som försöker tilldela- xtill en typ av- int. (Det finns ingen konvertering som standard.) Om du vill korrigera den här koden använder du- intför att ersätta- auto:- int x = {0}; int y = x;
- Aggregerad initiering tillåts inte längre när typen av det högra värdet inte matchar den typ av vänstervärde som initieras, och ett fel utfärdas eftersom ISO C++11 Standard kräver enhetlig initiering för att fungera utan att begränsa konverteringarna. Tidigare, om en begränsad konvertering var tillgänglig, skulle en kompilatorvarning (nivå 4) C4242 ha utfärdats i stället för ett fel. - int i = 0; char c = {i}; // error- Du korrigerar den här koden genom att lägga till en explicit begränsad konvertering: - int i = 0; char c = {static_cast<char>(i)};
- Följande initiering är inte längre tillåten: - void *p = {{0}};- Använd något av följande formulär för att korrigera den här koden: - void *p = 0; // or void *p = {0};
- Namnsökningen har ändrats. Följande kod löses på olika sätt i C++-kompilatorn i Visual Studio 2012 och Visual Studio 2013: - enum class E1 { a }; enum class E2 { b }; int main() { typedef E2 E1; E1::b; }- I Visual Studio 2012 löstes uttrycket - E1- E1::btill- ::E1i den globala omgivningen. I Visual Studio 2013 löses- E1i uttrycket- E1::btill definitionen av- typedef E2i- main()och har typen- ::E2.
- Objektlayouten har ändrats. På x64 kan objektlayouten för en klass ändras från tidigare versioner. Om den har en - virtualfunktion men inte har någon basklass som har en- virtualfunktion, infogar kompilatorns objektmodell en pekare i en- virtualfunktionstabell efter layouten för datamedlem. Det innebär att layouten kanske inte är optimal i alla fall. I tidigare versioner skulle en optimering för x64 försöka förbättra layouten åt dig, men eftersom den inte fungerade korrekt i komplexa kodsituationer togs den bort i Visual Studio 2013. Tänk till exempel på den här koden:- __declspec(align(16)) struct S1 { }; struct S2 { virtual ~S2(); void *p; S1 s; };
- I Visual Studio 2013 är resultatet på - sizeof(S2)x64 48, men i tidigare versioner utvärderas det till 32. Om du vill att detta ska utvärderas till 32 i Visual Studio 2013 C++-kompilatorn för x64 lägger du till en dummybasklass som har en- virtualfunktion:- __declspec(align(16)) struct S1 { }; struct dummy { virtual ~dummy() {} }; struct S2 : public dummy { virtual ~S2(); void *p; S1 s; };- Om du vill hitta platser i koden som en tidigare version skulle ha försökt optimera använder du en kompilator från den versionen tillsammans med kompilatoralternativet - /W3och aktiverar varning C4370. Till exempel:- #pragma warning(default:4370) __declspec(align(16)) struct S1 { }; struct S2 { virtual ~S2(); void *p; S1 s; };- Innan Visual Studio 2013 skriver den här koden ut följande meddelande: "warning C4370: 'S2' : layout av klassen har ändrats från en tidigare version av kompileraren på grund av bättre packning". - X86-kompilatorn har samma underoptimala layoutproblem i alla versioner av kompilatorn. Om den här koden till exempel kompileras för x86: - struct S { virtual ~S(); int i; double d; };- Resultatet av - sizeof(S)är 24. Den kan dock minskas till 16 om du använder den lösning som nämns för x64:- struct dummy { virtual ~dummy() {} }; struct S : public dummy { virtual ~S(); int i; double d; };
Standardbibliotek
C++-kompilatorn i Visual Studio 2013 detekterar felaktiga matchningar i _ITERATOR_DEBUG_LEVEL, som implementerades i Visual Studio 2010, och RuntimeLibrary-felmatchningar. Dessa felmatchningar uppstår när kompilatoralternativ /MT (statisk utgivning), /MTd (statisk felsökning), /MD (dynamisk utgivning) och /MDd (dynamisk felsökning) blandas.
- Om koden bekräftar den tidigare versionens simulerade aliasmallar måste du ändra den. I stället för - allocator_traits<A>::rebind_alloc<U>::othermåste du till exempel säga- allocator_traits<A>::rebind_alloc<U>. Även om- ratio_add<R1, R2>::typeinte längre är nödvändig och vi nu rekommenderar att du säger- ratio_add<R1, R2>, kommer den tidigare fortfarande att kompileras eftersom- ratio<N, D>måste ha en typedef av typen "typ" för ett reducerat förhållande, vilket kommer att vara samma typ om den redan är reducerad.
- Du måste använda - #include <algorithm>när du anropar- std::min()eller- std::max().
- Om din befintliga kod använder den tidigare versionens simulerade omfångsuppräkningar – traditionella uppräkningar som inte är begränsade till namnområden – måste du ändra den. Om du till exempel refererade till typen - std::future_status::future_statusmåste du nu säga- std::future_status. De flesta koderna påverkas dock inte, till exempel- std::future_status::readykompileras fortfarande.
- explicit operator bool()är striktare än operatorn unspecified-bool-type().- explicit operator bool()tillåter explicita konverteringar till bool , till exempel givet- shared_ptr<X> sp, både- static_cast<bool>(sp)och- bool b(sp)är giltiga – och boolesktestbara "kontextuella konverteringar" till bool – till exempel- if (sp),- !spvad- sp &&som helst. Förbjuder dock- explicit operator bool()implicita konverteringar till bool, så du kan inte säga- bool b = sp;och med en bool-returtyp kan du inte säga- return sp.
- Nu när verkliga variadic-mallar implementeras har _VARIADIC_MAX och relaterade makron ingen effekt. Om du fortfarande definierar _VARIADIC_MAX ignoreras det. Om du har använt våra makromaskiner som är avsedda att stödja simulerade variadiska mallar på något annat sätt än avsett måste du ändra din kod. 
- Förutom vanliga nyckelord förbjuder C++ standardbibliotekshuvuden nu makrobytet av kontextkänsliga nyckelord åsidosättning och slutlig. 
- reference_wrapper,- ref()och- cref()förbjuder nu bindning till temporära objekt.
- <random>framtvingar nu strikt sina kompileringstidsförutsättningar.
- Olika egenskaper för C++-standardbibliotekstyp har förhandsvillkoret "T ska vara en fullständig typ". Även om kompilatorn nu tillämpar den här förutsättningen striktare kanske den inte framtvingar den i alla situationer. (Eftersom förhandsvillkorsöverträdelser för C++ StandardBibliotek utlöser odefinierat beteende garanterar standardinställningen inte verkställighet.) 
- C++-standardbiblioteket stödjer inte - /clr:oldSyntax.
- C++11-specifikationen för - common_type<>hade oväntade och oönskade konsekvenser; i synnerhet får den- common_type<int, int>::typeatt returnera- int&&. Kompilatorn implementerar därför den föreslagna lösningen för biblioteksarbetsgruppens problem 2141, som returnerar- common_type<int, int="">::type- int.- Som en bieffekt av denna ändring fungerar inte längre identitetsfallet ( - common_type<T>resulterar inte alltid i typ- T). Det här beteendet överensstämmer med den föreslagna lösningen, men den bryter all kod som förlitade sig på det tidigare beteendet.- Om du behöver ett identitetstypdrag ska du inte använda den icke-standard - std::identitysom har definierats i- <type_traits>eftersom den inte fungerar för- <void>. Implementera i stället ditt eget identitetstypdrag som passar dina behov. Här är ett exempel:- template < typename T> struct Identity { typedef T type; };
MFC och ATL
- Endast Visual Studio 2013: MFC MBCS-biblioteket ingår inte i Visual Studio eftersom Unicode är så populärt och användningen av MBCS har minskat avsevärt. Den här ändringen håller även MFC mer anpassad med själva Windows SDK eftersom många av de nya kontrollerna och meddelandena är endast Unicode. Men om du måste fortsätta att använda MFC MBCS-biblioteket kan du ladda ned det från Microsoft Download Center på Multibyte MFC-biblioteket för Visual Studio 2013. Visual C++ Redistributable Package innehåller fortfarande det här biblioteket. (Obs! MBCS DLL ingår i C++-installationskomponenterna i Visual Studio 2015 och senare). 
- Tillgängligheten för MFC-menyfliksområdet har ändrats. I stället för en arkitektur på en nivå finns det nu en hierarkisk arkitektur. Du kan fortfarande använda det gamla beteendet genom att anropa - CRibbonBar::EnableSingleLevelAccessibilityMode().
- CDatabase::GetConnect-metoden tas bort. För att förbättra säkerheten lagras anslutningssträngen nu krypterad och dekrypteras endast efter behov. det kan inte returneras som oformaterad text. Strängen kan erhållas med hjälp av- CDatabase::Dumpmetoden.
- Signaturen för - CWnd::OnPowerBroadcasthar ändrats. Signaturen för den här meddelandehanteraren ändras för att ta en LPARAM som den andra parametern.
- Signaturer ändras för att passa meddelandehanterare. Parameterlistorna för följande funktioner har ändrats för att använda nyligen tillagda ON_WM_* meddelandehanterare: - CWnd::OnDisplayChangehar ändrats till (UINT, int, int) i stället för (WPARAM, LPARAM) så att det nya ON_WM_DISPLAYCHANGE makrot kan användas i meddelandekartan.
- CFrameWnd::OnDDEInitiatehar ändrats till (CWnd*, UINT, UNIT) i stället för (WPARAM, LPARAM) så att det nya ON_WM_DDE_INITIATE makrot kan användas i meddelandekartan.
- CFrameWnd::OnDDEExecutehar ändrats till (CWnd*, HANDLE) i stället för (WPARAM, LPARAM) så att det nya ON_WM_DDE_EXECUTE makrot kan användas på meddelandekartan.
- CFrameWnd::OnDDETerminatehar ändrats till (CWnd*) som parameter i stället för (WPARAM, LPARAM) så att det nya ON_WM_DDE_TERMINATE makrot kan användas i meddelandekartan.
- CMFCMaskedEdit::OnCuthar ändrats till inga parametrar i stället för (WPARAM, LPARAM) så att det nya ON_WM_CUT makrot kan användas i meddelandekartan.
- CMFCMaskedEdit::OnClearhar ändrats till inga parametrar i stället för (WPARAM, LPARAM) så att det nya ON_WM_CLEAR makrot kan användas i meddelandekartan.
- CMFCMaskedEdit::OnPastehar ändrats till inga parametrar i stället för (WPARAM, LPARAM) så att det nya ON_WM_PASTE makrot kan användas i meddelandekartan.
 
- #ifdefdirektiv i MFC-huvudfilerna tas bort. Många- #ifdefdirektiv i MFC-huvudfilerna som rör versioner av Windows (- WINVER < 0x0501) som inte stöds tas bort.
- ATL DLL (atl120.dll) tas bort. ATL tillhandahålls nu som rubriker och ett statiskt bibliotek (atls.lib). 
- Atlsd.lib, atlsn.lib och atlsnd.lib tas bort. Atls.lib har inte längre teckenuppsättningsberoenden eller kod som är specifika för felsökning/lansering. Eftersom det fungerar på samma sätt för Unicode/ANSI och felsökning/version krävs endast en version av biblioteket. 
- ATL/MFC Trace-verktyget tas bort tillsammans med ATL DLL och spårningsmekanismen förenklas. Konstruktorn - CTraceCategorytar nu en parameter (kategorinamnet) och TRACE-makrona anropar CRT-felsökningsrapporteringsfunktionerna.
Brytande ändringar i Visual Studio 2012
Kompilator
- Kompilatoralternativet - /Ylhar ändrats. Kompilatorn använder som standard det här alternativet, vilket kan leda till LNK2011 fel under vissa förhållanden. För mer information, se /Yl (Mata in PCH-referens för felsökningsbiblioteket).
- I kod som kompileras med - /clr, definierar nyckelordet class- enumen C++11-uppräkning, inte en CLR-uppräkning (Common Language Runtime). Om du vill definiera en CLR-uppräkning måste du vara tydlig med dess tillgänglighet.
- Använd nyckelordet "template" för att uttryckligen klargöra ett beroende namn i enlighet med C++-standardens krav. I följande exempel är nyckelordet för den markerade mallen obligatoriskt för att lösa tvetydigheten. Mer information finns i Namnmatchning för beroende typer. - template < typename X = "", typename = "" AY = ""> struct Container { typedef typename AY::template Rebind< X> ::Other AX; };
- Konstant uttryck av typen float tillåts inte längre som ett mallargument, som du ser i följande exempel. - template<float n=3.14> struct B {}; // error C2993: 'float': illegal type for non-type template parameter 'n'
- Kod som kompileras med kommandoradsalternativet - /GSoch har en off-by-one sårbarhet kan leda till att processen termineras vid körtid, vilket visas i följande pseudokod-exempel.- char buf[MAX]; int cch; ManipulateString(buf, &cch); // ... buf[cch] = '\0'; // if cch >= MAX, process will terminate
- Standardarkitekturen för x86-versioner ändras till SSE2. Kompilatorn kan därför avge SSE-instruktioner och använder XMM-registren för att utföra flyttalsberäkningar. Om du vill återgå till tidigare beteende använder du kompilatorflaggan - /arch:IA32för att ange arkitekturen som IA32.
- Kompilatorn kan utfärda varningar Kompilatorvarning (nivå 4) C4703 och C4701 där den tidigare inte gjorde det. Kompilatorn tillämpar starkare kontroller för användning av uninitialiserade lokala variabler av pekartyp. 
- När den nya länkflaggan - /HIGHENTROPYVAhar angetts orsakar Windows 8 vanligtvis minnesallokeringar för att returnera en 64-bitars adress. (Före Windows 8 returnerade sådana allokeringar oftare adresser som var mindre än 2 GB.) Den här ändringen kan exponera pekartunkeringsbuggar i befintlig kod. Som standard är den här växeln på. Om du vill inaktivera det här beteendet anger du- /HIGHENTROPYVA:NO.
- Den hanterade kompilatorn (Visual Basic/C#) har också stöd - /HIGHENTROPYVAför hanterade versioner. Men i det här fallet är- /HIGHENTROPYVAswitchinaktiverad som standard.
IDE
- Även om vi rekommenderar att du inte skapar Windows Forms-program i C++/CLI, stöds underhåll av befintliga C++/CLI-gränssnittsprogram. Om du måste skapa ett Windows Forms-program eller något annat .NET-användargränssnittsprogram använder du C# eller Visual Basic. Använd endast C++/CLI i samverkanssyfte.
Bibliotek för parallella mönster och samtidighetskörningsbibliotek
Uppräkningen SchedulerType av UmsThreadDefault är inaktuell. Specifikationen av UmsThreadDefault genererar en inaktuell varning och mappar internt tillbaka till ThreadScheduler.
Standardbibliotek
- Efter en genombrottsändring mellan C++98/03- och C++11-standarderna går det vanligtvis inte att använda explicita mallargument för att anropa - make_pair()– som i- make_pair<int, int>(x, y)– i Visual C++ i Visual Studio 2012. Lösningen är att alltid anropa- make_pair()utan explicita mallargument – som i- make_pair(x, y). Att tillhandahålla explicita mallargument motverkar funktionens syfte. Om du behöver exakt kontroll över den resulterande typen använder du- pairi stället för- make_pair– som i- pair<short, short>(int1, int2).
- En annan icke-bakåtkompatibel ändring mellan C++98/03- och C++11-standarderna: När A kan implicit konverteras till B och B kan implicit konverteras till C, men A inte kan implicit konverteras till C, tillät C++98/03 och Visual Studio 2010 - pair<A, X>att konverteras (implicit eller explicit) till- pair<C, X>. (Den andra typen, X, är inte av intresse här och är inte specifik för den första typen i paret.) C++-kompilatorn i Visual Studio 2012 identifierar att A inte implicit kan konverteras till C och tar bort parkonverteringen från överbelastningsupplösning. Den här ändringen är positiv för många scenarier. Till exempel kommer överlagring- func(const pair<int, int>&)och- func(const pair<string, string>&)och att anropa- func()med- pair<const char *, const char *>att kompilera med den här ändringen. Den här ändringen bryter dock kod som förlitade sig på aggressiva parkonverteringar. Sådan kod kan vanligtvis åtgärdas genom att utföra en del av konverteringen explicit, till exempel genom att skicka- make_pair(static_cast<B>(a), x)till en funktion som förväntar sig- pair<C, X>.
- Simulerade variadmallar i Visual Studio 2010 – till exempel - make_shared<T>(arg1, arg2, argN)– upp till en gräns på 10 argument genom att utrota överlagringar och specialiseringar med maskiner för förprocessorer. I Visual Studio 2012 minskas den här gränsen till fem argument för att förbättra kompileringstiderna och kompilatorns minnesförbrukning för de flesta användare. Du kan dock ange den tidigare gränsen genom att uttryckligen definiera _VARIADIC_MAX som 10, hela projektet.
- C++11 17.6.4.3.1 [macro.names]/2 förbjuder makrobyte av nyckelord när C++ Standard Library-huvuden inkluderas. Rubrikerna genererar nu kompilatorfel om de identifierar makro-ersatta nyckelord. (Genom att definiera _ALLOW_KEYWORD_MACROS kan sådan kod kompileras, men vi avråder starkt från den användningen.) Som ett undantag tillåts makroformen - newav som standard, eftersom rubrikerna skyddar sig fullständigt med hjälp- #pragma push_macro("new")/- #undef new/- #pragma pop_macro("new")av . Att definiera _ENFORCE_BAN_OF_MACRO_NEW gör exakt vad namnet antyder.
- För att implementera olika optimeringar och felsökningskontroller bryter C++ Standard Library-implementeringen avsiktligt binär kompatibilitet mellan versioner av Visual Studio (2005, 2008, 2010, 2012). När C++-standardbiblioteket används förbjuder det blandning av objektfiler och statiska bibliotek som kompileras med hjälp av olika versioner i en binär fil (EXE eller DLL) och förbjuder överföring av C++ standardbiblioteksobjekt mellan binärfiler som kompileras med hjälp av olika versioner. Blandning av objektfiler och statiska bibliotek (med hjälp av C++-standardbiblioteket som kompilerades med hjälp av Visual Studio 2010 med de som kompilerades med hjälp av C++-kompilatorn i Visual Studio 2012 genererar länkfel om _MSC_VER matchningsfel, där _MSC_VER är makrot som innehåller kompilatorns huvudversion (1700 för Visual C++ i Visual Studio 2012). Den här kontrollen kan inte identifiera DLL-blandning och kan inte identifiera blandning som omfattar Visual Studio 2008 eller tidigare. 
- Förutom att identifiera _ITERATOR_DEBUG_LEVEL missmatchningar, som implementerades i Visual Studio 2010, upptäcker C++-kompilatorn i Visual Studio 2012 missmatchningar i körbiblioteket. Dessa matchningar uppstår när kompilatoralternativen - /MT(statisk version),- /MTd(statisk felsökning),- /MD(dynamisk version) och- /MDd(dynamisk felsökning) blandas.
- operator<(),- operator>(),- operator<=()och- operator>=()var tidigare tillgängliga för- std::unordered_map- och- stdext::hash_map-familjerna av containrar, även om deras implementeringar inte var användbara. Dessa icke-standardoperatorer har tagits bort i Visual C++ i Visual Studio 2012. Dessutom har genomförandet av- operator==()och- operator!=()för- std::unordered_map-familjen utökats för att täcka- stdext::hash_map-familjen. (Vi rekommenderar att du undviker att använda- stdext::hash_mapfamiljen i ny kod.)
- C++11 22.4.1.4 [locale.codecvt] anger detta - codecvt::length()och- codecvt::do_length()bör ta modifierbara- stateT¶metrar, men Visual Studio 2010 tog- const stateT&. C++-kompilatorn i Visual Studio 2012 tar- stateT&som föreskrivs av standarden. Den här skillnaden är betydande för alla som försöker åsidosätta den virtuella funktionen- do_length().
CRT
- C Runtime (CRT)-heapen, som används för new och malloc(), är inte längre privat. CRT använder nu process-heapen. Det innebär att heapen inte förstörs när en DLL avladdas, så DLL:er som länkar statiskt till CRT måste se till att minnet som allokerats av DLL-koden rengörs innan DLL:en avladdas. 
- Funktionen - iscsymf()hävdar med negativa värden.
- Structen - threadlocaleinfostructhar ändrats för att anpassa ändringarna till nationella funktioner.
- CRT-funktioner som har motsvarande inbyggda funktioner, till exempel - memxxx(),- strxxx()tas bort från intrin.h. Om du bara har inkluderat intrin.h för dessa funktioner måste du nu inkludera motsvarande CRT-huvuden.
MFC och ATL
- Stöd för fusion har tagits bort (afxcomctl32.h); Därför har alla metoder som definierats i - <afxcomctl32.h>tagits bort. Huvudfiler- <afxcomctl32.h>och- <afxcomctl32.inl>har tagits bort.
- Ändrade namnet på - CDockablePane::RemoveFromDefaultPaneDividiertill- CDockablePane::RemoveFromDefaultPaneDivider.
- Ändrade signaturen - CFileDialog::SetDefExtför att använda LPCTSTR, därför påverkas Unicode-versioner.
- Föråldrade ATL-spårningskategorier har tagits bort. 
- Ändrade signaturen för - CBasePane::MoveWindowså att den tar en- const CRect.
- Ändrade signaturen för - CMFCEditBrowseCtrl::EnableBrowseButton.
- Tog bort - m_fntTabsoch- m_fntTabsBoldfrån- CMFCBaseTabCtrl.
- Lade till en parameter i konstruktorerna - CMFCRibbonStatusBarPane. (Det är en standardparameter, så den är inte källbrytande.)
- Lade till en parameter i - CMFCRibbonCommandsListBoxkonstruktorn. (Det är en standardparameter, så den är inte källbrytande.)
- Tog bort API:et - AFXTrackMouse(och relaterad tidsinställd process). Använd Win32-API- TrackMouseEvent:et i stället.
- Lade till en parameter i - CFolderPickerDialogkonstruktorn. (Det är en standardparameter, så den är inte källbrytande.)
- CFileStatusstrukturstorleken har ändrats: Medlemmen- m_attributehar ändrats från BYTE till DWORD (för att matcha värdet som returneras från- GetFileAttributes).
- CRichEditCtrloch- CRichEditViewanvänd MSFTEDIT_CLASS (RichEdit 4.1-kontroll) i stället för RICHEDIT_CLASS (RichEdit 3.0-kontroll) i Unicode-versioner.
- Har tagits bort - AFX_GLOBAL_DATA::IsWindowsThemingDrawParentBackgroundeftersom det alltid är SANT i Windows Vista, Windows 7 och Windows 8.
- Har tagits bort - AFX_GLOBAL_DATA::IsWindowsLayerSupportAvailableeftersom det alltid är SANT i Windows Vista, Windows 7 och Windows 8.
- Tog bort - AFX_GLOBAL_DATA::DwmExtendFrameIntoClientArea. Anropa Windows API direkt i Windows Vista, Windows 7 och Windows 8.
- Tog bort - AFX_GLOBAL_DATA::DwmDefWindowProc. Anropa Windows API direkt i Windows Vista, Windows 7 och Windows 8.
- Bytte namn på - AFX_GLOBAL_DATA::DwmIsCompositionEnabledtill- IsDwmCompositionEnabledför att eliminera namnkollision.
- Ändrade identifierare för ett antal interna MFC-timers och flyttade definitionerna till afxres.h (AFX_TIMER_ID_*). 
- Ändrade signaturen - OnExitSizeMoveför metoden för att överensstämma med makrot ON_WM_EXITSIZEMOVE:- CFrameWndEx
- CMDIFrameWndEx
- CPaneFrameWnd
 
- Ändrade namnet och signaturen för - OnDWMCompositionChangedför att överensstämma med makrot ON_WM_DWMCOMPOSITIONCHANGED:- CFrameWndEx
- CMDIFrameWndEx
- CPaneFrameWnd
 
- Ändrade signaturen - OnMouseLeaveför metoden för att överensstämma med makrot ON_WM_MOUSELEAVE:- CMFCCaptionBar
- CMFCColorBar
- CMFCHeaderCtrl
- CMFCProperySheetListBox
- CMFCRibbonBar
- CMFCRibbonPanelMenuBar
- CMFCRibbonRichEditCtrl
- CMFCSpinButtonCtrl
- CMFCToolBarErsättDennaText
- CMFCToolBarComboBoxEdit
- CMFCToolBarEditCtrl
- CMFCAutoHideBar
 
- Ändrade signaturen - OnPowerBroadcastför för att överensstämma med makrot ON_WM_POWERBROADCAST:- CFrameWndEx
- CMDIFrameWndEx
 
- Har ändrat signaturen - OnStyleChangedför för att överensstämma med makrot ON_WM_STYLECHANGED:- CMFCListCtrl
- CMFCStatusBar
 
- Den interna metoden - FontFamalyProcFontshar bytt namn till- FontFamilyProcFonts.
- Flera globala statiska - CStringobjekt har tagits bort för att eliminera minnesläckor i vissa situationer (ersatta med #defines) och följande klassmedlemsvariabler:- 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
 
- Ändrade signaturen för - CKeyboardManager::ShowAllAcceleratorsoch tog bort parametern för acceleratoravgränsare.
- Lade till - CPropertyPage::GetParentSheet, och i- CPropertyPage-klassen anropar du nu detta istället för- GetParentför att hämta rätt överordnat bladfönster, som kan vara det överordnade eller ett förfädersfönster till- CPropertyPage. Du kan behöva ändra koden för att anropa- GetParentSheeti stället för- GetParent.
- Åtgärdade obalanserad #pragma warning(push) i ATLBASE.H, vilket gjorde att varningar inaktiverades felaktigt. Dessa varningar är nu aktiverade korrekt efter ATLBASE. H har parsats. 
- Flyttade D2D-relaterade metoder från AFX_GLOBAL_DATA till _AFX_D2D_STATE: - GetDirectD2dFactory
- GetWriteFactory
- GetWICFactory
- InitD2D
- ReleaseD2DRefs
- IsD2DInitialized
- D2D1MakeRotateMatrix
- I stället för att anropa till exempel - afxGlobalData.IsD2DInitialized, anropa- AfxGetD2DState->IsD2DInitialized.
 
- Tog bort föråldrad ATL*. CPP-filer från mappen \atlmfc\include\. 
- Flyttade - afxGlobalDatainitieringen till på begäran istället för under CRT-initieringsfasen, för att uppfylla- DLLMainkrav.
- RemoveButtonByIndexMetoden har lagts till i- CMFCOutlookBarPaneklassen.
- Korrigerade - CMFCCmdUsageCount::IsFreqeuntlyUsedCmdtill- IsFrequentlyUsedCmd.
- Korrigerade flera instanser av - RestoreOriginalstatetill- RestoreOriginalState (CMFCToolBar, CMFCMenuBar, CMFCOutlookBarPane).
- Oanvända metoder har tagits bort från - CDockablePane:- SetCaptionStyle,- IsDrawCaption,- IsHideDisabledButtons,- GetRecentSiblingPaneInfooch- CanAdjustLayout.
- Tog bort - CDockablePanestatiska medlemsvariabler- m_bCaptionTextoch- m_bHideDisabledButtons.
- Lade till en åsidosättningsmetod - DeleteStringi- CMFCFontComboBox.
- Oanvända metoder har tagits bort från - CPane:- GetMinLengthoch- IsLastPaneOnLastRow.
- Har bytt - CPane::GetDockSiteRow(CDockingPanesRow *)namn till- CPane::SetDockSiteRow.
Ändringar som bryter kompatibilitet i Visual Studio 2010
Kompilator
- Nyckelordet - autohar en ny standard betydelse. Eftersom användningen av den gamla innebörden är sällsynt påverkas de flesta program inte av den här ändringen.
- Det nya - static_assertnyckelordet introduceras, vilket orsakar en namnkonflikt om det redan finns en identifierare med det namnet i koden.
- Stöd för den nya lambda-notationen utesluter stöd för kodning av ett ociterat GUID i ett IDL uuid-attribut. 
- .NET Framework 4 introducerar begreppet skadade tillståndsundanstag, som är undantag som lämnar en process i ett oåterkalleligt skadat tillstånd. Som standardinställning kan du inte fånga ett skadad tillståndsundantag, även med kompileringsalternativet /EHa som fångar alla andra undantag. Använd __try-__except-instruktioner för att uttryckligen fånga ett skadat tillståndsfel. Du kan också använda attributet [HandledProcessCorruptedStateExceptions] för att aktivera en funktion för att fånga skadade tillståndsundantag. Den här ändringen påverkar främst systemprogrammerare som kan behöva fånga ett undantag för skadat tillstånd. De åtta undantagen är 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. Mer information om dessa undantag finns i makrot GetExceptionCode . 
- Det ändrade - /GSkompileringsalternativet skyddar mot buffertöverskridanden mer omfattande än i tidigare versioner. Den här versionen kan infoga ytterligare säkerhetskontroller i stacken som kan minska prestandan. Använd det nya- __declspec(safebuffers)nyckelordet för att instruera kompilatorn att inte infoga säkerhetskontroller för en viss funktion.
- Om du kompilerar med kompileringsalternativen - /GL- /clr(hela programoptimering) och- /GL(Common Language Runtime-kompilering) ignoreras alternativet. Den här ändringen gjordes eftersom kombinationen av kompilatoralternativ gav liten fördel. Som ett resultat av den här ändringen förbättras byggets prestanda.
- Som standard inaktiveras stöd för trigrafer i Visual Studio 2010. Använd kompileringsalternativet - /Zc:trigraphsför att aktivera stöd för trigrafer. En trigraf består av två på varandra följande frågetecken ("??") följt av ett unikt tredje tecken. Kompilatorn ersätter en trigraf med motsvarande skiljetecken. Kompilatorn ersätter till exempel trigrafen- ??=med tecknet #. Använd trigrafer i C-källfiler som använder en teckenuppsättning som inte innehåller praktiska grafiska representationer för vissa skiljetecken.
- Länkaren stöder inte längre optimering för Windows 98. Alternativet - /OPT(Optimeringar) skapar ett kompileringstidsfel om du anger- /OPT:WIN98eller- /OPT:NOWIN98.
- Standardalternativen för kompilatorn som anges av systemegenskaperna RuntimeLibrary och DebugInformationFormat har ändrats. Som standard anges dessa byggegenskaper i projekt som skapas av Visual C++ versioner 7.0 till 10.0. Om du migrerar ett projekt som skapades av Visual C++ 6.0 bör du överväga om du vill ange ett värde för dessa egenskaper. 
- I Visual Studio 2010, RuntimeLibrary = MultiThreaded ( - /MD) och DebugInformationFormat = ProgramDatabase (- /Zi). I Visual C++ 9.0, RuntimeLibrary = Flertrådad (- /MT) och DebugInformationFormat = Inaktiverad.
CLR (Common Language Runtime)
- Microsoft C# och Visual Basic-kompilatorerna kan nu skapa utan en primär interop-sammansättning (ingen PIA). En sammansättning utan PIA kan använda sig av COM-typer utan att distribuera den relevanta primära interop-samlingen. När du använder no-PIA-sammansättningar som skapats av Visual C# eller Visual Basic måste du referera till PIA-sammansättningen i kompileringskommandot innan du refererar till någon no-PIA-sammansättning som använder biblioteket.
Visual Studio C++-projekt och MSBuild
- Visual Studio C++-projekt baseras nu på VERKTYGET MSBuild. Därför använder projektfiler ett nytt XML-filformat och ett .vcxproj filsuffix. Visual Studio 2010 konverterar automatiskt projektfiler från tidigare versioner av Visual Studio till det nya filformatet. Ett befintligt projekt påverkas om det beror på det tidigare byggverktyget, VCBUILD.exeeller projektfilsuffixet .vcproj. 
- I tidigare versioner stödde Visual C++ den sena utvärderingen av egenskapsblad. Ett överordnat egenskapsblad kan till exempel importera ett underordnat egenskapsblad, och den överordnade kan använda en variabel som definierats i det underordnade objektet för att definiera andra variabler. Försenad utvärdering gjorde det möjligt för föräldern att använda barnvariabeln redan innan barnets egenskapsblad importerades. I Visual Studio 2010 kan en projektdokumentvariabel inte användas innan den definieras eftersom MSBuild endast stöder tidig utvärdering. 
IDE
- Dialogrutan för programavslut avslutar inte längre ett program. I tidigare versioner, när - abort()funktionen eller- terminate()stängde detaljhandelsversionen av ett program, visade C Run-Time-biblioteket ett meddelande om programavslut i ett konsolfönster eller en dialogruta. Meddelandet sa delvis: "Det här programmet har begärt att Runtime ska avsluta det på ett ovanligt sätt. Kontakta programmets supportteam för mer information." Meddelandet om programavslut var redundant eftersom Windows senare visade den aktuella avslutningshanteraren, vilket vanligtvis var dialogrutan Windows Error Reporting (Dr. Watson) eller Visual Studio-felsökningsprogrammet. Från och med Visual Studio 2010 visas inte meddelandet i C Run-Time-biblioteket. Dessutom förhindrar körmiljön att programmet avslutas innan en felsökare startar. Det här är en kritisk ändring bara om du förlitar dig på det tidigare beteendet av programavslutsmeddelandet.
- Specifikt för Visual Studio 2010 fungerar inte IntelliSense för C++/CLI-kod eller -attribut, Hitta alla referenser fungerar inte för lokala variabler och Kodmodellen hämtar inte typnamn från importerade sammansättningar eller löser typer till sina fullständigt kvalificerade namn. 
Bibliotek
- Klassen SafeInt ingår i Visual C++ och finns inte längre i en separat nedladdning. Det här är bara en icke-bakåtkompatibel ändring om du har utvecklat en klass med namnet "SafeInt". 
- Distributionsmodellen för bibliotek använder inte längre manifest för att hitta en viss version av ett dynamiskt länkbibliotek. I stället innehåller namnet på varje dynamiskt länkbibliotek dess versionsnummer och du använder det namnet för att hitta biblioteket. 
- I tidigare versioner av Visual Studio kunde du återskapa körtidsbiblioteken. Visual Studio 2010 har inte längre stöd för att skapa egna kopior av C-körningsbiblioteksfilerna. 
Standardbibliotek
- Huvudet - <iterator>inkluderas inte längre automatiskt av många andra huvudfiler. Inkludera i stället rubriken explicit om du behöver stöd för de fristående iteratorer som definierats i rubriken. Ett befintligt projekt påverkas om det beror på det tidigare byggverktyget, VCBUILD.exeeller projektfilsuffixet .vcproj.iterator.
- I rubriken - <algorithm>tas funktionerna- checked_*och- unchecked_*bort. Och i- <iterator>>-rubriken tas- checked_iterator-klassen bort och- unchecked_array_iterator-klassen har lagts till.
- Konstruktorn - CComPtr::CComPtr(int)tas bort. Konstruktorn tillät att ett- CComPtrobjekt konstruerades från NULL-makrot, men var onödigt och tillät meningslösa konstruktioner från heltal som inte är noll.- A - CComPtrkan fortfarande konstrueras från NULL, som definieras som 0, men misslyckas om det konstrueras från ett annat heltal än literal 0. Använd- nullptri stället.
- Följande - ctypemedlemsfunktioner har tagits bort:- ctype::_Do_narrow_s,- ctype::_Do_widen_s,- ctype::_narrow_s,- ctype::_widen_s. Om ett program använder någon av dessa medlemsfunktioner måste du ersätta den med motsvarande icke-säkra version:- ctype::do_narrow,- ctype::do_widen,- ctype::narrow,- ctype::widen.
CRT-, MFC- och ATL-bibliotek
- Stöd har tagits bort för användare för att skapa CRT-, MFC- och ATL-biblioteken. Till exempel tillhandahålls ingen lämplig NMAKE-fil. Användarna har dock fortfarande åtkomst till källkoden för dessa bibliotek. Och ett dokument som beskriver de MSBuild-alternativ som Microsoft använder för att skapa dessa bibliotek kommer förmodligen att publiceras i en Visual C++ Team-blogg. 
- MFC-stöd för IA64 har tagits bort. Stöd för CRT och ATL på IA64 tillhandahålls dock fortfarande. 
- Ordningstal återanvänds inte längre i MFC-moduldefinitionsfiler (.def). Den här ändringen innebär att ordningstalen inte skiljer sig mellan mindre versioner, och binär kompatibilitet för servicepaket och snabbkorrigeringsversioner kommer att förbättras. 
- En ny virtuell funktion har lagts till i - CDocTemplateklassen. Den nya virtuella funktionen är CDocTemplate Class. Den tidigare versionen av- OpenDocumentFilehade två parametrar. Den nya versionen har tre parametrar. För att stödja omstartshanteraren måste alla klasser som härleds från- CDocTemplateimplementera den version som har tre parametrar. Den nya parametern är- bAddToMRU.
Makron och miljövariabler
- Miljövariabeln __MSVCRT_HEAP_SELECT stöds inte längre. Den här miljövariabeln tas bort och det finns ingen ersättning.
Referens för Microsoft Macro Assembler
- Flera direktiv har tagits bort från Microsoft Macro Assembler-referenskompilatorn. De borttagna direktiven är .186,.286,.286P,.287,.8086och.8087.NO87.
Icke-bakåtkompatibla ändringar i Visual Studio 2008
Kompilator
- Plattformarna Windows 95, Windows 98, Windows ME och Windows NT stöds inte längre. Dessa operativsystem har tagits bort från listan över målplattformar. 
- Kompilatorn stöder inte längre flera attribut som är direkt associerade med ATL Server. Följande attribut stöds inte längre: - prestandaräknare 
- perf_object 
- perfmon (prestandaövervakningsverktyget) 
- förfrågningshanterare 
- SOAP-handler 
- SOAP-huvud 
- soap_metod 
- taggnamn 
 
Visual Studio C++-projekt
- När du uppgraderar projekt från tidigare versioner av Visual Studio kan du behöva ändra WINVER och _WIN32_WINNT makron så att de är större än eller lika med 0x0500. 
- Från och med Visual Studio 2008 har den nya projektguiden inget alternativ för att skapa ett C++ SQL Server-projekt. SQL Server-projekt som skapats med hjälp av en tidigare version av Visual Studio kompileras fortfarande och fungerar korrekt. 
- Windows API-huvudfilen Winable.h har tagits bort. Inkludera Winuser.h i stället. 
- Windows API-biblioteket Rpcndr.lib har tagits bort. Länka med rpcrt4.lib i stället. 
CRT
- Stöd för Windows 95, Windows 98, Windows Millennium Edition och Windows NT 4.0 har tagits bort. 
- Följande globala variabler har tagits bort: - _osplatform 
- _osver 
- _winmajor 
- _winminor 
- _winver 
 
- Följande funktioner har tagits bort. Använd Windows API-funktionerna - GetVersioneller- GetVersionExi stället:- _get_osplatform 
- _get_osver 
- _get_winmajor 
- _get_winminor 
- _get_winver 
 
- Syntaxen för SAL-anteckningar har ändrats. Mer information finns i SAL-anteckningar. 
- IEEE-filtret stöder nu instruktionsuppsättningen SSE 4.1. Mer information finns i - _fpieee_flt.
- De C Run-Time-bibliotek som levereras med Visual Studio är inte längre beroende av systemets DLL-msvcrt.dll. 
Standardbibliotek
- Stöd för Windows 95, Windows 98, Windows Millennium Edition och Windows NT 4.0 har tagits bort. 
- När du kompilerar i felsökningsläge med _HAS_ITERATOR_DEBUGGING definierat (ersatt av _ITERATOR_DEBUG_LEVEL efter Visual Studio 2010), kommer ett program nu att kontrollera när en iterator försöker öka eller minska gränsen för den underliggande containern. 
- Medlemsvariabeln c för stackklassen är nu skyddad. Tidigare förklarades den här medlemsvariabeln offentlig. 
- Beteendet av - money_get::do_gethar ändrats. Tidigare, när du analyserade en monetär mängd med fler bråksiffror än vad som behövs av- frac_digits, brukade- do_getkonsumera alla.- do_getslutar nu analys efter att ha analyserat som mest- frac_digitstecken.
ATL
- ATL kan inte skapas utan ett beroende av CRT. I tidigare versioner av Visual Studio kan du använda #define ATL_MIN_CRT för att göra ett ATL-projekt minimalt beroende av CRT. I Visual Studio 2008 är alla ATL-projekt minimalt beroende av CRT oavsett om ATL_MIN_CRT har definierats. 
- ATL Server-kodbasen har släppts som ett delat källkodsprojekt på CodePlex och är inte installerad som en del av Visual Studio. Datakodnings- och avkodningsklasser från atlenc.h och verktygsfunktioner och klasser från atlutil.h och atlpath.h har sparats och ingår nu i ATL-biblioteket. Flera filer som är associerade med ATL Server ingår inte längre i Visual Studio. 
- Vissa funktioner ingår inte längre i DLL:n. De finns fortfarande i importbiblioteket. Detta påverkar inte kod som använder funktionerna statiskt. Det påverkar endast den kod som använder dessa funktioner dynamiskt. 
- Makrona PROP_ENTRY och PROP_ENTRY_EX har föråldrats och ersatts med makron PROP_ENTRY_TYPE och PROP_ENTRY_TYPE_EX av säkerhetsskäl. 
Delade ATL/MFC-klasser
- ATL kan inte skapas utan ett beroende av CRT. I tidigare versioner av Visual Studio kan du använda - #define ATL_MIN_CRTför att göra ett ATL-projekt minimalt beroende av CRT. I Visual Studio 2008 är alla ATL-projekt minimalt beroende av CRT oavsett om ATL_MIN_CRT har definierats.
- ATL Server-kodbasen har släppts som ett delat källkodsprojekt på CodePlex och är inte installerad som en del av Visual Studio. Datakodnings- och avkodningsklasser från atlenc.h och verktygsfunktioner och klasser från atlutil.h och atlpath.h har sparats och ingår nu i ATL-biblioteket. Flera filer som är associerade med ATL Server ingår inte längre i Visual Studio. 
- Vissa funktioner ingår inte längre i DLL:n. De finns fortfarande i importbiblioteket. Detta påverkar inte kod som använder funktionerna statiskt. Det påverkar endast den kod som använder dessa funktioner dynamiskt. 
MFC
- CTimeKlass: Klassen- CTimeaccepterar nu datum från 1/1/1900 C.E. i stället för 1/1/1970 C.E.
- Tabbordning för kontroller i MFC-dialogrutor: Rätt flikordning för flera kontroller i en MFC-dialogruta störs om en MFC ActiveX-kontroll infogas i tabbordningen. Den här ändringen korrigerar problemet. - Skapa till exempel ett MFC-dialogprogram som har en ActiveX-kontroll och flera redigeringskontroller. Placera ActiveX-kontrollen i mitten av flikordningen för redigeringskontrollerna. Starta programmet, klicka på en redigeringskontroll vars flikordning är efter ActiveX-kontrollen och ta sedan fliken. Före den här ändringen gick fokus till redigeringskontrollen efter ActiveX-kontrollen i stället för nästa redigeringskontroll i tabbordningen. 
- CFileDialogKlass: Anpassade mallar för- CFileDialogklassen kan inte automatiskt portas till Windows Vista. De är fortfarande användbara, men kommer inte att ha ytterligare funktioner eller utseenden som Windows Vista-formatdialogrutor.
- CWndKlass och- CFrameWndklass: Metoden- CWnd::GetMenuBarInfohar tagits bort.- Metoden - CFrameWnd::GetMenuBarInfoär nu en icke-virtuell metod. Mer information finns i Funktionen GetMenuBarInfo i Windows SDK.
- MFC ISAPI-stöd: MFC stöder inte längre att skapa program med Internet Server Application Programming Interface (ISAPI). Om du vill skapa ett ISAPI-program anropar du ISAPI-tilläggen direkt. 
- Inaktuella ANSI-API:er: ANSI-versionerna av flera MFC-metoder är inaktuella. Använd Unicode-versionerna av dessa metoder i dina framtida program. Mer information finns i Build Requirements for Windows Vista Common Controls. 
Störande ändringar i Visual Studio 2005
CRT
- Många funktioner har blivit inaktuella. Se Inaktuella CRT-funktioner. 
- Många funktioner verifierar nu sina parametrar och stoppar körningen om de får ogiltiga parametrar. Den här verifieringen kan bryta kod som skickar ogiltiga parametrar och förlitar sig på att funktionen ignorerar dem eller bara returnerar en felkod. Se Parameterverifiering. 
- Filbeskrivningsvärdet -2 används nu för att ange att - stdoutoch- stderrinte är tillgängliga för utdata, till exempel i ett Windows-program som inte har något konsolfönster. Det tidigare värdet som användes var -1. Mer information finns i _fileno.
- De enkeltrådade CRT-biblioteken (libc.lib och libcd.lib) har tagits bort. Använd CRT-bibliotek med flera trådar. Kompilatorflaggan - /MLstöds inte längre. Icke-låsningsversioner av vissa funktioner har lagts till i fall där prestandaskillnaden mellan den flertrådade koden och den enkeltrådade koden kan vara betydande.
- Överlagringen av pow, double pow(int, int) togs bort för att bättre överensstämma med standarden. 
- Den %n formatspecificeraren stöds inte längre som standard i någon av funktionerna i printf-serien eftersom den är osäker. Om %n påträffas är standardbeteendet att anropa den ogiltiga parameterhanteraren. Om du vill aktivera stöd för %n använder du - _set_printf_count_output(se- _get_printf_count_outputäven ).
- sprintfskriver nu ut det negativa tecknet på en signerad nolla.
- swprintfhar ändrats för att överensstämma med standarden. det kräver nu en storleksparameter. Formatet- swprintfutan en storleksparameter har föråldrats.
- _set_security_error_handlerhar tagits bort. Ta bort alla anrop till den funktionen. standardhanteraren är ett mycket säkrare sätt att hantera säkerhetsfel.
- time_tär nu ett 64-bitarsvärde (om inte _USE_32BIT_TIME_T har definierats).
- _spawn-,- _wspawn-funktionerna lämnar nu- errnoorörda vid framgång, i enlighet med C-standarden.
- RTC använder nu breda tecken som standard. 
- Stödfunktionerna för ordstöd för flyttalskontroller har blivit inaktuella för program som kompilerats med - /CLReller- /CLR:PURE. De berörda funktionerna är- _clear87,- _clearfp,- _control87,- _controlfp,- _fpreset, ,- _status87.- _statusfpDu kan inaktivera utfasningsvarningen genom att definiera _CRT_MANAGED_FP_NO_DEPRECATE, men användningen av dessa funktioner i hanterad kod är oförutsägbar och stöds inte.
- Vissa funktioner returnerar nu const-pekare. Det gamla icke-konstanta beteendet kan återställas genom att definiera _CONST_RETURN. De berörda funktionerna är - memchr, wmemchr 
- strchr, wcschr, _mbschr, _mbschr_l 
- strpbrk, wcspbrk, _mbspbrk, _mbspbrk_l 
- strrchr, wcsrchr, _mbsrchr, _mbsrchr_l 
- strstr, wcsstr, _mbsstr, _mbsstr_l 
 
- När du länkar med Setargv.obj eller Wsetargv.obj går det inte längre att undertrycka expansionen av ett jokertecken på kommandoraden genom att sätta det inom dubbla citattecken. Mer information finns i Utökning av jokerteckenargument. 
Standardbibliotek (2005)
- Undantagsklassen - <exception>(som finns i rubriken) har flyttats till- stdnamnområdet. I tidigare versioner fanns den här klassen i det globala namnområdet. Om du vill lösa eventuella fel som anger att undantagsklassen inte kan hittas, lägger du till följande using-sats i din kod:- using namespace std;
- När du anropar - valarray::resize()försvinner innehållet i- valarrayoch ersätts med standardvärden.- resize()-metoden är avsedd att återinitiera- valarraysnarare än att utöka den dynamiskt som en vektor.
- Felsöka iteratorer: Program som skapats med en felsökningsversion av C-Runtime-biblioteket och som använder iteratorer felaktigt kan börja se anspråk vid körning. Om du vill inaktivera dessa kontroller måste du definiera _HAS_ITERATOR_DEBUGGING (ersatt av - _ITERATOR_DEBUG_LEVELefter Visual Studio 2010) till 0. Mer information finns i Felsökningssupport för Iterator
Visual C++ .NET 2003 Kompatibilitetsändringar
Kompilator
- Avslutande parenteser krävs nu för det definierade förprocessordirektivet (C2004). 
- Explicita specialiseringar hittar inte längre mallparametrar från den primära mallen (kompilatorfel C2146). 
- En skyddad medlem (n) kan endast nås via en medlemsfunktion i en klass (B) som ärver från klassen (A) som den (n) är medlem i (kompilatorfel C2247). 
- Förbättrade hjälpmedelskontroller i kompilatorn identifierar nu otillgängliga basklasser (kompilatorfel C2248). 
- Ett undantag kan inte fångas om destruktorn och/eller kopieringskonstruktorn är otillgänglig (C2316). 
- Standardargument för pekare till funktioner som inte längre tillåts (kompilatorfel C2383). 
- En statisk datamedlem kan inte initieras via härledd klass (kompilatorfel C2477). 
- Initieringen av en - typedeftillåts inte av standarden och genererar nu ett kompilatorfel (kompilatorfel C2513).
- boolär nu en korrekt typ (kompilatorfel C2632).
- En UDC kan nu skapa tvetydighet med överlagrade operatorer (C2666). 
- Fler uttryck anses nu vara giltiga null-pekarkonstanter (kompilatorfel C2668). 
- mallen<> krävs nu på platser där kompilatorn tidigare skulle antyda det (kompilatorfel C2768). 
- Den explicita specialiseringen av en medlemsfunktion utanför klassen är inte giltig om funktionen redan uttryckligen har specialiserats via en mallklassspecialisering (kompilatorfel C2910). 
- Parametrar för icke-typmallar med flyttal tillåts inte längre (kompilatorfel C2993). 
- Klassmallar tillåts inte som malltypsargument (C3206). 
- Vänfunktionsnamn introduceras inte längre i innehållande namnområde (kompilatorfel C3767). 
- Kompilatorn accepterar inte längre extra kommatecken i ett makro (C4002). 
- Ett objekt av POD-typ som skapats med en initierare av typen () kommer att standardinitieras (C4345). 
- typename krävs nu om ett beroende namn ska behandlas som en typ (kompilatorvarning (nivå 1) C4346). 
- Funktioner som felaktigt betraktades som mallspecialiseringar anses inte längre vara det (C4347). 
- Statiska datamedlemmar kan inte initieras via härledd klass (C4356). 
- En specialisering av klassmallar måste definieras innan den används i en returtyp (kompilatorvarning (nivå 3) C4686). 
- Kompilatorn rapporterar nu oåtkomlig kod (C4702).