Microsoft C/C++ değişiklik geçmişi 2003 - 2015
Bu makalede, Visual Studio 2015'ten Visual Studio 2003'e geri dönerken yapılan tüm hataya neden olan değişiklikler açıklanır ve bu makalede "yeni davranış" veya "şimdi" terimleri Visual Studio 2015 ve sonraki sürümlere başvurur. "Eski davranış" ve "önce" terimleri Visual Studio 2013 ve önceki sürümlere başvurur.
Visual Studio'nun en son sürümü hakkında bilgi için bkz. Visual Studio'da C++ için yenilikler ve Visual Studio'da C++ uyumluluğu geliştirmeleri.
Not
Visual Studio 2015 ile Visual Studio 2017 arasında ikili hataya neden olan hiçbir değişiklik yoktur.
Visual Studio'nun yeni bir sürümüne yükselttiğinizde, daha önce derlenen ve doğru şekilde çalıştırılan kodda derleme ve/veya çalışma zamanı hatalarıyla karşılaşabilirsiniz. Yeni sürümde bu tür sorunlara neden olan değişiklikler, hataya neden olan değişiklikler olarak bilinir ve genellikle C++ dil standardı, işlev imzaları veya bellekteki nesnelerin düzenindeki değişiklikler için gereklidir.
Algılaması ve tanılaması zor olan çalışma zamanı hatalarını önlemek için, derleyicinin farklı bir sürümü kullanılarak derlenen ikili dosyalara hiçbir zaman statik olarak bağlanmamanızı öneririz. Ayrıca, bir EXE veya DLL projesini yükseltirken, bağlantı verdiği kitaplıkları da yükselttiğinizden emin olun. Derleyicinin farklı sürümleri kullanılarak derlenen DLL'ler de dahil olmak üzere ikili dosyalar arasında CRT (C Çalışma Zamanı) veya C++ Standart Kitaplığı (C++ Standart Kitaplığı) türlerini geçirmeyin. Daha fazla bilgi için bkz . DLL Sınırları Boyunca CRT Nesnelerini Geçirirken Olası Hatalar.
COM arabirimi veya POD nesnesi olmayan bir nesne için belirli bir düzene bağımlı kod yazmamalısınız. Bu tür bir kod yazarsanız, yükseltme sonrasında çalışmasını sağlamalısınız. Daha fazla bilgi için bkz . ABI Sınırlarında Taşınabilirlik.
Ayrıca, derleyici uyumluluğunda devam eden geliştirmeler bazen derleyicinin mevcut kaynak kodunuzu anlama biçimini değiştirebilir. Örneğin, derlemeniz sırasında yeni veya farklı hatalar, hatta daha önce derlenmiş ve düzgün çalışıyor gibi görünen kodda davranış farklılıkları bulabilirsiniz. Bu geliştirmeler, bu belgede açıklanan değişiklikler gibi önemli değişiklikler olmasa da, bu sorunları çözmek için kaynak kodunuzda değişiklik yapmanız gerekebilir:
C Çalışma Zamanı (CRT) Kitaplığında Hataya Neden Olan Değişiklikler
Standart C++ ve C++ Standart Kitaplık Hataya Neden Olan Değişiklikler
Visual Studio 2015 Uyumluluk Değişiklikleri
C Çalışma Zamanı Kitaplığı (CRT)
Genel Değişiklikler
Yeniden düzenlenmiş ikili dosyalar
CRT Kitaplığı iki farklı ikili dosya olarak yeniden düzenlenmiştir: standart işlevlerin çoğunu içeren Evrensel CRT (ucrtbase) ve bir VC Çalışma Zamanı Kitaplığı (vcruntime). vcruntime kitaplığı, özel durum işleme ve iç bilgiler gibi derleyiciyle ilgili işlevleri içerir. Varsayılan proje ayarlarını kullanıyorsanız bağlayıcı yeni varsayılan kitaplıkları otomatik olarak kullandığından bu değişiklik sizi etkilemez. Projenin Bağlayıcı özelliğini Tüm Varsayılan Kitaplıkları Yoksay seçeneğini Evet olarak ayarladıysanız veya komut satırında bağlayıcı seçeneğini kullanıyorsanız
/NODEFAULTLIB
, kitaplık listenizi (Ek Bağımlılıklar özelliğinde) yeni, yeniden düzenlenmiş kitaplıkları içerecek şekilde güncelleştirmeniz gerekir. Eski CRT kitaplığını (libcmt.lib
,libcmtd.lib
,msvcrt.lib
,msvcrtd.lib
) eşdeğer yeniden düzenlenmiş kitaplıklarla değiştirin. Yeniden düzenlenmiş iki kitaplığın her biri için statik (.lib) ve dinamik (.dll) sürümleri ve yayın (son eki olmayan) ve hata ayıklama sürümleri ("d" son eki ile) vardır. Dinamik sürümler, bağlandığınız bir içeri aktarma kitaplığına sahiptir. Yeniden düzenlenmiş iki kitaplık, özellikle ucrtbase.dll veya ucrtbase.lib, ucrtbased.dll veya ucrtbased.lib ve VC çalışma zamanı kitaplığı, ,libvcruntime.lib
vcruntimesürümü.dll, ve vcruntimedsürümü.dlllibvcruntimed.lib
Evrensel CRT'dir. Hem Visual Studio 2015 hem de Visual Studio 2017'deki sürüm 140'tır. Bkz. CRT Kitaplığı Özellikleri.
<locale.h>
localeconv
localeconv
locale.h dosyasında bildirilen işlev artık iş parçacığı başına yerel ayar etkinleştirildiğinde düzgün çalışıyor. Kitaplığın önceki sürümlerinde, bu işlev iş parçacığınınlconv
yerel ayarını değil genel yerel ayarın verilerini döndürür.İş parçacığı başına yerel ayarlar kullanıyorsanız, kullanımınızı
localeconv
denetlemeniz gerekir. Kodunuz döndürülen verilerin genel yerel ayar için olduğunu varsayarsalconv
, düzeltmeniz gerekir.
<math.h>
Matematik kitaplığı işlevlerinin C++ aşırı yüklemeleri
Önceki sürümlerde,
<math.h>
matematik kitaplığı işlevleri için C++ aşırı yüklemelerinin bazılarını tanımlamış ancak tümünü tanımlanmamıştır. Geri kalan aşırı yüklemeler üst bilgisindeydi<cmath>
. Yalnızca dahil<math.h>
edilen kod, işlev aşırı yükleme çözümlemesiyle ilgili sorunlarla karşılaşabilir. Artık C++ aşırı yüklemeleri öğesinden<math.h>
kaldırılmıştır ve yalnızca içinde<cmath>
bulunur.Hataları çözmek için, öğesinden
<math.h>
kaldırılan işlevlerin bildirimlerini almayı ekleyin<cmath>
. Bu işlevler taşındı:double abs(double)
vefloat abs(float)
double pow(double, int)
,float pow(float, float)
,float pow(float, int)
,long double pow(long double, long double)
, ,long double pow(long double, int)
float
kayanlong double
nokta işlevleriacos
,acosh
, ,asin
,asinh
,atan
, ,atanh
,atan2
ceil
exp
exp2
erfc
copysign
fdim
cos
erf
fabs
cosh
cbrt
expm1
, vefloor
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
tgamma
trunc
Yalnızca üst bilgiyi içeren
<math.h>
kayan nokta türüyle kullananabs
kodunuz varsa, kayan nokta sürümleri artık kullanılamaz. Çağrı artık kayan nokta bağımsız değişkeniyle bile hataya neden olan olarak çözümlenmektedirabs(int)
:warning C4244: 'argument' : conversion from 'float' to 'int', possible loss of data
Bu uyarının düzeltmesi, çağrısının
abs
değerininabs
kayan nokta sürümüyle (örneğinfabs
, bir çift bağımsız değişken veya float bağımsız değişkeni için) değiştirmek ya dafabsf
üst bilgiyi dahil<cmath>
etmek ve kullanmayaabs
devam etmektir.Kayan nokta uyumluluğu
IEEE-754 ve C11 Ek F belirtimlerine NaN'ler ve sonsuzluklar gibi özel durum girişleri bakımından uyumluluğu geliştirmek için matematik kitaplığında birçok değişiklik yapılmıştır. Örneğin, kitaplığın önceki sürümlerinde genellikle hata olarak ele alınan sessiz NaN girişleri artık hata olarak değerlendirilmez. Bkz. C11 Standardının IEEE 754 Standard ve Ek F.
Bu değişiklikler derleme zamanı hatalarına neden olmaz, ancak programların standarda göre farklı ve daha doğru davranmasına neden olabilir.
FLT_ROUNDS
Visual Studio 2013'te FLT_ROUNDS makrosu sabit bir ifadeye genişletildi. Bu, yuvarlama modu çalışma zamanında yapılandırılabilir olduğu için hatalıydı, örneğin fesetround çağrısıyla. FLT_ROUNDS makro artık dinamiktir ve geçerli yuvarlama modunu doğru şekilde yansıtır.
<new>
ve <new.h>
new
vedelete
Kitaplığın önceki sürümlerinde, uygulama tanımlı işleç yeni ve silme işlevleri çalışma zamanı kitaplığı DLL'sinden (örneğin, msvcr120.dll) dışarı aktarılmıştır. Bu işleç işlevleri artık çalışma zamanı kitaplığı DLL'leri kullanılırken bile ikili dosyalarınıza her zaman statik olarak bağlanır.
Bu, yerel veya karma kod (
/clr
) için hataya neden olan bir değişiklik değildir, ancak /clr:pure olarak derlenen kod için bu değişiklik kodunuzun derlenememasına neden olabilir. Kodu olarak/clr:pure
derliyorsanız, bu değişiklik nedeniyle derleme hatalarını geçici olarak eklemeniz#include <new>
veya#include <new.h>
geçici olarak düzeltmeniz gerekebilir. Bu/clr:pure
seçenek Visual Studio 2015'te kullanım dışıdır ve Visual Studio 2017'de desteklenmez. "Saf" olması gereken kod C# olarak taşınabilir.
<process.h>
_beginthread
ve_beginthreadex
_beginthread
ve_beginthreadex
işlevleri artık iş parçacığının süresi boyunca iş parçacığı yordamının tanımlandığı modüle bir başvuru barındıracaktır. Bu, bir iş parçacığı tamamlanmak üzere çalıştırılana kadar modüllerin yüklenmemesini sağlamaya yardımcı olur.
<stdarg.h>
va_start
ve başvuru türleriC++ kodu derlenirken,
va_start
derleme zamanında geçirilen bağımsız değişkenin başvuru türünde olmadığını doğrular. Başvuru türü bağımsız değişkenleri C++ Standardı tarafından yasaklanmıştır.
<stdio.h>
ve <conio.h>
Printf ve scanf işlev ailesi artık satır içinde tanımlanmıştır.
ve işlevlerinin
printf
tümünün tanımları, ,<conio.h>
ve diğer CRT üst bilgilerine<stdio.h>
satır içi olarakscanf
taşındı. Bu hataya neden olan değişiklik, uygun CRT üst bilgilerini eklemeden bu işlevleri yerel olarak bildiren tüm programlar için bağlayıcı hatasına (LNK2019, çözümlenmemiş dış simge) yol açar. Mümkünse, kodu CRT üst bilgilerini (yani, ekleme#include <stdio.h>
) ve satır içi işlevleri içerecek şekilde güncelleştirmeniz gerekir, ancak kodunuzu bu üst bilgi dosyalarını içerecek şekilde değiştirmek istemiyorsanız, bağlayıcı girişinize alternatif bir çözüm eklemektirlegacy_stdio_definitions.lib
.Bu kitaplığı IDE'deki bağlayıcı girişinize eklemek için proje düğümünün bağlam menüsünü açın, Özellikler'i seçin, ardından Proje Özellikleri iletişim kutusunda Bağlayıcı'yı seçin ve bağlayıcı girişini düzenleyerek noktalı virgülle ayrılmış listeye ekleyin
legacy_stdio_definitions.lib
.Projeniz 2015'ten önceki bir Visual Studio sürümüyle derlenmiş statik kitaplıklarla bağlantı kurarsa, bağlayıcı çözülmemiş bir dış simge bildirebilir. Bu hatalar, imp* biçimindeki belirli
<stdio.h>
işlevler için_iob
,_iob_func
, veya ilgili içeri aktarmalar için iç tanımlara başvurabilir. Microsoft, bir projeyi yükseltirken tüm statik kitaplıkları C++ derleyicisinin ve kitaplıklarının en son sürümüyle yeniden derlemenizi önerir. Kitaplık, kaynağın kullanılamadığı bir üçüncü taraf kitaplığıysa, üçüncü taraftan güncelleştirilmiş bir ikili dosya istemeli veya bu kitaplık kullanımınızı derleyicinin ve kitaplıkların eski sürümüyle derlediğiniz ayrı bir DLL'de kapsüllemeniz gerekir.Uyarı
Windows SDK 8.1 veya önceki bir sürüme bağlanıyorsanız, bu çözülmemiş dış simge hatalarıyla karşılaşabilirsiniz. Bu durumda, daha önce açıklandığı gibi bağlayıcı girişine legacy_stdio_definitions.lib ekleyerek hatayı çözmeniz gerekir.
Çözülmemiş simge hatalarını gidermek için kullanarak ikili dosyada tanımlanan simgeleri incelemeyi deneyebilirsiniz
dumpbin.exe
. Kitaplıkta tanımlanan simgeleri görüntülemek için aşağıdaki komut satırını deneyin.dumpbin.exe /LINKERMEMBER somelibrary.lib
alır ve _getws
gets ve _getws işlevleri kaldırıldı. Gets işlevi, güvenli bir şekilde kullanılamadığından C11'deki C Standart Kitaplığı'ndan kaldırıldı. _getws işlevi, geniş dizeler için almakla eşdeğer olan bir Microsoft uzantısıydı. Bu işlevlerin alternatifleri olarak fget, fgetws, gets_s ve _getws_s kullanmayı göz önünde bulundurun.
_cgets ve _cgetws
_cgets ve _cgetws işlevleri kaldırıldı. Bu işlevlerin alternatifleri olarak _cgets_s ve _cgetws_s kullanmayı göz önünde bulundurun.
Sonsuzluk ve NaN Biçimlendirmesi
Önceki sürümlerde, sonsuzlar ve NaN'ler MSVC'ye özgü sentinel dizeleri kullanılarak biçimlendirilirdi.
Sonsuzluk: 1.#INF
Sessiz NaN: 1.#QNAN
Sinyal NaN: 1.#SNAN
Süresiz NaN: 1.#IND
Bu biçimlerden herhangi biri bir işaretle ön ekli olabilir ve alan genişliğine ve duyarlığına bağlı olarak biraz farklı biçimlendirilmiş olabilir (bazen sıra dışı efektlerle, örneğin
printf("%.2f\n", INFINITY)
1,#J yazdırılabilir çünkü #INF 2 basamaklı duyarlıklara "yuvarlanır"). C99, sonsuzlukların ve NaN'lerin nasıl biçimlendirileceğine ilişkin yeni gereksinimler getirilmiştir. MSVC uygulaması artık bu gereksinimlere uygundur. Yeni dizeler aşağıdaki gibidir:Sonsuzluk: inf
Sessiz NaN: nan
Sinyal NaN'i: nan(snan)
Süresiz NaN: nan(ind)
Bunlardan herhangi birinin ön eki bir işaret olabilir. Büyük harf biçim tanımlayıcısı (%f yerine (%F) kullanılırsa, dizeler gerektiği gibi büyük harfle (
INF
yerineinf
) yazdırılır.Scanf işlevleri bu yeni dizeleri ayrıştıracak şekilde değiştirildiğinden, bu dizeler artık ve
scanf
üzerindenprintf
gidiş dönüşlü olarak değiştirilebilir.Kayan nokta biçimlendirme ve ayrıştırma
Doğruluğu geliştirmek için yeni kayan nokta biçimlendirme ve ayrıştırma algoritmaları kullanıma sunulmuştur. Bu değişiklik, printf ve scanf işlev ailelerini ve strtod gibi işlevleri etkiler.
Eski biçimlendirme algoritmaları yalnızca sınırlı sayıda basamak oluşturur ve kalan ondalık basamakları sıfırla doldurur. Genellikle özgün kayan nokta değerine geri dönüş yapacak dizeler oluşturabilirler, ancak tam değeri (veya en yakın ondalık gösterimini) istiyorsanız harika değildi. Yeni biçimlendirme algoritmaları, değeri temsil etmek (veya belirtilen duyarlığı doldurmak için) gereken sayıda basamak oluşturur. İyileştirme örneği olarak; iki büyük bir güç yazdırırken sonuçları göz önünde bulundurun:
printf("%.0f\n", pow(2.0, 80))
Eski çıkış:
1208925819614629200000000
Yeni çıkış:
1208925819614629174706176
Eski ayrıştırma algoritmaları giriş dizesinden en fazla 17 anlamlı basamak sayar ve kalan basamakları atar. Bu yaklaşım, dize tarafından temsil edilen değerin yakın tahminini oluşturmak için yeterlidir ve sonuç genellikle doğru yuvarlanmış sonuca çok yakındır. Yeni uygulama tüm mevcut basamakları dikkate alır ve tüm girişler için doğru yuvarlanmış sonucu üretir (en fazla 768 basamak uzunluğunda). Buna ek olarak, bu işlevler artık yuvarlama moduna (fesetround ile denetlenebilir) saygı gösterir. Bu işlevler farklı sonuçlara neden olabileceğinden bu büyük olasılıkla hataya neden olan bir davranış değişikliğidir. Yeni sonuçlar her zaman eski sonuçlardan daha doğrudur.
Onaltılık ve sonsuz/NaN kayan nokta ayrıştırma
Kayan nokta ayrıştırma algoritmaları artık yukarıda açıklandığı gibi onaltılık kayan nokta dizelerini (örneğin, %a ve %A printf biçim tanımlayıcıları tarafından oluşturulanlar) ve işlevler tarafından
printf
oluşturulan tüm sonsuz ve NaN dizelerini ayrıştıracak.%A ve %a sıfır doldurma
%a ve %A biçim tanımlayıcıları kayan nokta sayısını onaltılık mantis ve ikili üs olarak biçimlendirir. Önceki sürümlerde
printf
işlevler yanlış sıfır tuş takımı dizeleri kullanmıştı. Örneğin,printf("%07.0a\n", 1.0)
0x01p+0 yazdırılır ve 0x01p+0 yazdırılır. Bu kusur düzeltildi.%A ve %a duyarlık
%A ve %a biçim tanımlayıcılarının varsayılan duyarlığı kitaplığın önceki sürümlerinde 6'ydı. Varsayılan duyarlık artık C Standardı ile uyumlu olması için 13'tür.
Bu, %A veya %a ile bir biçim dizesi kullanan herhangi bir işlevin çıktısında yapılan çalışma zamanı davranışı değişikliğidir. Eski davranışta, %A tanımlayıcısını kullanan çıkış "1.1A2B3Cp+111" olabilir. Şimdi aynı değerin çıkışı "1.1A2B3C4D5E6F7p+111" olur. Eski davranışı almak için duyarlık belirtebilirsiniz, örneğin, %.6A. Bkz. Duyarlık Belirtimi.
%F tanımlayıcısı
%F biçim/dönüştürme tanımlayıcısı artık destekleniyor. Sonsuzlukların ve NaN'lerin büyük harfler kullanılarak biçimlendirilmelerinin dışında, işlev olarak %f biçim belirticisine eşdeğerdir.
Önceki sürümlerde, F ve N'yi uzunluk değiştirici olarak ayrıştırmak için kullanılan uygulama. Segmentlere ayrılmış adres alanlarının yaşına kadar uzanan bu davranış: Bu uzunluk değiştiricileri sırasıyla %Fp veya %Ns'de olduğu gibi uzak ve yakın işaretçileri göstermek için kullanıldı. Bu davranış kaldırıldı. %F ile karşılaşılırsa, artık %F biçim tanımlayıcısı olarak kabul edilir; %N ile karşılaşılırsa, artık geçersiz bir parametre olarak kabul edilir.
Üstel biçimlendirme
%e ve %E biçim tanımlayıcıları kayan nokta sayısını ondalık mantis ve üs olarak biçimlendirdi. %g ve %G biçim tanımlayıcıları da bazı durumlarda bu formdaki sayıları biçimlendirir. Önceki sürümlerde CRT her zaman üç basamaklı üslere sahip dizeler oluşturur. Örneğin,
printf("%e\n", 1.0)
1.000000e+000 yazdırılır ve bu yanlıştır. C, üs yalnızca bir veya iki basamak kullanılarak gösterilebilirse yalnızca iki basamak yazdırılmasını gerektirir.Visual Studio 2005'te genel uyumluluk anahtarı eklendi: _set_output_format. Bir program, uyumlu üstel yazdırmayı etkinleştirmek için bu işlevi _TWO_DIGIT_EXPONENT bağımsız değişkeniyle çağırabilir. Varsayılan davranış standartlara uygun üstel yazdırma moduna değiştirildi.
Dize doğrulamayı biçimlendirme
Önceki sürümlerde
printf
vescanf
işlevleri, bazen olağan dışı efektler içeren birçok geçersiz biçim dizesini sessizce kabul ederdi. Örneğin, %hlhlhld %d olarak değerlendirilir. Tüm geçersiz biçim dizeleri artık geçersiz parametre olarak değerlendirilir.fopen modu dize doğrulaması
Önceki sürümlerde,
fopen
işlev ailesi gibir+b+
bazı geçersiz mod dizelerini sessizce kabul etti. Geçersiz mod dizeleri artık algılanıyor ve geçersiz parametre olarak işleniyor._O_U8TEXT modu
_setmode işlevi artık in_O_U8TEXT modunda açılan akışlar için modu doğru raporlar. Kitaplığın önceki sürümlerinde, bu tür akışların _O_WTEXT açıldığını bildiriyor.
Kodunuz kodlamanın UTF-8 olduğu akışlar için _O_WTEXT modunu yorumlarsa bu hataya neden olan bir değişikliktir. Uygulamanız UTF_8 desteklemiyorsa, giderek artan bu kodlama için destek eklemeyi göz önünde bulundurun.
snprintf ve vsnprintf
Snprintf ve vsnprintf işlevleri artık uygulandı. Eski kod genellikle CRT kitaplığı tarafından uygulanmadığından, ancak daha yeni sürümlerde artık gerekli olmadığından bu işlevlerin makro sürümlerini tanımlar. dahil etmeden önce snprintf veya vsnprintf makro olarak tanımlanıyorsa, derleme artık makronun tanımlandığı yeri gösteren bir hatayla başarısız
<stdio.h>
olur.Normalde, bu sorunun düzeltmesi kullanıcı kodundaki
snprintf
veyavsnprintf
bildirimlerini silmektir.tmpnam Kullanılabilir Dosya Adları Oluşturur
Önceki sürümlerde ve
tmpnam_s
işlevleri,tmpnam
sürücünün kökünde (\sd3c. gibi) dosya adları oluşturmşturdu. Bu işlevler artık geçici bir dizinde kullanılabilir dosya adı yolları oluşturur.FILE Kapsüllemesi
Önceki sürümlerde, tam DOSYA türü içinde
<stdio.h>
genel olarak tanımlanmıştı, bu nedenle kullanıcı kodunun bir FILE dosyasına ulaşması ve iç bileşenlerini değiştirmesi mümkündü. Kitaplık, uygulama ayrıntılarını gizleyecek şekilde değiştirildi. Bu değişikliğin bir parçası olarak, içinde<stdio.h>
tanımlanan FILE artık opak bir türdür ve üyelerine CRT'nin dışından erişilemez._outp ve _inp
_outp, _outpw, _outpd, _inp, _inpw ve _inpd işlevleri kaldırıldı.
<stdlib.h>
, <malloc.h>
ve <sys/stat.h>
strtof ve wcstof
strtof
Değer kayan değer olarak temsil edilemediğinde vewcstof
işlevleri ERANGE olarak ayarlanamadıerrno
. Bu hata bu iki işleve özeldi;strtod
,wcstod
,strtold
vewcstold
işlevleri etkilenmedi. Bu sorun düzeltildi ve çalışma zamanı hataya neden olan bir değişikliktir.Hizalanmış ayırma işlevleri
Önceki sürümlerde, hizalanmış ayırma işlevleri (
_aligned_malloc
,_aligned_offset_malloc
vb.), 0 hizalamalı bir blok için istekleri sessizce kabul ederdi. İstenen hizalama, sıfırdan farklı olan iki güçte olmalıdır. İstenen 0 hizalaması artık geçersiz bir parametre olarak değerlendirilir. Bu sorun düzeltildi ve çalışma zamanı hataya neden olan bir değişikliktir.Yığın işlevleri
_heapadd
,_heapset
ve_heapused
işlevleri kaldırıldı. CRT, Windows yığınını kullanacak şekilde güncelleştirildiğinden beri bu işlevler işlevsizdir.smallheap
smallheap
Bağlantı seçeneği kaldırıldı. Bkz. Bağlantı Seçenekleri._Stat
İşlev
_stat
ailesi, Visual Studio 2013 ve önceki sürümleri yerineFindFirstFile
Visual Studio 2015'te kullanılırCreateFile
. Bu,_stat
eğik çizgi ile biten bir yolda, işlevin olarak ayarlandığındaENOENT
hataerrno
vermesinin aksine, yolun bir dizine başvuruda bulunursa başarılı olacağı anlamına gelir.
<string.h>
wcstok
İşlevin
wcstok
imzası, C Standard'ın gerektirdiğiyle eşleşecek şekilde değiştirildi. Kitaplığın önceki sürümlerinde bu işlevin imzası şöyleydi:wchar_t* wcstok(wchar_t*, wchar_t const*)
için olduğu gibi çağrılar arasında durumu izlemek için
strtok
iç, iş parçacığı başına bağlamı kullandı. İşlevin artık imzasıwchar_t* wcstok(wchar_t*, wchar_t const*, wchar_t**)
vardır ve çağıranın bağlamı işleve üçüncü bir bağımsız değişken olarak geçirmesini gerektirir.Taşımayı kolaylaştırmak için eski imzayla yeni
_wcstok
bir işlev eklendi. C++ kodu derlenirken, eski imzaya sahip satır içi aşırı yüklemesiwcstok
de vardır. Bu aşırı yükleme kullanım dışı olarak bildirilir. C kodunda, yerinewcstok
kullanılmasına neden_wcstok
define_CRT_NON_CONFORMING_WCSTOK.
<time.h>
clock
Önceki sürümlerde işlev,
clock
Windows APIGetSystemTimeAsFileTime
kullanılarak uygulanıyordu. Bu uygulamayla, saat işlevi sistem zamanına duyarlıydı ve bu nedenle monoton olması şart değildi. Saat işlevi, ve bakımındanQueryPerformanceCounter
yeniden bir araya geldi ve artık monoton.fstat ve _utime
Önceki sürümlerde,
_stat
,fstat
ve_utime
işlevleri yaz saati işlemlerini yanlış işler. Visual Studio 2013'ün öncesinde, bu işlevlerin tümü standart saat saatlerini yanlış bir şekilde gün ışığındaymış gibi ayarladı.Visual Studio 2013'te sorun işlev ailesinde
_stat
düzeltildi, ancak işlev ailelerindeki ve_utime
ailelerindekifstat
benzer sorunlar düzeltilmedi. Bu kısmi düzeltme, işlevler arasındaki tutarsızlık nedeniyle sorunlara yol açtı. vefstat
_utime
işlev aileleri artık düzeltilmiştir, bu nedenle bu işlevlerin tümü artık yaz saati işlemlerini doğru ve tutarlı bir şekilde gerçekleştirmektedir.asctime
Önceki sürümlerde işlev,
asctime
tek basamaklı günleri baştaki sıfırla doldurmaya yönelikti, örneğin:Fri Jun 06 08:00:00 2014
. Belirtim, bu tür günlerin içinde olduğu gibiFri Jun 6 08:00:00 2014
önünde boşluk olmasını gerektirir. Bu sorun düzeltilmiştir.strftime ve wcsftime
strftime
vewcsftime
işlevleri artık %C, %D, %e, %F, %g, %G, %h, %n, %r, %R, %t, %T, %u ve %V biçim tanımlayıcılarını destekliyor. Ayrıca, E ve O değiştiricileri ayrıştırılır ancak yoksayılır.%c biçim belirticisi, geçerli yerel ayar için "uygun tarih ve saat gösterimi" oluşturarak belirtilir. C yerel ayarında, bu gösterimin ile aynı
%a %b %e %T %Y
olması ve tarafındanasctime
üretilen biçimin aynı olması gerekir. Önceki sürümlerde, %c biçim belirticisi birMM/DD/YY HH:MM:SS
gösterim kullanılarak yanlış biçimlendirilmiş zamanlar. Bu sorun düzeltilmiştir.timespec ve TIME_UTC
Üst
<time.h>
bilgi artık C11 Standard'dan tür vetimespec_get
işlevi tanımlartimespec
. Buna ek olarak, işlevletimespec_get
kullanılmak üzere TIME_UTC makro artık tanımlanmıştır. Bu güncelleştirme, bu tanımlayıcılardan herhangi biri için çakışan bir tanımı olan kod için hataya neden olan bir değişikliktir.CLOCKS_PER_SEC
CLOCKS_PER_SEC makro artık C dilinin gerektirdiği şekilde türünde
clock_t
bir tamsayıya genişletiliyor.
C++ Standart Kitaplığı
Yeni iyileştirmeleri ve hata ayıklama denetimlerini etkinleştirmek için, C++ Standart Kitaplığı'nın Visual Studio uygulaması bir sürümden sonraki bir sürüme ikili uyumluluğu kasıtlı olarak bozar. Bu nedenle, C++ Standart Kitaplığı kullanıldığında, farklı sürümlerin kullanımıyla derlenmiş nesne dosyaları ve statik kitaplıklar tek bir ikili dosya (EXE veya DLL) halinde karma yapılabilir ve C++ Standart Kitaplığı nesneleri, farklı sürümler kullanılarak derlenmiş ikili dosyalar arasında geçirilemez. Bu tür karmalar, _MSC_VER uyuşmazlıklarıyla ilgili bağlayıcı hataları verir. (_MSC_VER, derleyicinin ana sürümünü (örneğin, Visual Studio 2013 için 1800) içeren makrodur.) Bu denetim DLL karıştırmasını algılayamaz ve Visual Studio 2008 veya önceki sürümleri içeren karıştırmayı algılayamaz.
C++ Standart Kitaplığı dosyaları içerir
C++ Standart Kitaplığı üst bilgilerinde ekleme yapısında bazı değişiklikler yapılmıştır. C++ Standart Kitaplık üst bilgilerinin belirtilmeyen yollarla birbirini içermesine izin verilir. Genel olarak kodunuzu, C++ standardına göre gereken tüm üst bilgileri dikkatle içerecek şekilde yazmanız ve hangi C++ Standart Kitaplık üst bilgilerinin hangi C++ Standart Kitaplık üst bilgilerini içerdiğine güvenmemesi gerekir. Bu, kodu sürümler ve platformlar arasında taşınabilir hale getirir. Visual Studio 2015'teki en az iki üst bilgi değişikliği kullanıcı kodunu etkiler. İlk olarak,
<string>
artık öğesini içermez<iterator>
. İkinci olarak,<tuple>
kodun tamamını<array>
eklemeden bildirirstd::array
ve kodu şu kod yapılarının birleşimiyle bölebilir: kodunuzun "array" adlı bir değişkeni vardır ve "using namespace std;" using-yönergesine sahip olursunuz ve içeren bir C++ Standart Kitaplık üst bilgisi (örneğin<functional>
)<tuple>
eklersiniz ve bu da artık bildirirstd::array
.steady_clock
<chrono>
uygulamasısteady_clock
, kararlılık ve monotonluk için C++ Standart gereksinimlerini karşılayacak şekilde değişmiştir.steady_clock
artık öğesini temel alırQueryPerformanceCounter
vehigh_resolution_clock
artık içinsteady_clock
bir tür tanımıdır. Sonuç olarak, Visual Studio'dasteady_clock::time_point
artık içinchrono::time_point<steady_clock>
bir tür tanımıdır; ancak diğer uygulamalar için bu durum geçerli olmayabilir.ayırıcılar ve const
Artık her iki tarafta da sabit bağımsız değişkenleri kabul etmek için ayırıcı eşitlik/eşitsizlik karşılaştırmaları gerekiyor. Ayırıcılarınız bu işleçleri böyle tanımlarsa,
bool operator==(const MyAlloc& other)
ardından bunları güncelleştirip const üyeleri olarak bildirmeniz gerekir:
bool operator==(const MyAlloc& other) const
const öğeleri
C++ standardı her zaman sabit öğelerin (veya
set<const T>
gibivector<const T>
) kapsayıcılarını yasaklamıştır. Visual Studio 2013 ve önceki sürümler bu tür kapsayıcıları kabul etti. Geçerli sürümde, bu tür kapsayıcılar derlenemiyor.std::allocator::d eallocate
Visual Studio 2013 ve önceki sürümlerinde,
std::allocator::deallocate(p, n)
n için geçirilen bağımsız değişkeni yoksaymıştı. C++ standardı her zaman n değerinin p döndüren çağrısınınallocate
ilk bağımsız değişkeni olarak geçirilen değere eşit olması gerekir. Ancak geçerli sürümde n değeri incelenir. Standardın gerektirdiğinden farklı n bağımsız değişkenlerini geçiren kod çalışma zamanında kilitlenebilir.hash_map ve hash_set
Standart olmayan üst bilgi dosyaları
<hash_map>
ve<hash_set>
Visual Studio 2015'te kullanım dışıdır ve gelecek bir sürümde kaldırılacaktır. bunun yerine ve<unordered_set>
kullanın<unordered_map>
.comparators and operator()
İlişkili kapsayıcılar (
<map>
aile) artık karşılaştırıcılarının çağrılabilen işlev çağrı işleçlerine sahip olmasını gerektirir. Bir karşılaştırıcı sınıf bildirimindeki aşağıdaki kod artık derlenemiyor:bool operator()(const X& a, const X& b)
Bu hatayı düzeltmek için işlev bildirimini şu şekilde değiştirin:
bool operator()(const X& a, const X& b) const
tür özellikleri
C++ taslak standardının önceki bir sürümündeki tür özellikleri için eski adlar kaldırılmıştır. Bunlar C++11'de değiştirildi ve Visual Studio 2015'teki C++11 değerlerine güncelleştirildi. Aşağıdaki tabloda eski ve yeni adlar gösterilmektedir.
Eski ad Yeni ad add_reference add_lvalue_reference has_default_constructor is_default_constructible has_copy_constructor is_copy_constructible has_move_constructor is_move_constructible has_nothrow_constructor is_nothrow_default_constructible has_nothrow_default_constructor is_nothrow_default_constructible has_nothrow_copy is_nothrow_copy_constructible has_nothrow_copy_constructor is_nothrow_copy_constructible has_nothrow_move_constructor is_nothrow_move_constructible has_nothrow_assign is_nothrow_copy_assignable has_nothrow_copy_assign is_nothrow_copy_assignable has_nothrow_move_assign is_nothrow_move_assignable has_trivial_constructor is_trivially_default_constructible has_trivial_default_constructor is_trivially_default_constructible has_trivial_copy is_trivially_copy_constructible has_trivial_move_constructor is_trivially_move_constructible has_trivial_assign is_trivially_copy_assignable has_trivial_move_assign is_trivially_move_assignable has_trivial_destructor is_trivially_destructible launch::any ve launch::sync ilkeleri
Standart
launch::any
olmayan velaunch::sync
ilkeler kaldırıldı. Bunun yerine, içinlaunch::any
kullanınlaunch:async | launch:deferred
.launch::sync
içinlaunch::deferred
'i kullanın. Bkz . Numaralandırmayı başlatma.
MFC ve ATL
Microsoft Foundation Sınıfları (MFC)
artık büyük boyutu nedeniyle Visual Studio'nun "Tipik" yüklemesine dahil değildir. MFC'yi yüklemek için Visual Studio 2015 kurulumunda Özel yükleme seçeneğini belirleyin. Visual Studio 2015 zaten yüklüyse, Visual Studio kurulumunu yeniden çalıştırarak MFC'yi yükleyebilirsiniz. Özel yükleme seçeneğini ve ardından Microsoft Foundation Sınıfları'nı seçin. Visual Studio kurulumunu Programlar ve Özellikler'i Denetim Masası denetiminden veya yükleme medyasından çalıştırabilirsiniz.
Visual C++ Yeniden Dağıtılabilir Paketi'nde bu kitaplık halen yer almaktadır.
Eşzamanlılık Çalışma Zamanı
Windows.h'den eşzamanlılık::Context::Yield ile çakışan verim makroları
Daha önce Eşzamanlılık Çalışma Zamanı, Windows.h h'de tanımlanan Verim makro ile işlev arasındaki çakışmaları önlemek için Verim makrosunun tanımlarını
concurrency::Context::Yield
silmek için kullanılırdı#undef
. Bu#undef
kaldırıldı ve çakışmayan yeni bir eşdeğer API çağrısı eşzamanlılığı::Context::YieldExecution eklendi. Yield ile çakışmaları geçici olarak çözmek için, aşağıdaki örnekte olduğu gibi kodunuzu işlevi çağıracakYieldExecution
şekilde güncelleştirebilir veya çağrı sitelerinde işlev adını parantezlerle çevreleyebilirsinizYield
:(concurrency::Context::Yield)();
Visual Studio 2015'te Derleyici Uyumluluğu Geliştirmeleri
Önceki sürümlerden kod yükseltirken, Visual Studio 2015'te yapılan uyumluluk geliştirmelerinden kaynaklanan derleyici hatalarıyla da karşılaşabilirsiniz. Bu geliştirmeler, Visual Studio'nun önceki sürümlerinden ikili uyumluluğu bozmaz, ancak daha önce hiçbirinin gösterilmediği derleyici hataları üretebilir. Daha fazla bilgi için bkz . Visual C++ Yenilikler 2003 ile 2015 arasında.
Visual Studio 2015'te, derleyici uyumluluğunda yapılan sürekli iyileştirmeler bazen derleyicinin mevcut kaynak kodunuzu anlama biçimini değiştirebilir. Sonuç olarak, derlemeniz sırasında yeni veya farklı hatalarla, hatta daha önce derlenmiş ve düzgün çalışıyor gibi görünen kodda davranış farklılıklarıyla karşılaşabilirsiniz.
Neyse ki bu farklılıklar kaynak kodunuzun çoğunu çok az etkiler veya hiç etkilemez. Bu farkları gidermek için kaynak kodu veya diğer değişiklikler gerektiğinde, düzeltmeler küçük ve doğrudan olma eğilimindedir. Daha önce kabul edilebilir kaynak koduna ilişkin değiştirilmesi (önce) gerekebilecek birçok örnek ve bunları düzeltmek için düzeltmeler (sonra) dahil ettik.
Bu farklılıklar kaynak kodunuzu veya diğer derleme yapıtlarınızı etkileyebilir ancak Visual Studio sürümlerine yönelik güncelleştirmeler arasındaki ikili uyumluluğu etkilemez. Hataya neden olan bir değişiklik daha ciddidir ve ikili uyumluluğu etkileyebilir, ancak bu tür ikili uyumluluk sonları yalnızca Visual Studio'nun ana sürümleri arasında (örneğin, Visual Studio 2013 ile Visual Studio 2015 arasında) oluşur. Visual Studio 2013 ile Visual Studio 2015 arasında gerçekleşen hataya neden olan değişiklikler hakkında bilgi için bkz . Visual Studio 2015 Uyumluluk Değişiklikleri.
Visual Studio 2015'te Uyumluluk Geliştirmeleri
/Zc:forScope- seçeneği
Derleyici seçeneği
/Zc:forScope-
kullanım dışıdır ve gelecek bir sürümde kaldırılacaktır.Command line warning D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release
Genellikle bu seçenek, standart değere göre kapsamın dışına çıkmaları gereken noktadan sonra döngü değişkenlerini kullanan standart olmayan kodlara izin vermek için kullanılır. Yalnızca seçeneğiyle
/Za
derlendiğinde gerekliydi, çünkü olmadan/Za
, döngünün sonundan sonra bir for döngüsü değişkeninin kullanılmasına her zaman izin verilir. Standart uyumluluğu önemsemiyorsanız (örneğin, kodunuz diğer derleyicilere taşınabilir değilse) seçeneğini kapatabilir/Za
(veya Dil Uzantılarını Devre Dışı Bırak özelliğini Hayır olarak ayarlayabilirsiniz). Taşınabilir, standartlara uygun kod yazmaya önem veriyorsanız, bu tür değişkenlerin bildirimini döngü dışında bir noktaya taşıyarak kodunuzu standarda uyacak şekilde yeniden yazmanız gerekir.// C2065 expected int main() { // Uncomment the following line to resolve. // int i; for (int i = 0; i < 1; i++); i = 20; // i has already gone out of scope under /Za }
/Zg
derleyici seçeneğiDerleyici
/Zg
seçeneği (İşlev Prototipleri Oluştur) artık kullanılamıyor. Bu derleyici seçeneği daha önce kullanım dışı bırakılmıştı.C++/CLI ile birim testlerini artık mstest.exe ile komut satırından çalıştırasınız. Bunun yerine vstest.console.exe kullanın. Bkz. VSTest.Console.exe komut satırı seçenekleri.
mutable anahtar sözcüğü
mutable
Depolama sınıfı tanımlayıcısının daha önce hatasız derlendiği yerlerde artık izin verilmiyor. Şimdi derleyici C2071 (geçersiz depolama sınıfı) hatası veriyor. Standarda göre,mutable
tanımlayıcı yalnızca sınıf veri üyelerinin adlarına uygulanabilir ve sabit veya statik olarak bildirilen adlara uygulanamaz ve başvuru üyelerine uygulanamaz.Örneğin, aşağıdaki kodu göz önünde bulundurun:
struct S { mutable int &r; };
Derleyicinin önceki sürümleri bunu kabul etti, ancak şimdi derleyici aşağıdaki hatayı veriyor:
error C2071: 'S::r': illegal storage class
Hatayı düzeltmek için yedekli
mutable
anahtar sözcüğü kaldırın.char_16_t ve char32_t
Artık içinde veya
char32_t
diğer adlarıtypedef
kullanamazsınızchar16_t
çünkü bu türler artık yerleşik olarak ele alındı. Kullanıcıların ve kitaplık yazarlarının sırasıyla vechar32_t
diğer adları olarak tanımlamasıuint32_t
char16_t
uint16_t
yaygın bir durumdu.#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; }
Kodunuzu güncelleştirmek için bildirimleri kaldırın
typedef
ve bu adlarla çakan diğer tanımlayıcıları yeniden adlandırın.Tür olmayan şablon parametreleri
Açık şablon bağımsız değişkenleri sağladığınızda tür olmayan şablon parametreleri içeren bazı kodlar artık tür uyumluluğu için doğru şekilde denetlenmektedir. Örneğin, aşağıdaki kod Visual Studio'nun önceki sürümlerinde hatasız derlenmiştir.
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>(); }
Şablon parametre türü şablon bağımsız değişkeniyle eşleşmediğinden geçerli derleyici doğru bir hata veriyor (parametre bir const üyesinin işaretçisidir, ancak f işlevi const değildir):
error C2893: Failed to specialize function template 'void S2::f(void)'note: With the following template arguments:note: 'C=S1'note: 'Function=S1::f'
Kodunuzdaki bu hatayı gidermek için kullandığınız şablon bağımsız değişkeninin türünün, şablon parametresinin bildirilen türüyle eşleştiğinden emin olun.
__declspec(align)
Derleyici artık işlevleri kabul etmemektedir
__declspec(align)
. Bu yapı her zaman yoksayılır, ancak şimdi bir derleyici hatası üretir.error C3323: 'alignas' and '__declspec(align)' are not allowed on function declarations
Bu sorunu düzeltmek için işlev bildiriminden kaldırın
__declspec(align)
. Hiçbir etkisi olmadığından, kaldırmak hiçbir şeyi değiştirmez.Özel durumları işleme
Özel durum işlemede birkaç değişiklik vardır. İlk olarak, özel durum nesnelerinin kopyalanabilir veya taşınabilir olması gerekir. Aşağıdaki kod Visual Studio 2013'te derlenmiş ancak Visual Studio 2015'te derlenemez:
struct S { public: S(); private: S(const S &); }; int main() { throw S(); // error }
Sorun, kopya oluşturucunun özel olmasıdır, bu nedenle nesne bir özel durumu işlemenin normal sırasında olduğu gibi kopyalanamaz. Aynı durum, kopya oluşturucu bildirildiğinde
explicit
de geçerlidir.struct S { S(); explicit S(const S &); }; int main() { throw S(); // error }
Kodunuzu güncelleştirmek için, özel durum nesnenizin
public
kopya oluşturucusunun işaretli olmadığından ve işaretlenmediğindenexplicit
emin olun.Bir özel durumun değere göre yakalanması, özel durum nesnesinin de kopyalanabilir olmasını gerektirir. Aşağıdaki kod Visual Studio 2013'te derlenmiş ancak Visual Studio 2015'te derlenemez:
struct B { public: B(); private: B(const B &); }; struct D : public B {}; int main() { try { } catch (D d) // error { } }
için parametre türünü
catch
bir başvuru olarak değiştirerek bu sorunu düzeltebilirsiniz.catch (D& d) { }
Dize değişmez değerleri ve ardından makrolar
Derleyici artık kullanıcı tanımlı değişmez değerleri destekliyor. Sonuç olarak, dize değişmez değerleri ve ardından boşluk içermeyen makrolar kullanıcı tanımlı değişmez değerler olarak yorumlanır ve bu da hatalara veya beklenmeyen sonuçlara neden olabilir. Örneğin, önceki derleyicilerde aşağıdaki kod başarıyla derlenmiş:
#define _x "there" char* func() { return "hello"_x; } int main() { char * p = func(); return 0; }
Derleyici bu kodu bir dize değişmez değeri "hello" olarak yorumladı ve ardından "orada" olarak genişletilen bir makro ve ardından iki dize değişmez değeri birleştirilmişti. Visual Studio 2015'te derleyici bu diziyi kullanıcı tanımlı değişmez değer olarak yorumlar, ancak eşleşen kullanıcı tanımlı değişmez değer
_x
tanımlanmadığından hata verir.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?
Bu sorunu çözmek için dize değişmez değeri ile makro arasına bir boşluk ekleyin.
Bitişik dize değişmez değerleri
Öncekine benzer şekilde, dize ayrıştırmadaki ilgili değişiklikler nedeniyle, herhangi bir boşluk olmadan bitişik dize değişmez değerleri (geniş veya dar karakter dizesi değişmez değerleri), Visaul C++ uygulamasının önceki sürümlerinde tek bir birleştirilmiş dize olarak yorumlandı. Visual Studio 2015'te artık iki dize arasına boşluk eklemeniz gerekir. Örneğin, aşağıdaki kod değiştirilmelidir:
char * str = "abc""def";
Bu sorunu çözmek için iki dize arasına bir boşluk ekleyin:
char * str = "abc" "def";
Yeni yerleştirme ve silme
C++14 standardına uygun hale getirmek için işleçte bir değişiklik yapılmıştır
delete
. Standart değişikliğinin ayrıntıları C++ Boyutlu Serbest Bırakma adresinde bulunabilir. Değişiklikler, boyut parametresini alan geneldelete
işlecin biçimini ekler. Hataya neden olan değişiklik, daha önce aynı imzaya sahip bir işleç kullandıysanız (yerleştirme yeni işlecinedelete
karşılık gelecek şekilde), derleyici hatası (C2956, yeni yerleştirmenin kullanıldığı noktada oluşur, çünkü bu, derleyicinin uygun bir eşleştirmedelete
işlecini tanımlamaya çalıştığı kod konumudur).İşlev
void operator delete(void *, size_t)
, C++11'deki yerleştirme yeni işlevinevoid * operator new(size_t, size_t)
karşılık gelen bir yerleştirme silme işleciydi. C++14 boyutlu serbest bırakma ile bu silme işlevi artık normal bir serbest bırakma işlevidir (geneldelete
işleç). Standart, yeni yerleştirme kullanımı karşılık gelen bir silme işlevini ararsa ve normal bir serbest bırakma işlevi bulursa, programın kötü biçimlendirilmiş olmasını gerektirir.Örneğin, kodunuzun hem yeni bir yerleştirme hem de yerleştirme silme işlemi tanımladığı varsayılarak:
void * operator new(std::size_t, std::size_t); void operator delete(void*, std::size_t) noexcept;
Sorun, tanımladığınız bir yerleştirme silme işleci ile yeni genel boyutlu
delete
işleç arasındaki işlev imzalarındaki eşleşme nedeniyle oluşur. Yeni yerleştirme vedelete
işleçlersize_t
dışında farklı bir tür kullanıp kullanamayacağınızı düşünün. türüsize_t
typedef
derleyiciye bağımlıdır; MSVC'de içinunsigned int
şeklindedirtypedef
. bunun gibi numaralandırılmış bir tür kullanmak iyi bir çözümdür:enum class my_type : size_t {};
Ardından, yeni yerleştirme tanımınızı değiştirin ve
delete
bu türü yerinesize_t
ikinci bağımsız değişken olarak kullanın. Ayrıca, yeni türü geçirmek için çağrıları yeni yerleştirmeye güncelleştirmeniz (örneğin, tamsayı değerinden dönüştürmek için kullanarakstatic_cast<my_type>
) ve tanımınınew
güncelleştirerek vedelete
tamsayı türüne geri döndürmeniz gerekir. Bunun için birenum
kullanmanız gerekmez; üyesi olan birsize_t
sınıf türü de çalışır.Alternatif bir çözüm, yeni yerleştirmeyi tamamen ortadan kaldırabilmenizdir. Kodunuz yerleştirme bağımsız değişkeninin ayrılan veya silinen nesnenin boyutu olduğu bir bellek havuzu uygulamak için yerleştirme yeni kullanıyorsa, boyutlandırılmış serbest bırakma özelliği kendi özel bellek havuzu kodunuzu değiştirmeye uygun olabilir ve yerleştirme işlevlerinden kurtulup yerleştirme işlevleri yerine kendi iki bağımsız değişken
delete
işlecinizi kullanabilirsiniz.Kodunuzu hemen güncelleştirmek istemiyorsanız, derleyici seçeneğini
/Zc:sizedDealloc-
kullanarak eski davranışa geri dönebilirsiniz. Bu seçeneği kullanırsanız, iki bağımsız değişkenli silme işlevleri yoktur ve yerleştirme silme işlecinizle çakışmaya neden olmaz.Birleşim veri üyeleri
Birleşimlerin veri üyeleri artık başvuru türlerine sahip olamaz. Aşağıdaki kod Visual Studio 2013'te başarıyla derlenmiş ancak Visual Studio 2015'te bir hata üretir.
union U1 { const int i; }; union U2 { int & i; }; union U3 { struct { int & i; }; };
Yukarıdaki kod aşağıdaki hataları oluşturur:
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
Bu sorunu gidermek için başvuru türlerini işaretçi veya değer olarak değiştirin. Türü işaretçi olarak değiştirmek için birleşim alanını kullanan kodda değişiklik yapılması gerekir. Kodun bir değere değiştirilmesi birleşimde depolanan verileri değiştirir ve birleşim türlerindeki alanlar aynı belleği paylaştığından diğer alanları etkiler. Değerin boyutuna bağlı olarak birleşim boyutunu da değiştirebilir.
Anonim birleşimler artık standarda daha uygun. Derleyicinin önceki sürümleri anonim birleşimler için açık bir oluşturucu ve yıkıcı oluşturdu. Derleyici tarafından oluşturulan bu işlevler Visual Studio 2015'te silinir.
struct S { S(); }; union { struct { S s; }; } u; // C2280
Yukarıdaki kod, Visual Studio 2015'te aşağıdaki hatayı oluşturur:
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
Bu sorunu çözmek için oluşturucu ve/veya yıkıcının kendi tanımlarını sağlayın.
struct S { // Provide a default constructor by adding an empty function body. S() {} }; union { struct { S s; }; } u;
Anonim yapılara sahip birleşimler
Standarda uymak için birleşimlerdeki anonim yapıların üyeleri için çalışma zamanı davranışı değişti. Bir birleşimdeki anonim yapı üyeleri için oluşturucu, böyle bir birleşim oluşturulduğunda artık örtük olarak çağrılmaz. Ayrıca, bir birleşimdeki anonim yapı üyeleri için yıkıcı artık birleşim kapsamı dışına çıktığında örtük olarak çağrılmaz. U birleşiminin, yıkıcısı olan adlandırılmış üye yapısı S içeren anonim bir yapı içerdiği aşağıdaki kodu göz önünde bulundurun.
#include <stdio.h> struct S { S() { printf("Creating S\n"); } ~S() { printf("Destroying S\n"); } }; union U { struct { S s; }; U() {} ~U() {} }; void f() { U u; // Destructor implicitly called here. } int main() { f(); char s[1024]; printf("Press any key.\n"); gets_s(s); return 0; }
Visual Studio 2013'te, birleşim oluşturulduğunda S oluşturucu çağrılır ve f işlevinin yığını temizlendiğinde S için yıkıcı çağrılır. Ancak Visual Studio 2015'te oluşturucu ve yıkıcı çağrılmaz. Derleyici bu davranış değişikliği hakkında bir uyarı verir.
warning C4587: 'U::s': behavior change: constructor is no longer implicitly calledwarning C4588: 'U::s': behavior change: destructor is no longer implicitly called
Özgün davranışı geri yüklemek için anonim yapıya bir ad verin. Anonim olmayan yapıların çalışma zamanı davranışı, derleyici sürümünden bağımsız olarak aynıdır.
#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; }
Alternatif olarak, oluşturucu ve yıkıcı kodunu yeni işlevlere taşımayı deneyin ve birleşim için oluşturucu ve yıkıcıdan bu işlevlere çağrılar ekleyin.
#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; }
Şablon çözünürlüğü
Şablonlar için ad çözümlemesinde değişiklikler yapılmıştır. C++'ta, bir adın çözümlenmesi için adaylar dikkate alınırken, olası eşleşmeler geçersiz bir şablon örneklemesi oluşturduğundan dikkate alınacak bir veya daha fazla adın olması söz konusu olabilir. Bu geçersiz örneklemeler normalde SFINAE (Değiştirme Hatası Bir Hata Değildir) olarak bilinen bir ilke olan derleyici hatalarına neden olmaz.
Şimdi, SFINAE derleyicinin bir sınıf şablonunun uzmanlığını oluşturmasını gerektiriyorsa, bu işlem sırasında oluşan hatalar derleyici hatalarıdır. Önceki sürümlerde derleyici bu tür hataları yoksayacaktı. Örneğin, aşağıdaki kodu göz önünde bulundurun:
#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); }
Geçerli derleyiciyle derlerseniz aşağıdaki hatayı alırsınız:
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 ]
Bunun nedeni, sınıfın
D
henüz tanımlanmamış is_base_of ilk çağrının noktasında olmasıdır.Bu durumda, düzeltme, sınıf tanımlanana kadar bu tür özellikleri kullanmamaktır. ve
D
tanımlarınıB
kod dosyasının başına taşırsanız hata çözülür. Tanımlar üst bilgi dosyalarındaysa, sorunlu şablonlar kullanılmadan önce tüm sınıf tanımlarının derlendiğinden emin olmak için üst bilgi dosyalarının include deyimlerinin sırasını denetleyin.Oluşturucuları kopyalama
Hem Visual Studio 2013'te hem de Visual Studio 2015'te, bu sınıfın kullanıcı tanımlı bir taşıma oluşturucusunun olması ancak kullanıcı tanımlı kopya oluşturucunun olmaması durumunda derleyici sınıf için bir kopya oluşturucu oluşturur. Dev14'te, örtük olarak oluşturulan bu kopya oluşturucu da "= delete" olarak işaretlenir.
extern "C" olarak bildirilen main artık bir dönüş türü gerektiriyor.
Aşağıdaki kod artık C4430 üretir.
extern "C" __cdecl main(){} // C4430
Hatayı düzeltmek için dönüş türünü ekleyin:
extern "C" int __cdecl main(){} // OK
Üye başlatıcıda typename'e izin verilmiyor
Aşağıdaki kod artık C2059 üretir:
template<typename T> struct S1 : public T::type { S1() : typename T::type() // C2059 { } }; struct S2 { typedef S2 type; }; S1<S2> s;
Hatayı düzeltmek için başlatıcıdan kaldırın
typename
:S1() : T::type() // OK ...
Açık özelleştirmelerdeki depolama sınıfı yoksayılır.
Aşağıdaki kodda statik depolama sınıfı tanımlayıcısı yoksayılır
template <typename T> void myfunc(T h) { } template<> static void myfunc(double h) // static is ignored { }
Sınıf şablonunun içindeki bir static_assert kullanılan sabit her zaman başarısız olur.
Aşağıdaki kod, öğesinin
static_assert
her zaman başarısız olmasına neden olur:template <size_t some_value> struct S1 { static_assert(false, "default not valid"); // always invoked }; //other partial specializations here
Bu soruna geçici bir çözüm bulmak için değerini içinde
struct
sarmala: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
İleriye dönük bildirimler için zorunlu kılınan kurallar. (Yalnızca C için geçerlidir.)
Aşağıdaki kod artık C2065 üretir:
struct token_s; typedef int BOOL; typedef int INT; typedef int(*PFNTERM)(PTOKEN, BOOL, INT); // C2065: 'PTOKEN' : undeclared identifier
Bu sorunu düzeltmek için uygun iletme bildirimlerini ekleyin:
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);
İşlev işaretçisi türlerinin daha tutarlı bir şekilde uygulanması
Aşağıdaki kod artık C2197 üretir:
typedef int(*F1)(int); typedef int(*F2)(int, int); void func(F1 f, int v1, int v2) { f(v1, v2); // C2197 }
Aşırı yüklenmiş işlevlere belirsiz çağrılar
Şu kod artık C266 üretir: 'N::bind': aşırı yüklenmiş işleve belirsiz çağrı
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 } };
Hatayı düzeltmek için çağrısına
bind: N::bind(...)
tam niteleyebilirsiniz. Ancak, bu değişiklik bildirilmemiş bir tanımlayıcı (C2065) aracılığıyla bildiriliyorsa, bunun yerine birusing
bildirimle düzeltmek uygun olabilir.Bu düzen, ComPtr ve ad alanında diğer türlerde
Microsoft::WRL
sık sık gerçekleşir.Yanlış adresi düzelt
Şu kod artık C2440 üretir: '=': 'type *' türünden 'type' türüne dönüştürülemez. Hatayı düzeltmek için &(tür) değerini (tür) ve (&f()) değerini (f()) olarak değiştirin.
// 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()); }
Dize değişmez değeri sabit bir dizidir
Şu kod artık C2664 üretir: 'void f(void )': 1 bağımsız değişkenini 'const char ()[2]' olan 'void *' karakterine dönüştüremez
void f(void *); void h(void) { f(&__FUNCTION__); void *p = &""; }
Hatayı düzeltmek için işlev parametre türünü
const void*
olarak değiştirin veya gövdesinih
şu örneğe benzer şekilde değiştirin:void h(void) { char name[] = __FUNCTION__; f( name); void *p = &""; }
C++11 UDL dizeleri
Aşağıdaki kod artık C3688 hatası üretir: geçersiz değişmez değer soneki 'L'; değişmez değer işleci veya değişmez değer işleci şablonu 'işleç ""L' bulunamadı
#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"); }
Hatayı düzeltmek için kodu değiştirerek bir alan ekleyin:
#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"); }
Yukarıdaki örnekte,
MACRO
artık iki belirteç (bir dize ve ardından bir makro) olarak ayrıştırılmış değildir. Şimdi tek bir belirteç UDL olarak ayrıştırılır. Aynı durum, daha önce L"" ve L"" olarak ayrıştırılan ve şimdi L""L ve "" olarak ayrıştırılan L""L"" için de geçerlidir.Dize birleştirme kuralları da standartla uyumlu bir şekilde getirilmiştir, yani L"a" "b" L"ab" ile eşdeğerdir. Visual Studio'nun önceki sürümleri, farklı karakter genişliğine sahip dizelerin birleştirilme işlemini kabul etmedi.
C++11 boş karakter kaldırıldı
Aşağıdaki kod artık C2137 hatası üretir: boş karakter sabiti
bool check(wchar_t c){ return c == L''; //implicit null character }
Hatayı düzeltmek için kodu null değerini açık olacak şekilde değiştirin:
bool check(wchar_t c){ return c == L'\0'; }
MFC özel durumları kopyalanamadığından değer tarafından yakalanamaz
MFC uygulamasındaki aşağıdaki kod artık C2316 hatasına neden oluyor: 'D': yıkıcı ve/veya kopya oluşturucu erişilemez veya silindiğinden yakalanamaz
struct B { public: B(); private: B(const B &); }; struct D : public B { }; int main() { try { } catch (D) // C2316 { } }
Kodu düzeltmek için catch bloğunu
catch (const D &)
olarak değiştirebilirsiniz, ancak en iyi çözüm genellikle MFC TRY/CATCH makrolarını kullanmaktır.alignof
artık bir anahtar sözcükAşağıdaki kod artık C2332 hatası üretir: 'class': etiket adı eksik. Kodu düzeltmek için sınıfı yeniden adlandırmanız veya sınıfı ile aynı işi
alignof
yapıyorsa sınıfını yeni anahtar sözcükle değiştirmeniz gerekir.class alignof{}
constexpr
artık bir anahtar sözcükAşağıdaki kod artık C2059 hatası üretir: söz dizimi hatası: ')'. Kodu düzeltmek için adlı
constexpr
işlev veya değişken adlarını yeniden adlandırmanız gerekir.int constexpr() {return 1;}
Taşınabilir türler sabit olamaz
bir işlev taşınması amaçlanan bir tür döndürdüğünde, dönüş türü olmamalıdır
const
.Silinen kopya oluşturucuları
Aşağıdaki kod artık C2280 'S::S(S&&)' üretir: silinen bir işleve başvurmaya çalışıyor:
struct S{ S(int, int); S(const S&) = delete; S(S&&) = delete; }; S s2 = S(2, 3); //C2280
Hatayı düzeltmek için için
S2
doğrudan başlatmayı kullanın:struct S{ S(int, int); S(const S&) = delete; S(S&&) = delete; }; S s2 = {2,3}; //OK
yalnızca lambda yakalama olmadığında oluşturulan işlev işaretçisine dönüştürme
Aşağıdaki kod Visual Studio 2015'te C2664 oluşturur.
void func(int(*)(int)) {} int main() { func([=](int val) { return val; }); }
Hatayı düzeltmek için yakalama listesinden öğesini kaldırın
=
.Dönüştürme işleçlerini içeren belirsiz çağrılar
Şu kod artık C2440 hatasını üretir: 'tür ataması': 'S2'den 'S1'e dönüştürülemez:
struct S1 { S1(int); }; struct S2 { operator S1(); operator int(); }; void f(S2 s2) { (S1)s2; }
Hatayı düzeltmek için dönüştürme işlecini açıkça çağırın:
void f(S2 s2) { //Explicitly call the conversion operator s2.operator S1(); // Or S1((int)s2); }
Şu kod artık C2593 hatası üretir: 'operator =' belirsiz:
struct S1 {}; struct S2 { operator S1&(); operator S1() const; }; void f(S1 *p, S2 s) { *p = s; }
Hatayı düzeltmek için dönüştürme işlecini açıkça çağırın:
void f(S1 *p, S2 s) { *p = s.operator S1&(); }
Statik olmayan veri üyesi başlatmasında (NSDMI) geçersiz kopya başlatma düzeltildi
Şu kod artık C2664 hatasını üretir: 'S1::S1(S1 &)': 'bool' olan bağımsız değişken 1'i 'const S1 &' değerine dönüştüremez:
struct S1 { explicit S1(bool); }; struct S2 { S1 s2 = true; // error };
Hatayı düzeltmek için doğrudan başlatmayı kullanın:
struct S2 { S1 s1{true}; // OK };
Decltype deyimleri içindeki oluşturuculara erişme
Şu kod artık C2248 üretir: 'S::S': 'S' sınıfında bildirilen özel üyeye erişemiyor:
class S { S(); public: int i; }; class S2 { auto f() -> decltype(S().i); };
Hatayı düzeltmek için içinde için
S2
S
bir arkadaş bildirimi ekleyin:class S { S(); friend class S2; // Make S2 a friend public: int i; };
Lambda'nın varsayılan ctor'ı örtük olarak silinir
Aşağıdaki kod artık C3497 hatası üretir: lambda örneği oluşturamazsınız:
void func(){ auto lambda = [](){}; decltype(lambda) other; }
Hatayı düzeltmek için varsayılan oluşturucunun çağrılma gereksinimini kaldırın. Lambda hiçbir şey yakalamazsa işlev işaretçisine atanabilir.
Silinen atama işlecine sahip lambdalar
Aşağıdaki kod artık C2280 hatasını üretir:
#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); }
Hatayı düzeltmek için lambda değerini bir functor sınıfıyla değiştirin veya atama işlecini kullanma gereksinimini kaldırın.
Silinen kopya oluşturucu ile bir nesneyi taşıma girişimi
Şu kod artık C2280 hatasını üretir: 'moveable::moveable(const moveable &)': silinen bir işleve başvurmaya çalışıyor
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; };
Hatayı düzeltmek için şunu kullanın
std::move
:S(moveable && m) : m_m(std::move(m))
Yerel sınıf aynı işlevde daha sonra tanımlanan diğer yerel sınıfa başvuramaz
Şu kod artık C2079 hatasını üretir: 's', tanımsız 'main::S2' yapısı kullanıyor
int main() { struct S2; struct S1 { void f() { S2 s; } }; struct S2 {}; }
Hatayı düzeltmek için tanımını
S2
yukarı taşıyın:int main() { struct S2 { //moved up }; struct S1 { void f() { S2 s; } }; }
Türetilmiş ctor gövdesinde korumalı bir temel ctor çağrılamaz.
Şu kod artık C2248 hatası üretir: 'S1::S1': 'S1' sınıfında bildirilen korumalı üyeye erişilemiyor
struct S1 { protected: S1(); }; struct S2 : public S1 { S2() { S1(); } };
Hatayı düzeltmek için içinde
S2
oluşturucudan çağrısıS1()
kaldırın ve gerekirse başka bir işleve yerleştirin.{} işaretçiye dönüştürmeyi engeller
Aşağıdaki kod artık C2439 'S::p' üretir: üye başlatılamadı
struct S { S() : p({ 0 }) {} void *p; };
Hatayı düzeltmek için, bu örnekte gösterildiği gibi veya yerine kullanın
nullptr
küme ayraçlarını0
kaldırın:struct S { S() : p(nullptr) {} void *p; };
Yanlış makro tanımı ve parantezli kullanım
Aşağıdaki örnek şimdi C2008 hatası üretir: ';': makro tanımında beklenmeyen
#define A; //cause of error struct S { A(); // error };
Sorunu çözmek için üst satırı olarak değiştirin
#define A();
Aşağıdaki kod C2059 hatası üretir: söz dizimi hatası: ')'
//notice the space after 'A' #define A () ; struct S { A(); };
Kodu düzeltmek için A ile () arasındaki boşluğu kaldırın.
Aşağıdaki kod C2091 hatasını üretir: function returns function:
#define DECLARE void f() struct S { DECLARE(); };
Hatayı düzeltmek için, S: içinde DECLARE'tan sonra parantezleri kaldırın.
DECLARE;
Aşağıdaki kod C2062 hatasını oluşturur: beklenmeyen 'int' türü
#define A (int) struct S { A a; };
Sorunu çözmek için şu şekilde tanımlayın
A
:#define A int
Bildirimlerde fazladan ayrıştırmalar
Aşağıdaki kod C2062 hatasını oluşturur: beklenmeyen 'int' türü
struct S { int i; (int)j; };
Hatayı düzeltmek için çevresindeki
j
parantezleri kaldırın. Netlik için parantez gerekiyorsa, kullanıntypedef
.Derleyici tarafından oluşturulan oluşturucular ve __declspec(novtable)
Visual Studio 2015'te, sanal temel sınıflara sahip soyut sınıfların derleyici tarafından oluşturulan satır içi oluşturucularının ile
__declspec(dllimport)
birlikte kullanıldığında yanlış kullanımını__declspec(novtable)
ortaya çıkarma olasılığı artar.otomatik, doğrudan liste başlatmada tek bir ifade gerektirir
Şu kod artık C3518 hatası üretir: 'testPositions': Doğrudan liste başlatma bağlamında 'auto' türü yalnızca tek bir başlatıcı ifadesinden çıkarılabilir
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} };
Hatayı düzeltmek için aşağıdaki gibi başlatma
testPositions
olasılığı vardır: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} };
is_convertible için türleri denetleme ve tür işaretçileri karşılaştırması
Aşağıdaki kod artık statik onaylama işleminin başarısız olmasına neden olur.
struct B1 { private: B1(const B1 &); }; struct B2 : public B1 {}; struct D : public B2 {}; static_assert(std::is_convertible<D, B2>::value, "fail");
Hatayı düzeltmek için işaretçileri
D
veB2
ile karşılaştıracak şekilde değerini değiştirinstatic_assert
:static_assert(std::is_convertible<D*, B2*>::value, "fail");
__declspec(novtable) bildirimleri tutarlı olmalıdır
__declspec
bildirimlerinin tüm kitaplıklarda tutarlı olması gerekir. Aşağıdaki kod artık tek tanımlı bir kural (ODR) ihlali oluşturur://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;
Güncelleştirme 1'de Uyumluluk Geliştirmeleri
Özel sanal temel sınıflar ve dolaylı devralma
Derleyicinin önceki sürümleri, türetilmiş bir sınıfın dolaylı olarak türetilmiş
private virtual
temel sınıflarının üye işlevlerini çağırmasına izin verdi. Bu eski davranış yanlıştı ve C++ standardına uymuyor. Derleyici artık bu şekilde yazılmış kodu kabul etmemektedir ve sonuç olarak derleyici hatası C2280'i döndürür.error C2280: 'void *S3::__delDtor(unsigned int)': attempting to reference a deleted function
Örnek (önce)
class base { protected: base(); ~base(); }; class middle : private virtual base {}; class top : public virtual middle {}; void destroy(top *p) { delete p; // }
Örnek (sonra)
class base; // as above class middle : protected virtual base {}; class top : public virtual middle {}; void destroy(top *p) { delete p; }
- veya -
class base; // as above class middle : private virtual base {}; class top : public virtual middle, private virtual bottom {}; void destroy(top *p) { delete p; }
Aşırı yüklenmiş yeni işleç ve işleç silme
Derleyicinin önceki sürümleri, üye olmayan işleç yeni ve üye olmayan işleç silme işleminin statik olarak bildirilmesine ve genel ad alanı dışındaki ad alanlarına bildirilmesine izin verdi. Bu eski davranış, programın programcının
new
amaçladığı veyadelete
işleci uygulamasını çağırmaması riski oluşturarak sessiz hatalı çalışma zamanı davranışına neden oldu. Derleyici artık bu şekilde yazılmış kodu kabul etmemektedir ve bunun yerine derleyici hatası C2323'e neden olur.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.
Örnek (önce)
static inline void * __cdecl operator new(size_t cb, const std::nothrow_t&) // error C2323
Örnek (sonra)
void * __cdecl operator new(size_t cb, const std::nothrow_t&) // removed 'static inline'
Ayrıca, derleyici belirli bir tanılama vermese de, satır içi işleç
new
kötü biçimlendirilmiş olarak kabul edilir.Sınıf dışı türlerde 'operator type()' (kullanıcı tanımlı dönüştürme) çağrısı
Derleyicinin önceki sürümleri sessizce yoksayırken sınıf dışı türlerde 'işleç türü()' çağrılmaya izin verdi. Bu eski davranış sessiz hatalı kod oluşturma riski oluşturarak öngörülemeyen çalışma zamanı davranışına neden oldu. Derleyici artık bu şekilde yazılmış kodu kabul etmemektedir ve bunun yerine derleyici hatası C2228'i döndürür.
error C2228: left of '.operator type' must have class/struct/union
Örnek (önce)
typedef int index_t; void bounds_check(index_t index); void login(int column) { bounds_check(column.operator index_t()); // error C2228 }
Örnek (sonra)
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' }
Ayrıntılı tür tanımlayıcılarında yedekli tür adı
Derleyicinin önceki sürümleri ayrıntılı bir tür belirticisinde izin veriliyordu
typename
, ancak bu şekilde yazılmış kodlar ad açısından yanlış. Derleyici artık bu şekilde yazılmış kodu kabul etmemektedir ve bunun yerine derleyici hatası C3406'dır.error C3406: 'typename' cannot be used in an elaborated type specifier
Örnek (önce)
template <typename class T> class container;
Örnek (sonra)
template <class T> // alternatively, could be 'template <typename T>'; 'typename' is not elaborating a type specifier in this case class container;
Bir başlatıcı listesinden dizilerin tür kesintisi
Derleyicinin önceki sürümleri, bir başlatıcı listesinden dizilerin tür kesintisini desteklemedi. Derleyici artık bu tür kesinti biçimini destekler ve sonuç olarak, başlatıcı listelerini kullanan işlev şablonlarına yapılan çağrılar artık belirsiz olabilir veya derleyicinin önceki sürümlerinden farklı bir aşırı yükleme seçilebilir. Bu sorunları çözmek için, programın artık programcının hedeflediği aşırı yüklemeyi açıkça belirtmesi gerekir.
Bu yeni davranış, aşırı yükleme çözümlemesinin geçmiş aday kadar iyi olan ek bir adayı dikkate almasına neden olduğunda, çağrı belirsiz hale gelir ve derleyici sonuç olarak derleyici hatası C2668'i döndürür.
error C2668: 'function' : ambiguous call to overloaded function.
Örnek 1: Aşırı yüklenmiş işleve belirsiz çağrı (önce)
// 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 }
Örnek 1: aşırı yüklenmiş işleve belirsiz çağrı (sonra)
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); }
Bu yeni davranış, aşırı yükleme çözümlemesinin geçmiş adaydan daha iyi bir aday olarak kabul edilmesine neden olduğunda, çağrı yeni adayla belirsiz bir şekilde çözülür ve programcının hedeflediği davranıştan büyük olasılıkla farklı bir program davranışı değişikliğine neden olur.
Örnek 2: aşırı yükleme çözünürlüğünde değişiklik (önce)
// 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 }); }
Örnek 2: aşırı yükleme çözünürlüğünde değişiklik (sonra)
struct S; // as before template < typename... Args> void f(S, Args...); template < int N, typename... Args> void f(const int *&)[N], Args...); int main() { // To call f(S, Args...), perform an explicit cast to S on the initializer list. f(S{ 1, 2 }); }
Switch deyimi uyarılarının geri yüklenmesi
Derleyicinin önceki bir sürümü deyimlerle ilgili
switch
bazı uyarıları kaldırdı; bu uyarılar artık geri yüklendi. Derleyici artık geri yüklenen uyarıları yayımlar ve belirli servis talepleri (varsayılan servis talebi dahil) ile ilgili uyarılar artık switch deyiminin son satırında değil, sorunlu olayı içeren satırda verilir. Bu uyarıların geçmiştekinden farklı satırlarda verilmesinin bir sonucu olarak, daha önce kullanılarak#pragma warning(disable:####)
gizlenen uyarılar artık istendiği gibi gizlenmeyebilir. Bu uyarıların istendiği gibi gizlenmesi için yönergesini#pragma warning(disable:####)
ilk sorunlu durumun üzerindeki bir satıra taşımak gerekebilir. Geri yüklenen uyarılar şunlardır:warning C4060: switch statement contains no 'case' or 'default' labels
warning C4061: enumerator 'bit1' in switch of enum 'flags' is not explicitly handled by a case label
warning C4062: enumerator 'bit1' in switch of enum 'flags' is not handled
warning C4063: case 'bit32' is not a valid value for switch of enum 'flags'
warning C4064: switch of incomplete enum 'flags'
warning C4065: switch statement contains 'default' but no 'case' labels
warning C4808: case 'value' is not a valid value for switch condition of type 'bool'
Warning C4809: switch statement has redundant 'default' label; all possible 'case' labels are given
C4063 örneği (önce)
class settings { public: enum flags { bit0 = 0x1, bit1 = 0x2, ... }; ... }; int main() { auto val = settings::bit1; switch (val) { case settings::bit0: break; case settings::bit1: break; case settings::bit0 | settings::bit1: // warning C4063 break; } };
C4063 örneği (sonra)
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; } };
Geri yüklenen diğer uyarıların örnekleri belgelerinde verilmiştir.
#include: '..' üst dizin tanımlayıcısının kullanımı pathname içinde (yalnızca etkiler
/Wall
/WX
)Derleyicinin önceki sürümleri üst dizin tanımlayıcısı '..' kullanımını algılamadı yönergelerinin yol adında
#include
. Bu şekilde yazılan kod genellikle proje göreli yollarını yanlış kullanarak projenin dışında bulunan üst bilgileri içerecek şekilde tasarlanmıştır. Bu eski davranış, programcının hedeflediği kaynak dosyadan farklı bir kaynak dosyası ekleyerek programın derlenme riskini veya bu göreli yolların diğer derleme ortamlarına taşınmayacağını ortaya çıkardı. Derleyici şimdi programcıya bu şekilde yazılmış kodu algılar ve bildirir ve etkinleştirildiyse isteğe bağlı bir derleyici uyarısı C4464 verir.warning C4464: relative include path contains '..'
Örnek (önce)
#include "..\headers\C4426.h" // emits warning C4464
Örnek (sonra)
#include "C4426.h" // add absolute path to 'headers\' to your project's include directories
Ayrıca, derleyici belirli bir tanılama vermese de, projenizin ekleme dizinlerini belirtmek için üst dizin tanımlayıcısının ".." kullanılmaması önerilir.
#pragma optimize() üst bilgi dosyasının geçmiş sonunu genişletir (yalnızca etkiler
/Wall
/WX
)Derleyicinin önceki sürümleri, çeviri birimine dahil edilen üst bilgi dosyasından kaçan iyileştirme bayrağı ayarlarında yapılan değişiklikleri algılamadı. Derleyici şimdi programcıya bu şekilde yazılmış kodu algılar ve bildirir ve etkinleştirildiyse sorunlu
#include
konumunda isteğe bağlı bir derleyici uyarısı C4426 verir. Bu uyarı yalnızca değişiklikler, derleyiciye komut satırı bağımsız değişkenleri tarafından ayarlanan iyileştirme bayraklarıyla çakışıyorsa verilir.warning C4426: optimization flags changed after including header, may be due to #pragma optimize()
Örnek (önce)
// C4426.h #pragma optimize("g", off) ... // C4426.h ends // C4426.cpp #include "C4426.h" // warning C4426
Örnek (sonra)
// 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"
Eşleşmeyen #pragma uyarısı (gönderme) ve #pragma uyarısı(pop) (yalnızca etkiler
/Wall
/WX
)Derleyicinin önceki sürümleri, durum değişikliklerinin nadiren amaçlanan farklı bir kaynak dosyasındaki durum değişiklikleriyle
#pragma warning(pop)
eşleştirildiğini algılamadı#pragma warning(push)
. Bu eski davranış, programın programcının amaçladığı uyarı kümesinden farklı bir uyarı kümesiyle derlenmesi ve büyük olasılıkla sessiz hatalı çalışma zamanı davranışına neden olma riski doğurdu. Derleyici şimdi programcıya bu şekilde yazılmış kodu algılar ve bildirir ve etkinse eşleşen#pragma warning(pop)
konumunda isteğe bağlı bir derleyici uyarısı C5031 verir. Bu uyarı, ilgili #pragma uyarısının (gönderim) konumuna başvuran bir not içerir.warning C5031: #pragma warning(pop): likely mismatch, popping warning state pushed in different file
Örnek (önce)
// 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 ...
Örnek (sonra)
// 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" ...
Yaygın olmasa da, bu şekilde yazılan kodlar bazen kasıtlı olarak gerçekleştirilir. Bu şekilde yazılan kod, değişikliklere
#include
sırasıyla duyarlıdır; mümkün olduğunda, kaynak kod dosyalarının uyarı durumunu kendi içinde bir şekilde yönetmesini öneririz.Eşleşmeyen #pragma uyarısı (gönderme) (yalnızca etkiler
/Wall
/WX
)Derleyicinin önceki sürümleri, çeviri biriminin sonunda eşleşmeyen
#pragma warning(push)
durum değişikliklerini algılamadı. Derleyici şimdi programcıya bu şekilde yazılmış kodu algılar ve bildirir ve etkinleştirilirse eşleşmeyen#pragma warning(push)
konumunda isteğe bağlı bir derleyici uyarısı C5032 verir. Bu uyarı yalnızca çeviri biriminde derleme hatası yoksa verilir.warning C5032: detected #pragma warning(push) with no corresponding #pragma warning(pop)
Örnek (önce)
// 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
Örnek (sonra)
// 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)
Geliştirilmiş #pragma uyarı durumu izlemesi sonucunda ek uyarılar oluşturulabilir
Derleyicinin izlenen #pragma uyarı durumunun önceki sürümleri, istenen tüm uyarıları vermek için yeterince iyi değil. Bu davranış, programcının hedeflediğinden farklı durumlarda belirli uyarıların etkili bir şekilde gizleneceği bir risk oluşturmuştur. Derleyici artık durumu daha sağlam bir şekilde izler
#pragma warning
(özellikle şablonların içindeki durum değişiklikleriyle#pragma warning
ilgili) ve isteğe bağlı olarak programcının ve 'in istenmeyen kullanımlarını#pragma warning(push)
bulmasına yardımcı olmak için tasarlanan yeni C5031 ve#pragma warning(pop)
C5032 uyarıları verir.Gelişmiş
#pragma warning
durum değişikliği izlemesi sonucunda, önceden yanlış bir şekilde gizlenen uyarılar veya önceden yanlış tanılanan sorunlarla ilgili uyarılar artık yayınlanabilir.Ulaşılamayan kodun iyileştirilmiş kimliği
C++ Standart Kitaplığı değişiklikleri ve derleyicinin önceki sürümlerine göre işlev çağrılarını satır içi olarak satır içi hale getirme özelliği, derleyicinin belirli kodlara artık ulaşılamediğini kanıtlamasına olanak tanıyabilir. Bu yeni davranış, C4720 uyarısının yeni ve daha sık verilen örneklerine neden olabilir.
warning C4720: unreachable code
Çoğu durumda, bu uyarı yalnızca iyileştirmeler etkin olarak derlenirken verilebilir, çünkü iyileştirmeler daha fazla işlev çağrısı satır içi yapabilir, yedekli kodu ortadan kaldırabilir veya başka bir şekilde belirli kodun erişilemez olduğunu belirlemeyi mümkün hale getirir. C4720 uyarılarının yeni örneklerinin, özellikle std::find kullanımıyla ilgili olarak try/catch bloklarında sıklıkla oluştuğuna dikkat ettik.
Örnek (önce)
try { auto iter = std::find(v.begin(), v.end(), 5); } catch (...) { do_something(); // ok }
Örnek (sonra)
try { auto iter = std::find(v.begin(), v.end(), 5); } catch (...) { do_something(); // warning C4702: unreachable code }
Güncelleştirme 2'de Uyumluluk Geliştirmeleri
SFINAE ifadesi için kısmi destek sonucunda ek uyarılar ve hatalar oluşabilir
Derleyicinin önceki sürümleri, SFINAE ifadesi için destek olmaması nedeniyle tanımlayıcıların içinde
decltype
belirli ifade türlerini ayrıştırmamıştı. Bu eski davranış yanlıştı ve C++ standardına uymuyor. Derleyici artık bu ifadeleri ayrıştırıyor ve devam eden uyumluluk geliştirmeleri nedeniyle SFINAE ifadesi için kısmi desteğe sahip. Sonuç olarak, derleyici artık derleyicinin önceki sürümlerinin ayrıştırmadığı ifadelerde bulunan uyarılar ve hatalar döndürür.Bu yeni davranış henüz bildirilmemiş bir tür içeren bir
decltype
ifadeyi ayrıştırdığında, derleyici sonuç olarak derleyici hatası C2039'ı döndürür.error C2039: 'type': is not a member of 'global namespace'
Örnek 1: bildirilmemiş bir türün kullanımı (önce)
struct s1 { template < typename T> auto f() - > decltype(s2< T> ::type::f()); // error C2039 template< typename> struct s2 {}; }
Örnek 1 (sonra)
struct s1 { template < typename> // forward declare s2struct s2; template < typename T> auto f() - > decltype(s2< T> ::type::f()); template< typename> struct s2 {}; }
Bu yeni davranış, bağımlı bir
decltype
adın tür olduğunu belirtmek için anahtar sözcüğüntypename
gerekli kullanımını eksik olan bir ifadeyi ayrıştırdığında, derleyici C2923 derleyici hatasıyla birlikte derleyici uyarısı C4346'yı döndürür.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'
Örnek 2: bağımlı ad bir tür değil (önce)
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 };
Örnek 2 (sonra)
template < typename T> struct s1 { ... }; // as above template < typename T> struct s2 { ... }; // as above template < typename T> T declval(); struct s { template < typename T> auto f(T t) - > decltype(t(declval< S1< typename S2< T> ::type> ::type> ())); };
volatile
üye değişkenleri örtük olarak tanımlanmış oluşturucuları ve atama işleçlerini engellerDerleyicinin önceki sürümleri, üye değişkenleri olan
volatile
bir sınıfın varsayılan kopyalama/taşıma oluşturucularına ve varsayılan kopyalama/taşıma atama işleçlerinin otomatik olarak oluşturulmasına izin verdi. Bu eski davranış yanlıştı ve C++ standardına uymuyor. Derleyici artık üye değişkenleri olanvolatile
bir sınıfı önemsiz olmayan yapı ve atama işleçlerine sahip olarak değerlendirir ve bu da bu işleçlerin varsayılan uygulamalarının otomatik olarak oluşturulmasını engeller. Böyle bir sınıf bir birleşimin (veya bir sınıfın içindeki anonim bir birleşimin) üyesi olduğunda, birleşimin (veya anonim birleşimi içeren sınıfın) kopyalama/taşıma oluşturucuları ve kopyalama/taşıma atama işleçleri örtük olarak silinmiş olarak tanımlanır. Açıkça tanımlanmadan birleşim (veya anonim birleşimi içeren sınıf) oluşturma veya kopyalama girişimi bir hatadır ve derleyici sonuç olarak derleyici hatası C2280'i oluşturur.error C2280: 'B::B(const B &)': attempting to reference a deleted function
Örnek (önce)
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
Örnek (sonra)
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
Statik üye işlevleri cv niteleyicilerini desteklemez.
Visual Studio 2015'in önceki sürümleri, statik üye işlevlerinin cv niteleyicilerine sahip olmasını sağladı. Bu davranış, Visual Studio 2015 ve Visual Studio 2015 Güncelleştirme 1'deki bir regresyondan kaynaklanır; Visual Studio 2013 ve derleyicinin önceki sürümleri bu şekilde yazılmış kodu reddeder. Visual Studio 2015 ve Visual Studio 2015 Güncelleştirme 1'in davranışı yanlıştır ve C++ standardına uygun değildir. Visual Studio 2015 Güncelleştirme 2 bu şekilde yazılmış kodu reddeder ve bunun yerine derleyici hatası C2511'i döndürür.
error C2511: 'void A::func(void) const': overloaded member function not found in 'A'
Örnek (önce)
struct A { static void func(); }; void A::func() const {} // C2511
Örnek(sonra)
struct A { static void func(); }; void A::func() {} // removed const
WinRT kodunda sabit listesinin ileriye doğru bildirimine izin verilmez (yalnızca etkiler
/ZW
)Windows Çalışma Zamanı (WinRT) için derlenen kod, derleyici anahtarı kullanılarak .Net Framework için yönetilen C++ kodu derlendiğinde olduğu gibi türlerin iletilmesine
/clr
izinenum
vermez. Bu davranış, bir sabit listesi boyutunun her zaman bilinmesini ve WinRT tür sistemine doğru şekilde yansıtılabilmesini sağlar. Derleyici bu şekilde yazılmış kodu reddeder ve derleyici hatası C3197 ile birlikte C2599 derleyici hatası döndürür.error C2599: 'CustomEnum': the forward declaration of a WinRT enum is not allowed
error C3197: 'public': can only be used in definitions
Örnek (önce)
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; } };
Örnek (sonra)
// forward declaration of CustomEnum removed namespace A { public enum class CustomEnum : int32 { Value1 }; } public ref class Component sealed { public: CustomEnum f() { return CustomEnum::Value1; } };
Aşırı yüklenmiş üye olmayan işleç yeni ve işleç silme satır içinde bildirilemez (Düzey 1 (
/W1
) varsayılan olarak)Üye olmayan işleç yeni ve işleç silme işlevleri satır içinde bildirildiğinde derleyicinin önceki sürümleri uyarı vermez. Bu şekilde yazılan kod hatalı biçimlendirilmiş (tanılama gerekmez) ve eşleşmeyen yeni ve silme işleçlerinden kaynaklanan bellek sorunlarına neden olabilir (özellikle büyük boyutlu serbest bırakma ile birlikte kullanıldığında) tanılaması zor olabilir. Derleyici artık bu şekilde yazılmış kodu tanımlamaya yardımcı olmak için derleyici uyarısı C4595'i oluşturur.
warning C4595: 'operator new': non-member operator new or delete functions may not be declared inline
Örnek (önce)
inline void* operator new(size_t sz) // warning C4595 { ... }
Örnek (sonra)
void* operator new(size_t sz) // removed inline { ... }
Bu şekilde yazılan kodun düzeltilmesi, işleç tanımlarının bir üst bilgi dosyasından ve ilgili kaynak dosyaya taşınmasını gerektirebilir.
Güncelleştirme 3'te Uyumluluk Geliştirmeleri
std::is_convertable artık kendi kendine atamayı algılar (standart kitaplık)
Tür özelliğinin
std::is_convertable
önceki sürümleri, kopya oluşturucu silindiğinde veya özel olduğunda sınıf türünün kendi kendine atandığını doğru algılamadı. Şimdi,std::is_convertable<>::value
silinmiş veya özel kopya oluşturucu ile bir sınıf türüne uygulandığında doğru olarak ayarlanmıştırfalse
.Bu değişiklikle ilişkilendirilmiş derleyici tanılaması yok.
Örnek
#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");
Derleyicinin önceki sürümlerinde, bu örneğin en altındaki statik onaylar hatalı olarak olarak ayarlandığından
true
geçerstd::is_convertable<>::value
. Şimdi,std::is_convertable<>::value
statik onayların başarısız olmasına neden olarak doğru olarak olarak ayarlanmıştırfalse
.Varsayılan veya silinmiş önemsiz kopyalama ve taşıma oluşturucuları erişim tanımlayıcılarını dikkate alır
Derleyicinin önceki sürümleri, çağrılmalarına izin vermeden önce varsayılan veya silinmiş önemsiz kopyanın erişim tanımlayıcısını denetlemedi ve oluşturucuları taşımadı. Bu eski davranış yanlıştı ve C++ standardına uymuyor. Bazı durumlarda, bu eski davranış sessiz hatalı kod oluşturma riski oluşturarak öngörülemeyen çalışma zamanı davranışına neden oldu. Derleyici artık varsayılan veya silinmiş önemsiz kopyanın erişim tanımlayıcısını denetler ve oluşturucuları taşıyıp çağrılamayacağını belirler ve çağrılmadıysa, sonuç olarak derleyici uyarısı C2248'i gönderir.
error C2248: 'S::S' cannot access private member declared in class 'S'
Örnek (önce)
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 }
Örnek (sonra)
class S { public: S() = default; private: S(const S&) = default; }; void f(const S&); // pass S by reference int main() { S s; f(s); }
Öznitelikli ATL kod desteğinin kullanımdan kaldırılması (Düzey 1 (
/W1
) varsayılan olarak)Derleyicinin önceki sürümleri öznitelikli ATL kodunu destekliyor. Visual Studio 2008'de başlayan öznitelikli ATL kodu desteğini kaldırmanın sonraki aşaması olarak, atfedilen ATL kodu kullanım dışı bırakılmıştır. Derleyici artık bu tür kullanım dışı kodu tanımlamaya yardımcı olmak için derleyici uyarısı C4467'yi çıkartır.
warning C4467: Usage of ATL attributes is deprecated
Destek derleyiciden kaldırılana kadar öznitelikli ATL kodunu kullanmaya devam etmek istiyorsanız, derleyiciye veya
/wd:4467
komut satırı bağımsız değişkenlerini geçirerek/Wv:18
veya kaynak kodunuzu ekleyerek#pragma warning(disable:4467)
bu uyarıyı devre dışı bırakabilirsiniz.Örnek 1 (önce)
[uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")] class A {};
Örnek 1 (sonra)
__declspec(uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")) A {};
Bazen aşağıdaki örnek kodda olduğu gibi kullanım dışı ATL özniteliklerini kullanmaktan kaçınmak için bir IDL dosyası oluşturmanız gerekebilir veya bu dosyayı oluşturmak isteyebilirsiniz
Örnek 2 (önce)
[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 { // ... };
İlk olarak *.idl dosyasını oluşturun; vc140.idl tarafından oluşturulan dosya, arabirimleri ve ek açıklamaları içeren bir *.idl dosyası almak için kullanılabilir.
Ardından, C++ arabirim tanımlarının oluşturulduğundan emin olmak için derlemenize bir MIDL adımı ekleyin.
Örnek 2 IDL (sonra)
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; }; }
Ardından, aşağıdaki örnek kodda olduğu gibi doğrudan uygulama dosyasında ATL kullanın.
Örnek 2 Uygulama (sonra)
#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() };
Önceden derlenmiş üst bilgi (PCH) dosyaları ve eşleşmeyen #include yönergeleri (yalnızca etkiler
/Wall
/WX
)Derleyicinin önceki sürümleri, önceden derlenmiş
#include
üst bilgi (PCH) dosyaları kullanılırken ve-Yu
derlemeleri arasında-Yc
kaynak dosyalarda eşleşmeyen yönergeleri kabul etti. Bu şekilde yazılan kod artık derleyici tarafından kabul edilir. Derleyici artık PCH dosyalarını kullanırken eşleşmeyen#include
yönergeleri tanımlamaya yardımcı olmak için CC4598 derleyici uyarısı verdi.warning C4598: 'b.h': included header file specified for Ycc.h at position 2 does not match Yuc.h at that position
Örnek (önce):
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"
Örnek (sonra)
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"
Önceden derlenmiş üst bilgi (PCH) dosyaları ve eşleşmeyen ekleme dizinleri (yalnızca etkiler
/Wall
/WX
)Derleyicinin kabul edilen eşleşmeyen önceki sürümleri, önceden derlenmiş üst bilgi (PCH) dosyaları kullanılırken ve
-Yu
derlemeleri arasında-Yc
derleyiciye yönelik dizin (-I
) komut satırı bağımsız değişkenlerini içerir. Bu şekilde yazılan kod artık derleyici tarafından kabul edilir. Derleyici artık PCH dosyalarını kullanırken eşleşmeyen include directory (-I
) komut satırı bağımsız değişkenlerini tanımlamaya yardımcı olmak için derleyici uyarısı CC4599'u çalıştırıyor.warning C4599: '-I..' : specified for Ycc.h at position 1 does not match Yuc.h at that position
Örnek (önce)
cl /c /Wall /Ycc.h -I.. X.cpp cl /c /Wall /Yuc.h Z.cpp
Örnek (sonra)
cl /c /Wall /Ycc.h -I.. X.cpp cl /c /Wall /Yuc.h -I.. Z.cpp
Visual Studio 2013 Uyumluluk Değişiklikleri
Derleyici
Son anahtar sözcük artık daha önce derlenmiş olduğu çözümlenmemiş bir simge hatası oluşturur:
struct S1 { virtual void f() = 0; }; struct S2 final : public S1 { virtual void f(); }; int main(S2 *p) { p->f(); }
Önceki sürümlerde, çağrı bir
virtual
çağrı olduğundan bir hata verilmedi; yine de program çalışma zamanında kilitleniyordu. Artık, sınıfın son olduğu bilindiğinden bir bağlayıcı hatası verilmektedir. Bu örnekte, hatayı düzeltmek için tanımınıS2::f
içeren obj ile bağlantı oluşturursunuz.Ad alanları içinde arkadaş işlevlerini kullandığınızda, başvurmadan önce friend işlevini yeniden oluşturmanız gerekir, aksi takdirde derleyici artık ISO C++ Standardına uygun olduğundan bir hata alırsınız. Örneğin, bu örnek artık derlenmez:
namespace NS { class C { void func(int); friend void func(C* const) {} }; void C::func(int) { NS::func(this); // error } }
Bu kodu düzeltmek için işlevini bildirin
friend
: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, bir sınıfta açık özelleştirmeye izin vermez. Microsoft C++ derleyicisi bazı durumlarda buna izin veriyor olsa da, aşağıdaki örnek gibi durumlarda derleyici ikinci işlevi ilkinin uzmanlığı olarak değerlendirmediğinden bir hata oluşturulur.
template < int N> class S { public: template void f(T& val); template < > void f(char val); }; template class S< 1>;
Bu kodu düzeltmek için ikinci işlevi değiştirin:
template <> void f(char& val);
Derleyici artık aşağıdaki örnekteki iki işlevi birbirinden ayırmaya çalışmıyor ve şimdi bir hata yayıyor:
template< typename T> void Func(T* t = nullptr); template< typename T> void Func(...); int main() { Func< int>(); // error }
Bu kodu düzeltmek için çağrıyı netleştirin:
template< typename T> void Func(T* t = nullptr); template< typename T> void Func(...); int main() { Func< int>(nullptr); // ok }
Derleyici ISO C++11'e uymadan önce aşağıdaki kod derlenmiş ve türüne
int
çözümlenmesine neden olacaktıx
:auto x = {0}; int y = x;
Bu kod artık türüne
std::initializer_list<int>
çözümlenipx
bir sonraki satırda türüneint
atamayax
çalışan bir hataya neden olur. (Varsayılan olarak dönüştürme yoktur.) Bu koduint
düzeltmek için öğesini kullanarak değiştirinauto
:int x = {0}; int y = x;
Sağ taraftaki değerin türü başlatılmakta olan soldaki değerin türüyle eşleşmediğinde toplu başlatmaya artık izin verilmez ve ISO C++11 Standardı, dönüştürmeleri daraltmadan çalışmak için tekdüzen başlatma gerektirdiğinden bir hata verilir. Daha önce, bir daraltma dönüştürmesi varsa, hata yerine derleyici uyarısı (düzey 4) C4242 uyarısı verilmişti.
int i = 0; char c = {i}; // error
Bu kodu düzeltmek için açık bir daraltma dönüşümü ekleyin:
int i = 0; char c = {static_cast<char>(i)};
Aşağıdaki başlatmaya artık izin verilmiyor:
void *p = {{0}};
Bu kodu düzeltmek için şu formlardan birini kullanın:
void *p = 0; // or void *p = {0};
Ad araması değişti. Aşağıdaki kod, Visual Studio 2012 ve Visual Studio 2013'teki C++ derleyicisinde farklı şekilde çözümlenir:
enum class E1 { a }; enum class E2 { b }; int main() { typedef E2 E1; E1::b; }
Visual Studio 2012'de in ifadesi
E1::b
genelE1
kapsamda çözümlendi::E1
. Visual Studio 2013'te,E1
ifadeE1::b
içindeki tanımımain()
çözümlertypedef E2
ve türüne::E2
sahiptir.Nesne düzeni değişti. x64 üzerinde, bir sınıfın nesne düzeni önceki sürümlere göre değişebilmektedir. İşlevi
virtual
varsa ancak işlevi olanvirtual
bir temel sınıfı yoksa, derleyicinin nesne modeli veri üyesi düzeninden sonra işlev tablosuna birvirtual
işaretçi ekler. Başka bir deyişle, ilgili düzen her durumda en uygun düzen olmayabilir. Önceki sürümlerde, x64 için bir iyileştirme sizin için düzeni geliştirmeye çalışacaktı, ancak karmaşık kod durumlarında düzgün çalışmadığından, Visual Studio 2013'te kaldırıldı. Örneğin, aşağıdaki kodu düşünün:__declspec(align(16)) struct S1 { }; struct S2 { virtual ~S2(); void *p; S1 s; };
Visual Studio 2013'te x64'ün sonucu
sizeof(S2)
48'dir, ancak önceki sürümlerde 32 olarak değerlendirilir. Bunun x64 için Visual Studio 2013 C++ derleyicisinde 32 olarak değerlendirilmesini sağlamak için, işlevi olan sahte birvirtual
temel sınıf ekleyin:__declspec(align(16)) struct S1 { }; struct dummy { virtual ~dummy() {} }; struct S2 : public dummy { virtual ~S2(); void *p; S1 s; };
Kodunuzda önceki bir sürümün iyileştirmeye çalışacağı yerleri bulmak için, derleyici seçeneğiyle
/W3
birlikte bu sürümden bir derleyici kullanın ve uyarı C4370'i açın. Örneğin:#pragma warning(default:4370) __declspec(align(16)) struct S1 { }; struct S2 { virtual ~S2(); void *p; S1 s; };
Visual Studio 2013'ten önce bu kod şu iletiyi döndürür: "uyarı C4370: 'S2' : sınıfın düzeni daha iyi paketleme nedeniyle derleyicinin önceki bir sürümünden değiştirildi".
x86 derleyicisi, derleyicinin tüm sürümlerinde aynı alt çalışma düzeni sorununa sahiptir. Örneğin, bu kod x86 için derlenirse:
struct S { virtual ~S(); int i; double d; };
sonucu
sizeof(S)
24'tür. Ancak, x64 için belirtilen geçici çözümü kullanırsanız 16'ya düşürülebilir:struct dummy { virtual ~dummy() {} }; struct S : public dummy { virtual ~S(); int i; double d; };
Standart Kitaplık
Visual Studio 2013'teki C++ derleyicisi, Visual Studio 2010'da uygulanan _ITERATOR_DEBUG_LEVEL ve RuntimeLibrary uyuşmazlıklarını algılar. Derleyici seçenekleri /MT
(statik sürüm), (statik hata ayıklama), /MTd
(dinamik sürüm) /MD
ve /MDd
(dinamik hata ayıklama) karıştırıldığında bu uyuşmazlıklar oluşur.
Kodunuz önceki sürümün sanal diğer ad şablonlarını kabul ederse, bunu değiştirmeniz gerekir. Örneğin, yerine
allocator_traits<A>::rebind_alloc<U>::other
şimdi de diyebilirsinizallocator_traits<A>::rebind_alloc<U>
. Artık gerekli olmasaratio_add<R1, R2>::type
da ve şimdi de kullanmanızıratio_add<R1, R2>
öneririz, çünküratio<N, D>
azaltılmış bir oran için bir "tür" tür tanımına sahip olması gerektiğinden, bu zaten azaltılmışsa aynı tür olacaktır.veya
std::max()
öğesini çağırırkenstd::min()
kullanmanız#include <algorithm>
gerekir.Mevcut kodunuz önceki sürümün sanal kapsamlı sabit listelerini (ad alanlarına sarmalanmış geleneksel kapsamsız sabit listeleri) kullanıyorsa, bunu değiştirmeniz gerekir. Örneğin, türüne
std::future_status::future_status
başvuruda bulunduysanız, şimdi de de diyebilirsinizstd::future_status
. Ancak, çoğu kod etkilenmez; örneğin,std::future_status::ready
hala derlenmektedir.explicit operator bool()
unspecified-bool-type() işlecinden daha katıdır.explicit operator bool()
bool'a açık dönüştürmelere (örneğin, hemshared_ptr<X> sp
hem debool b(sp)
static_cast<bool>(sp)
geçerli) ve Boole tarafından test edilebilir bool'a "bağlamsal dönüştürmeler" (örneğin,if (sp)
,!sp
,sp &&
vb.) izin verir. Ancak,explicit operator bool()
bool'a örtük dönüştürmeleri yasaklar, bu nedenle bir bool dönüş türü belirtemezbool b = sp;
ve veremezsiniz, diyeemezsinizreturn sp
.Artık gerçek variadic şablonlar uygulandığına göre, _VARIADIC_MAX ve ilgili makroların hiçbir etkisi yoktur. _VARIADIC_MAX tanımlamaya devam ediyorsanız, yoksayılır. Benzetilmiş değişen sayıda bağımsız değişken içeren şablonları farklı bir şekilde desteklemeye yönelik makro makinemizi kabul ettiyseniz, kodunuzu değiştirmeniz gerekir.
Normal anahtar sözcüklere ek olarak, C++ Standart Kitaplığı üst bilgileri artık bağlama duyarlı anahtar sözcüklerin geçersiz kılınıp sonlandırılmasını yasaklar.
reference_wrapper
,ref()
vecref()
şimdi geçici nesnelere bağlamayı yasaklar.<random>
şimdi derleme zamanı önkoşullarını kesinlikle zorunlu tutar.Çeşitli C++ Standart Kitaplık türü özellikleri "T tam bir tür olmalıdır" ön koşuluna sahiptir. Derleyici artık bu önkoşulu daha katı bir şekilde zorlasa da, her durumda zorlamayabilir. (C++ Standart Kitaplığı önkoşul ihlalleri tanımsız davranış tetiklediğinden, Standart zorlamayı garanti etmez.)
C++ Standart Kitaplığı'nı desteklemez
/clr:oldSyntax
.için
common_type<>
C++11 belirtiminin beklenmeyen ve istenmeyen sonuçları vardı; özellikle decommon_type<int, int>::type
döndürürint&&
. Bu nedenle, derleyici Kitaplık Çalışma Grubu için Önerilen Çözüm sorununu 2141 uygular ve bucommon_type<int, int="">::type
da döndürürint
.Bu değişikliğin yan etkisi olarak, kimlik olayı artık çalışmaz (
common_type<T>
her zaman türüyleT
sonuçlanır). Bu davranış Önerilen Çözüm'e uygundur, ancak önceki davranışa bağlı olan tüm kodları bozar.Kimlik türü özelliğine ihtiyacınız varsa, içinde tanımlanan
<type_traits>
standartstd::identity
olmayan özelliği kullanmayın çünkü için<void>
çalışmaz. Bunun yerine, gereksinimlerinize uyan kendi kimlik türü ayırt edici niteliğini uygulayın. Bir örnek aşağıda verilmiştir:template < typename T> struct Identity { typedef T type; };
MFC ve ATL
Yalnızca Visual Studio 2013: Unicode çok popüler olduğundan ve MBCS kullanımı önemli ölçüde azaldığından MFC MBCS Kitaplığı Visual Studio'ya dahil değildir. Yeni denetimlerin ve iletilerin çoğu salt Unicode olduğundan, bu değişiklik aynı zamanda MFC'yi Windows SDK ile daha paralel halde tutar. Ancak, MFC MBCS kitaplığını kullanmaya devam etmeniz gerekiyorsa, Visual Studio 2013 için Çok Baytlı MFC Kitaplığı'ndaki Microsoft İndirme Merkezi'nden indirebilirsiniz. Visual C++ Yeniden Dağıtılabilir Paketi'nde bu kitaplık halen yer almaktadır. (Not: MBCS DLL,Visual Studio 2015 ve sonraki sürümlerde C++ kurulum bileşenlerine dahildir).
MFC şeridinin erişilebilirliği değiştirildi. Tek düzeyli mimari yerine artık hiyerarşik bir mimari vardır. çağrısı
CRibbonBar::EnableSingleLevelAccessibilityMode()
yaparak eski davranışı kullanmaya devam edebilirsiniz.CDatabase::GetConnect
yöntemi kaldırılır. Güvenliği geliştirmek için bağlantı dizesi artık şifrelenmiş olarak depolanır ve şifresi yalnızca gerektiğinde çözülür; düz metin olarak döndürülemez. Dize yöntemi kullanılarakCDatabase::Dump
elde edilebilir.İmzası
CWnd::OnPowerBroadcast
değiştirildi. Bu ileti işleyicisinin imzası ikinci parametre olarak bir LPARAM alacak şekilde değiştirilir.İmzalar, ileti işleyicilerini barındıracak şekilde değiştirilir. Aşağıdaki işlevlerin parametre listeleri yeni eklenen ON_WM_* ileti işleyicilerini kullanacak şekilde değiştirilmiştir:
CWnd::OnDisplayChange
yeni ON_WM_DISPLAYCHANGE makronun ileti eşlemesinde kullanılabilmesi için (WPARAM, LPARAM) yerine (UINT, int, int) olarak değiştirildi.CFrameWnd::OnDDEInitiate
yeni ON_WM_DDE_INITIATE makronun ileti eşlemesinde kullanılabilmesi için (WPARAM, LPARAM) yerine (CWnd*, UINT, UNIT) olarak değiştirildi.CFrameWnd::OnDDEExecute
yeni ON_WM_DDE_EXECUTE makronun ileti eşlemesinde kullanılabilmesi için yerine (WPARAM, LPARAM) yerine (CWnd*, HANDLE) olarak değiştirildi.CFrameWnd::OnDDETerminate
yeni ON_WM_DDE_TERMINATE makronun ileti eşlemesinde kullanılabilmesi için parametresi yerine (WPARAM, LPARAM) parametresi olarak (CWnd*) olarak değiştirildi.CMFCMaskedEdit::OnCut
yeni ON_WM_CUT makronun ileti eşlemesinde kullanılabilmesi için (WPARAM, LPARAM) yerine parametre yok olarak değiştirildi.CMFCMaskedEdit::OnClear
yeni ON_WM_CLEAR makronun ileti eşlemesinde kullanılabilmesi için (WPARAM, LPARAM) yerine parametre yok olarak değiştirildi.CMFCMaskedEdit::OnPaste
yeni ON_WM_PASTE makronun ileti eşlemesinde kullanılabilmesi için (WPARAM, LPARAM) yerine parametre yok olarak değiştirildi.
#ifdef
MFC üst bilgi dosyalarındaki yönergeler kaldırılır. Desteklenmeyen Windows (WINVER < 0x0501
) sürümleriyle ilgili MFC üst bilgi dosyalarındaki çok sayıda#ifdef
yönerge kaldırılır.ATL DLL (atl120.dll) kaldırılır. ATL artık, üst bilgiler ve statik kitaplık (atls.lib) olarak sağlanmaktadır.
Atlsd.lib, atlsn.lib ve atlsnd.lib kaldırılır. Atls.lib artık, karakter kümesi bağımlılıkları veya hata ayıklamaya/yayınlamaya özgü kod içermez. Unicode/ANSI ve hata ayıklama/yayınlama için aynı çalıştığından, kitaplığın yalnızca tek bir sürümü gereklidir.
ATL/MFC İzleme aracı ATL DLL ile birlikte kaldırılır ve izleme mekanizması basitleştirilmiştir. Oluşturucu
CTraceCategory
artık bir parametre (kategori adı) alır ve TRACE makroları CRT hata ayıklama raporlama işlevlerini çağırır.
Visual Studio 2012'de Önemli Değişiklikler
Derleyici
/Yl
Derleyici seçeneği değişti. Varsayılan olarak, derleyici belirli koşullar altında LNK2011 hatalara neden olabilecek bu seçeneği kullanır. Daha fazla bilgi için bkz . /Yl (Hata Ayıklama Kitaplığı için PCH Başvurusu Ekle).kullanılarak
/clr
enum
derlenen kodda, sınıf anahtar sözcüğü ortak dil çalışma zamanı (CLR) sabit listesi değil C++11 sabit listesi tanımlar. BIR CLR sabit listesi tanımlamak için erişilebilirliği konusunda açık olmanız gerekir.Bağımlı bir adı açıkça belirlemek için şablon anahtar sözcüğünü kullanın (C++ Dil Standardı uyumluluğu). Aşağıdaki örnekte, belirsizliği çözmek için vurgulanan şablon anahtar sözcüğü zorunludur. Daha fazla bilgi için bkz . Bağımlı Türler için Ad Çözümlemesi.
template < typename X = "", typename = "" AY = ""> struct Container { typedef typename AY::template Rebind< X> ::Other AX; };
Aşağıdaki örnekte gösterildiği gibi, float türünde sabit ifadeye artık şablon bağımsız değişkeni olarak izin verilmiyor.
template<float n=3.14> struct B {}; // error C2993: 'float': illegal type for non-type template parameter 'n'
Komut satırı seçeneği kullanılarak
/GS
derlenen ve bire bir güvenlik açığı olan kod, aşağıdaki sahte kod örneğinde gösterildiği gibi çalışma zamanında işleme sonlandırmaya yol açabilir.char buf[MAX]; int cch; ManipulateString(buf, &cch); // ... buf[cch] = '\0'; // if cch >= MAX, process will terminate
x86 derlemeleri için varsayılan mimari SSE2 olarak değiştirilir; bu nedenle, derleyici SSE yönergelerini yayabilir ve kayan nokta hesaplamaları yapmak için XMM yazmaçlarını kullanır. Önceki davranışa geri dönmek istiyorsanız, mimariyi
/arch:IA32
IA32 olarak belirtmek için derleyici bayrağını kullanın.Derleyici, daha önce olmadığı durumlarda Derleyici Uyarısı (düzey 4) C4703 ve C4701 uyarılarını verebilir. Derleyici, işaretçi türündeki başlatılmamış yerel değişkenlerin kullanımı için daha güçlü denetimler uygular.
Yeni bağlayıcı bayrağı
/HIGHENTROPYVA
belirtildiğinde, Windows 8 genellikle bellek ayırmalarının 64 bit adres döndürmesine neden olur. (Windows 8'den önce, bu ayırmalar genellikle 2 GB'tan az olan adresleri döndürür.) Bu değişiklik, var olan kodda işaretçi kesme hatalarını kullanıma sunabilir. Varsayılan olarak, bu anahtar açıktır. Bu davranışı devre dışı bırakmak için belirtin/HIGHENTROPYVA:NO
.Yönetilen derleyici (Visual Basic/C#) yönetilen derlemeler için de destekler
/HIGHENTROPYVA
. Ancak, bu durumda,/HIGHENTROPYVAswitch
varsayılan olarak kapalıdır.
IDE
- C++/CLI'da Windows Forms uygulamaları oluşturmamanızı önersek de, mevcut C++/CLI UI uygulamalarının bakımı desteklenir. Bir Windows Forms uygulaması veya başka bir .NET UI uygulaması oluşturmanız gerekiyorsa C# veya Visual Basic kullanın. Yalnızca birlikte çalışabilirlik amacıyla C++/CLI kullanın.
Paralel Desenler Kitaplığı ve Eşzamanlılık Çalışma Zamanı Kitaplığı
SchedulerType
UmsThreadDefault
numaralandırması kullanım dışı bırakıldı. belirtimi UmsThreadDefault
kullanım dışı bırakılmış bir uyarı üretir ve dahili olarak ile eşlenir ThreadScheduler
.
Standart Kitaplık
C++98/03 ve C++11 standartları arasındaki hataya neden olan bir değişikliğin ardından, çağrıda
make_pair()
olduğu gibimake_pair<int, int>(x, y)
açık şablon bağımsız değişkenleri kullanılır ve genellikle Visual Studio 2012'deki Visual C++ içinde derlenemez. Çözüm, içinde olduğu gibi açık şablon bağımsız değişkenleri olmadan her zaman çağırmaktırmake_pair()
make_pair(x, y)
. Açık şablon bağımsız değişkenleri sağlamak işlevin amacını yener. Sonuçta elde edilen tür üzerinde tam denetime ihtiyacınız varsa, yerine — öğesini kullanınpair
make_pair
pair<short, short>(int1, int2)
.C++98/03 ve C++11 standartları arasında başka bir hataya neden olan değişiklik: A örtük olarak B'ye dönüştürülebilirse ve B örtük olarak C'ye dönüştürülebilirse, ancak A örtük olarak C'ye dönüştürülemezse, C++98/03 ve Visual Studio 2010'un 'a
pair<C, X>
dönüştürülebilir olmasına izin verilirpair<A, X>
(örtük veya açıkça). (Diğer X türü burada ilgi çekici değildir ve çiftteki ilk türe özgü değildir.) Visual Studio 2012'deki C++ derleyicisi, A'nın örtük olarak C'ye dönüştürülemez olduğunu algılar ve çift dönüştürmeyi aşırı yükleme çözümlemesinden kaldırır. Bu değişiklik birçok senaryo için olumludur. Örneğin, ve aşırı yüklemefunc(const pair<int, int>&)
vefunc(const pair<string, string>&)
ilepair<const char *, const char *>
çağrısıfunc()
bu değişiklikle derlenir. Ancak bu değişiklik, agresif çift dönüştürmelerine dayalı kodu bozar. Bu tür kodlar genellikle dönüştürmenin bir bölümü açıkça gerçekleştirilerek düzeltilebilir; örneğin, öğesini bekleyenpair<C, X>
bir işleve geçirilerekmake_pair(static_cast<B>(a), x)
.Visual Studio 2010,
make_shared<T>(arg1, arg2, argN)
önişlemci makinelerle aşırı yüklemeleri ve özelleştirmeleri damgalayarak 10 bağımsız değişken sınırına kadar sanal variadic şablonlarıdır. Visual Studio 2012'de bu sınır, kullanıcıların çoğunluğu için derleme sürelerini ve derleyici bellek tüketimini iyileştirmek için beş bağımsız değişkene indirgenir. Ancak, _VARIADIC_MAX proje genelinde açıkça 10 olarak tanımlayarak önceki sınırı ayarlayabilirsiniz.C++11 17.6.4.3.1 [macro.names]/2, C++ Standart Kitaplığı üst bilgileri eklendiğinde anahtar sözcüklerin makroyla değiştirilmesini yasaklar. Üst bilgiler artık makroyla değiştirilen anahtar sözcükleri algılarsa derleyici hataları yayar. (_ALLOW_KEYWORD_MACROS tanımlama, bu tür kodların derlenabilmesine izin verir, ancak bu kullanımı kesinlikle önerilmez.) Özel durum olarak, üst bilgiler kullanarak/
#pragma pop_macro("new")
#pragma push_macro("new")
#undef new
/ kendilerini kapsamlı bir şekilde savunduğu için makro biçiminenew
varsayılan olarak izin verilir. _ENFORCE_BAN_OF_MACRO_NEW tanımlamak tam olarak adının ima ettiği şeyi yapar.C++ Standart Kitaplığı uygulaması, çeşitli iyileştirmeler ve hata ayıklama denetimleri uygulamak için Visual Studio sürümleri (2005, 2008, 2010, 2012) arasında ikili uyumluluğu kasıtlı olarak bozar. C++ Standart Kitaplığı kullanıldığında, farklı sürümler kullanılarak tek bir ikili dosyaya (EXE veya DLL) derlenen nesne dosyalarının ve statik kitaplıkların karıştırılması ve C++ Standart Kitaplığı nesnelerinin farklı sürümler kullanılarak derlenen ikili dosyalar arasında geçirilmesini yasaklar. Nesne dosyalarının ve statik kitaplıkların (Visual Studio 2012'de C++ derleyicisi kullanılarak derlenenlerle Visual Studio 2010 kullanılarak derlenen C++ Standart Kitaplığı kullanılarak) karıştırılması, _MSC_VER derleyicinin ana sürümünü (Visual Studio 2012'de Visual C++ için 1700) içeren makro olduğu _MSC_VER uyuşmazlığı hakkında bağlayıcı hataları gösterir. Bu denetim DLL karıştırmasını algılayamaz ve Visual Studio 2008 veya önceki sürümleri içeren karıştırmayı algılayamaz.
Visual Studio 2010'da uygulanan _ITERATOR_DEBUG_LEVEL uyuşmazlıklarını algılamaya ek olarak, Visual Studio 2012'deki C++ derleyicisi Çalışma Zamanı Kitaplığı uyuşmazlıklarını algılar. Derleyici seçenekleri
/MT
(statik sürüm), (statik hata ayıklama),/MTd
(dinamik sürüm)/MD
ve/MDd
(dinamik hata ayıklama) karıştırıldığında bu uyuşmazlıklar oluşur.operator<()
,operator>()
,operator<=()
veoperator>=()
daha önce vestdext::hash_map
kapsayıcı aileleri içinstd::unordered_map
kullanılabilirdi, ancak uygulamaları yararlı değildi. Standart olmayan bu işleçler Visual Studio 2012'deki Visual C++ uygulamasından kaldırılmıştır. Buna ek olarak,operator==()
operator!=()
ve uygulamasınınstd::unordered_map
aileyi kapsayacakstdext::hash_map
şekilde genişletildi. (Yeni kodda ailenin kullanımındanstdext::hash_map
kaçınmanızı öneririz.)C++11 22.4.1.4 [locale.codecvt] bunu
codecvt::length()
belirtir vecodecvt::do_length()
değiştirilebilirstateT&
parametreler almalıdır, ancak Visual Studio 2010 aldıconst stateT&
. Visual Studio 2012'deki C++ derleyicisi, standart tarafından zorunlu kılındığı şekilde alınırstateT&
. Bu fark, sanal işlevinido_length()
geçersiz kılmaya çalışan herkes için önemlidir.
CRT
new ve malloc() için kullanılan C Çalışma Zamanı (CRT) yığını artık özel değildir. CRT artık işlem yığınını kullanır. Bu, bir DLL kaldırıldığında yığının yok edilmediği anlamına gelir, bu nedenle CRT'ye statik olarak bağlanan DLL'ler, DLL kodu tarafından ayrılan belleğin kaldırılmadan önce temizlendiğinden emin olmalıdır.
iscsymf()
işlevi negatif değerlerle onaylar.Yapı
threadlocaleinfostruct
, yerel ayar işlevlerindeki değişikliklere uyum sağlamak için değişti.gibi
memxxx()
strxxx()
karşılık gelen iç öğelere sahip CRT işlevleri intrin.h dosyasından kaldırılır. Yalnızca bu işlevler için intrin.h dosyasını eklediyseniz, ilgili CRT üst bilgilerini eklemeniz gerekir.
MFC ve ATL
Fusion desteği kaldırıldı (afxcomctl32.h); bu nedenle, içinde
<afxcomctl32.h>
tanımlanan tüm yöntemler kaldırılmıştır. Üst bilgi dosyaları<afxcomctl32.h>
ve<afxcomctl32.inl>
silinmiş.öğesinin adı
CDockablePane::RemoveFromDefaultPaneDividier
olarakCDockablePane::RemoveFromDefaultPaneDivider
değiştirildi.imzası
CFileDialog::SetDefExt
LPCTSTR kullanacak şekilde değiştirildi; bu nedenle Unicode derlemeleri etkilenir.Eski ATL izleme kategorileri kaldırıldı.
öğesinin imzası
CBasePane::MoveWindow
bir alacak şekildeconst CRect
değiştirildi.öğesinin imzası
CMFCEditBrowseCtrl::EnableBrowseButton
değiştirildi.CMFCBaseTabCtrl
içindenm_fntTabs
vem_fntTabsBold
kaldırıldı.Oluşturuculara
CMFCRibbonStatusBarPane
bir parametre eklendi. (Varsayılan bir parametredir ve bu nedenle kaynak kesme değildir.)Oluşturucuya
CMFCRibbonCommandsListBox
bir parametre eklendi. (Varsayılan bir parametredir ve bu nedenle kaynak kesme değildir.)AFXTrackMouse
API (ve ilgili zamanlayıcı proc) kaldırıldı. Bunun yerine Win32TrackMouseEvent
API'sini kullanın.Oluşturucuya
CFolderPickerDialog
bir parametre eklendi. (Varsayılan bir parametredir ve bu nedenle kaynak kesme değildir.)CFileStatus
yapı boyutu değiştirildi: Üyem_attribute
BYTE'den DWORD'ye (öğesindenGetFileAttributes
döndürülen değerle eşleşecek şekilde) değiştirildi.CRichEditCtrl
veCRichEditView
Unicode derlemelerinde RICHEDIT_CLASS (RichEdit 3.0 denetimi) yerine MSFTEDIT_CLASS (RichEdit 4.1 denetimi) kullanın.Windows Vista, Windows 7 ve Windows 8'de her zaman DOĞRU olduğundan kaldırıldı
AFX_GLOBAL_DATA::IsWindowsThemingDrawParentBackground
.Windows Vista, Windows 7 ve Windows 8'de her zaman DOĞRU olduğundan kaldırıldı
AFX_GLOBAL_DATA::IsWindowsLayerSupportAvailable
.kaldırıldı
AFX_GLOBAL_DATA::DwmExtendFrameIntoClientArea
. Windows API'sini doğrudan Windows Vista, Windows 7 ve Windows 8'de çağır.kaldırıldı
AFX_GLOBAL_DATA::DwmDefWindowProc
. Windows API'sini doğrudan Windows Vista, Windows 7 ve Windows 8'de çağır.Ad çakışmasını ortadan kaldırmak için olarak yeniden adlandırıldı
AFX_GLOBAL_DATA::DwmIsCompositionEnabled
IsDwmCompositionEnabled
.Bir dizi MFC iç zamanlayıcısının tanımlayıcıları değiştirildi ve tanımları afxres.h (AFX_TIMER_ID_*) adresine taşıdı.
yöntemin
OnExitSizeMove
imzası, ON_WM_EXITSIZEMOVE makroyla anlaşacak şekilde değiştirildi:CFrameWndEx
CMDIFrameWndEx
CPaneFrameWnd
adı ve imzası
OnDWMCompositionChanged
, ON_WM_DWMCOMPOSITIONCHANGED makroyla anlaşacak şekilde değiştirildi:CFrameWndEx
CMDIFrameWndEx
CPaneFrameWnd
yöntemin
OnMouseLeave
imzası, ON_WM_MOUSELEAVE makroyla anlaşacak şekilde değiştirildi:CMFCCaptionBar
CMFCColorBar
CMFCHeaderCtrl
CMFCProperySheetListBox
CMFCRibbonBar
CMFCRibbonPanelMenuBar
CMFCRibbonRichEditCtrl
CMFCSpinButtonCtrl
CMFCToolBar
ReplaceThisTextCMFCToolBarComboBoxEdit
CMFCToolBarEditCtrl
CMFCAutoHideBar
ON_WM_POWERBROADCAST makrosunun imzasını
OnPowerBroadcast
kabul etmek için değiştirildi:CFrameWndEx
CMDIFrameWndEx
ON_WM_STYLECHANGED makrosunun imzasını
OnStyleChanged
kabul etmek için değiştirildi:CMFCListCtrl
CMFCStatusBar
İç yöntemi
FontFamalyProcFonts
olarakFontFamilyProcFonts
yeniden adlandırıldı.Bazı durumlarda bellek sızıntılarını (#defines ile değiştirilir) ve aşağıdaki sınıf üyesi değişkenlerini ortadan kaldırmak için çok sayıda genel statik
CString
nesne kaldırıldı: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
hızlandırıcı sınırlayıcısı parametresinin
CKeyboardManager::ShowAllAccelerators
imzası değiştirildi ve kaldırıldı.öğesi eklendi
CPropertyPage::GetParentSheet
ve sınıfınaCPropertyPage
öğesini çağırarakGetParent
doğru üst sayfa penceresini alın. Bu, üst sayfa veya üstCPropertyPage
öğe penceresi olabilir. yerine çağırmakGetParentSheet
GetParent
için kodunuzu değiştirmeniz gerekebilir.ATLBASE'de dengesiz #pragma uyarısı (gönderme) düzeltildi. H, uyarıların yanlış devre dışı bırakılmasına neden oldu. Bu uyarılar artık ATLBASE'den sonra doğru şekilde etkinleştirilmiştir. H ayrıştırıldı.
D2D ile ilgili yöntemler AFX_GLOBAL_DATA _AFX_D2D_STATE taşındı:
GetDirectD2dFactory
GetWriteFactory
GetWICFactory
InitD2D
ReleaseD2DRefs
IsD2DInitialized
D2D1MakeRotateMatrix
Örneğin,
afxGlobalData.IsD2DInitialized
çağrısı yerine öğesini çağırınAfxGetD2DState->IsD2DInitialized
.
Eski ATL* kaldırıldı. \atlmfc\include\ klasöründeki CPP dosyaları.
Gereksinimleri karşılamak
DLLMain
için başlatma CRT başlatma zamanı yerine isteğe bağlı olarak taşındıafxGlobalData
.RemoveButtonByIndex
yöntemi sınıfınaCMFCOutlookBarPane
eklendi.olarak düzeltildi
CMFCCmdUsageCount::IsFreqeuntlyUsedCmd
IsFrequentlyUsedCmd
.'nin
RestoreOriginalstate
birkaç örneği olarakRestoreOriginalState (CMFCToolBar, CMFCMenuBar, CMFCOutlookBarPane)
düzeltildi.Kullanılmayan yöntemler :
SetCaptionStyle
, ,IsDrawCaption
,IsHideDisabledButtons
GetRecentSiblingPaneInfo
veCanAdjustLayout
öğesindenCDockablePane
kaldırıldı.statik üye değişkenleri ve
m_bHideDisabledButtons
kaldırıldım_bCaptionText
CDockablePane
.öğesine
CMFCFontComboBox
bir geçersiz kılmaDeleteString
yöntemi eklendi.' den
CPane
kullanılmayan yöntemler kaldırıldı:GetMinLength
veIsLastPaneOnLastRow
.olarak
CPane::SetDockSiteRow
yeniden adlandırıldıCPane::GetDockSiteRow(CDockingPanesRow *)
.
Visual Studio 2010'da Önemli Değişiklikler
Derleyici
Anahtar
auto
sözcüğün yeni bir varsayılan anlamı vardır. Eski anlamın kullanımı nadir olduğundan çoğu uygulama bu değişiklikten etkilenmez.Kodunuzda bu ada göre bir tanımlayıcı varsa ad çakışmasına neden olacak yeni
static_assert
anahtar sözcük kullanıma sunulmuştur.Yeni lambda gösterimi desteği, IDL uuid özniteliğinde alıntılanmamış GUID kodlama desteğini dışlar.
.NET Framework 4, bir işlemi kurtarılamaz bozuk durumda bırakan özel durumlar olan bozuk durum özel durumları kavramını tanıtır. Varsayılan olarak, diğer tüm özel durumları yakalayan /EHa derleyici seçeneğiyle bile bozuk durum özel durumunu yakalayamazsınız. Bozuk bir durum özel durumunu açıkça yakalamak için __try-__except deyimlerini kullanın. Veya bir işlevin bozuk durum özel durumlarını yakalamasını sağlamak için [HandledProcessCorruptedStateExceptions]özniteliğini uygulayın. Bu değişiklik öncelikle bozuk bir durum özel durumunu yakalaması gerekebilecek sistem programcılarını etkiler. Sekiz özel durum 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'dır. Bu özel durumlar hakkında daha fazla bilgi için getExceptionCode makrosna bakın.
Düzeltilen
/GS
derleyici seçeneği, önceki sürümlerden daha kapsamlı arabellek taşmalarına karşı koruma sağlar. Bu sürüm, yığına performansı düşürebilecek ek güvenlik denetimleri ekleyebilir. Derleyiciye belirli bir işlev için güvenlik denetimleri eklememesi talimatı vermek için yeni__declspec(safebuffers)
anahtar sözcüğünü kullanın.Hem (Tüm Program İyileştirme) hem
/clr
de/GL
(Ortak Dil Çalışma Zamanı Derlemesi) derleyici seçenekleriyle derlerseniz,/GL
seçenek yoksayılır. Derleyici seçeneklerinin birleşimi çok az avantaj sağladığından bu değişiklik yapıldı. Bu değişikliğin sonucunda derlemenin performansı iyileştirilir.Varsayılan olarak, visual studio 2010'da trigraf desteği devre dışıdır.
/Zc:trigraphs
Trigraf desteğini etkinleştirmek için derleyici seçeneğini kullanın. Trigraf, ardışık iki soru işaretinden ("??") ve ardından benzersiz bir üçüncü karakterden oluşur. Derleyici, bir trigrafı karşılık gelen noktalama karakteriyle değiştirir. Örneğin, derleyici trigrafı??=
'#' karakteriyle değiştirir. C kaynak dosyalarında bazı noktalama işaretleri için uygun grafik gösterimleri içermeyen bir karakter kümesi kullanan trigraflar kullanın.Bağlayıcı artık Windows 98 için iyileştirmeyi desteklememektedir.
/OPT
(İyileştirmeler) seçeneği, veya/OPT:NOWIN98
belirtirseniz/OPT:WIN98
bir derleme zamanı hatası oluşturur.RuntimeLibrary ve DebugInformationFormat derleme sistemi özellikleri tarafından belirtilen varsayılan derleyici seçenekleri değiştirildi. Varsayılan olarak, bu derleme özellikleri Visual C++ sürüm 7.0 ile 10.0 arasında oluşturulan projelerde belirtilir. Visual C++ 6.0 tarafından oluşturulan bir projeyi geçirirseniz, bu özellikler için bir değer belirtip belirtmeyeceğinize dikkat edin.
Visual Studio 2010'da RuntimeLibrary = MultiThreaded (
/MD
) ve DebugInformationFormat = ProgramDatabase (/Zi
). Visual C++ 9.0'da RuntimeLibrary = MultiThreaded (/MT
) ve DebugInformationFormat = Disabled.
CLR
- Microsoft C# ve Visual Basic derleyicileri artık birincil birlikte çalışma derlemesi (PIA olmadan) üretebilir. PIA olmayan bir derleme, ilgili birincil birlikte çalışma derlemesinin (PIA) dağıtımı olmadan COM türlerini kullanabilir. Visual C# veya Visual Basic tarafından üretilen PIA olmayan derlemeleri kullanırken, kitaplığı kullanan hiçbir PIA derlemesine başvurmadan önce derleme komutundaki PIA derlemesine başvurmanız gerekir.
Visual Studio C++ projeleri ve MSBuild
Visual Studio C++ projeleri artık MSBuild aracını temel alır. Sonuç olarak, proje dosyaları yeni bir XML dosya biçimi ve .vcxproj dosya son eki kullanır. Visual Studio 2010, visual studio'nun önceki sürümlerindeki proje dosyalarını otomatik olarak yeni dosya biçimine dönüştürür. Mevcut proje, önceki derleme aracına, VCBUILD.exe veya proje dosyası son eki .vcproj'a bağlıysa etkilenir.
Önceki sürümlerde Visual C++ özellik sayfalarının geç değerlendirilmesini desteklemektedir. Örneğin, üst özellik sayfası bir alt özellik sayfasını içeri aktarabilir ve üst öğe diğer değişkenleri tanımlamak için alt öğede tanımlanan bir değişkeni kullanabilir. Geç değerlendirme, alt özellik sayfası içeri aktarilmeden önce bile üst değişkenin alt değişkeni kullanmasını etkinleştirdi. Visual Studio 2010'da, MSBuild yalnızca erken değerlendirmeyi desteklediği için, proje sayfası değişkeni tanımlanmadan önce kullanılamaz.
IDE
Uygulama sonlandırma iletişim kutusu artık bir uygulamayı sonlandırmaz. Önceki sürümlerde, veya
terminate()
işlevi bir uygulamanın perakende derlemesini kapattığındaabort()
, C Çalışma Zamanı Kitaplığı konsol penceresinde veya iletişim kutusunda bir uygulama sonlandırma iletisi görüntüledi. İletide kısmen şöyle dendi: "Bu uygulama Çalışma Zamanı'nı olağan dışı bir şekilde sonlandırmak için istedi. Daha fazla bilgi için lütfen uygulamanın destek ekibine başvurun." Windows daha sonra genellikle Windows Hata Bildirimi (Dr. Watson) iletişim kutusu veya Visual Studio hata ayıklayıcısı olan geçerli sonlandırma işleyicisini görüntülediğinden, uygulama sonlandırma iletisi yedekliydi. Visual Studio 2010'dan başlayarak, C Çalışma Zamanı Kitaplığı iletiyi görüntülemez. Ayrıca, çalışma zamanı bir hata ayıklayıcı başlamadan önce uygulamanın sona ermesini engeller. Bu, yalnızca uygulama sonlandırma iletisinin önceki davranışına bağlıysanız hataya neden olan bir değişikliktir.Özellikle Visual Studio 2010 için IntelliSense C++/CLI kodu veya öznitelikleri için çalışmaz, Tüm Başvuruları Bul yerel değişkenler için çalışmaz ve Kod Modeli içeri aktarılan derlemelerden tür adlarını almaz veya türleri tam adlarıyla çözümlemez.
Kitaplıklar
SafeInt sınıfı Visual C++ ile birlikte gelir ve artık ayrı bir indirmede bulunmaz. Bu, yalnızca "SafeInt" olarak da adlandırılan bir sınıf geliştirdiyseniz hataya neden olan bir değişikliktir.
Kitaplık dağıtım modeli artık dinamik bağlantı kitaplığının belirli bir sürümünü bulmak için bildirimleri kullanmıyor. Bunun yerine, her dinamik bağlantı kitaplığının adı sürüm numarasını içerir ve kitaplığı bulmak için bu adı kullanırsınız.
Visual Studio'nun önceki sürümlerinde çalışma zamanı kitaplıklarını yeniden oluşturabilirsiniz. Visual Studio 2010 artık C çalışma zamanı kitaplık dosyalarının kendi kopyalarını derlemeyi desteklememektedir.
Standart Kitaplık
Üst
<iterator>
bilgi artık diğer birçok üst bilgi dosyası tarafından otomatik olarak eklenmez. Bunun yerine, üst bilgide tanımlanan tek başına yineleyiciler için destek gerekiyorsa bu üst bilgiyi açıkça ekleyin. Mevcut proje, önceki derleme aracına, VCBUILD.exe veya proje dosyası soneki olan .vcproj.yineleyiciye bağlıysa etkilenir.Üst bilgide
<algorithm>
checked_*
veunchecked_*
işlevleri kaldırılır. Üst bilgisinde<iterator>
> sınıfchecked_iterator
kaldırılır veunchecked_array_iterator
sınıfı eklenir.CComPtr::CComPtr(int)
Oluşturucu kaldırılır. Bu oluşturucu birCComPtr
nesnenin NULL makrodan oluşturulmasına izin verdi, ancak gereksizdi ve sıfır olmayan tamsayılardan gerekli olmayan yapılara izin verdi.A
CComPtr
, 0 olarak tanımlanan NULL değerinden yine de oluşturulabilir, ancak değişmez değer 0 dışında bir tamsayıdan oluşturulursa başarısız olur. Bunun yerinenullptr
kullanın.Aşağıdaki
ctype
üye işlevleri kaldırıldı:ctype::_Do_narrow_s
,ctype::_Do_widen_s
,ctype::_narrow_s
,ctype::_widen_s
. Bir uygulama bu üye işlevlerinden birini kullanıyorsa, bunu ilgili güvenli olmayan sürümle değiştirmeniz gerekir:ctype::do_narrow
,ctype::do_widen
,ctype::narrow
,ctype::widen
.
CRT, MFC ve ATL Kitaplıkları
Kullanıcıların CRT, MFC ve ATL kitaplıklarını oluşturmasına yönelik destek kaldırıldı. Örneğin, uygun NMAKE dosyası sağlanmadı. Ancak, kullanıcılar bu kitaplıkların kaynak koduna erişmeye devam eder. Ayrıca, Microsoft'un bu kitaplıkları oluşturmak için kullandığı MSBuild seçeneklerini açıklayan bir belge büyük olasılıkla bir Visual C++ Ekip Blogu'nda yayınlanacaktır.
IA64 için MFC desteği kaldırıldı. Ancak, IA64 üzerinde CRT ve ATL desteği hala sağlanır.
Sıralar artık MFC modül tanımı (.def) dosyalarında yeniden kullanılmaz. Bu değişiklik, ikincil sürümler arasında sıraların farklı olmadığı ve hizmet paketleri ile hızlı düzeltme mühendisliği sürümleri için ikili uyumluluğun geliştirileceği anlamına gelir.
sınıfına
CDocTemplate
yeni bir sanal işlev eklendi. Bu yeni sanal işlev CDocTemplate Sınıfıdır. önceki sürümündeOpenDocumentFile
iki parametre vardı. Yeni sürümde üç parametre vardır. Yeniden başlatma yöneticisini desteklemek için, öğesindenCDocTemplate
türetilen herhangi bir sınıfın üç parametresi olan sürümü uygulaması gerekir. Yeni parametre:bAddToMRU
.
Makrolar ve Ortam Değişkenleri
- ortam değişkeni __MSVCRT_HEAP_SELECT artık desteklenmiyor. Bu ortam değişkeni kaldırılır ve değiştirme yoktur.
Microsoft Macro Assembler Başvurusu
- Microsoft Makro Derleyicisi Başvurusu derleyicisinden çeşitli yönergeler kaldırıldı. Kaldırılan yönergeler :
.186
,.286
,.286P
,.287
,.8086
,.8087
ve.NO87
.
Visual Studio 2008'de Önemli Değişiklikler
Derleyici
Windows 95, Windows 98, Windows ME ve Windows NT platformları artık desteklenmiyor. Bu işletim sistemleri hedeflenen platformlar listesinden kaldırılmıştır.
Derleyici artık DOĞRUDAN ATL Sunucusu ile ilişkilendirilmiş birden çok özniteliği desteklemez. Aşağıdaki öznitelikler artık desteklenmiyor:
perf_counter
perf_object
perfmon
request_handler
soap_handler
soap_header
soap_method
tag_name
Visual Studio C++ projeleri
Visual Studio'nun önceki sürümlerinden projeleri yükseltirken, WINVER ve _WIN32_WINNT makrolarını 0x0500'den büyük veya eşit olacak şekilde değiştirmeniz gerekebilir.
Visual Studio 2008'den başlayarak, yeni proje sihirbazının C++ SQL Server projesi oluşturma seçeneği yoktur. Visual Studio'nun önceki bir sürümü kullanılarak oluşturulan SQL Server projeleri yine de derlenir ve düzgün çalışır.
Windows API üst bilgi dosyası Winable.h kaldırıldı. Bunun yerine Winuser.h dosyasını ekleyin.
Windows API kitaplığı Rpcndr.lib kaldırıldı. Bunun yerine rpcrt4.lib ile bağlantı.
CRT
Windows 95, Windows 98, Windows Millennium Edition ve Windows NT 4.0 desteği kaldırıldı.
Aşağıdaki genel değişkenler kaldırıldı:
_osplatform
_osver
_winmajor
_winminor
_winver
Aşağıdaki işlevler kaldırıldı. Bunun yerine Windows API işlevlerini
GetVersion
GetVersionEx
kullanın:_get_osplatform
_get_osver
_get_winmajor
_get_winminor
_get_winver
SAL Ek Açıklamalarının söz dizimi değişti. Daha fazla bilgi için bkz . SAL Ek Açıklamaları.
IEEE filtresi artık SSE 4.1 yönerge kümesini destekliyor. Daha fazla bilgi için bkz . _fpieee_flt_fpieee_flt.
Visual Studio ile birlikte gelen C Çalışma Zamanı Kitaplıkları artık sistem DLL msvcrt.dll bağımlı değildir.
Standart Kitaplık
Windows 95, Windows 98, Windows Millennium Edition ve Windows NT 4.0 desteği kaldırıldı.
_HAS_ITERATOR_DEBUGGING tanımlı (Visual Studio 2010'un ardından _ITERATOR_DEBUG_LEVEL tarafından değiştirilen) hata ayıklama modunda derleme yaparken, bir yineleyici temel kapsayıcının sınırlarını artırmaya veya azaltmaya çalıştığında uygulama artık onaylayacak.
Stack Sınıfının c üye değişkeni artık korumalı olarak bildirilir. Daha önce bu üye değişkeni genel olarak bildirildi.
davranışı
money_get::do_get
değişti. Daha önce, tarafından çağrılandan daha fazla kesir basamağı olan bir parasal tutarı ayrıştırırken, bunların tümünü kullanmak içinfrac_digits
do_get
kullanılır. Şimdi,do_get
en fazlafrac_digits
karakter tüketildikten sonra ayrıştırma durdurulur.
ATL
ATL, CRT bağımlılığı olmadan oluşturulamaz. Visual Studio'nun önceki sürümlerinde, atl projesini CRT'ye en az bağımlı hale getirmek için #define ATL_MIN_CRT kullanabilirsiniz. Visual Studio 2008'de, ATL_MIN_CRT tanımlanıp tanımlanmadığına bakılmaksızın tüm ATL projeleri en az CRT'ye bağımlıdır.
ATL Server kod tabanı CodePlex'te paylaşılan kaynak projesi olarak yayımlanmıştır ve Visual Studio'nun bir parçası olarak yüklenmemiştir. atlenc.h dosyasından veri kodlama ve kod çözme sınıfları ve atlutil.h ve atlpath.h'den yardımcı program işlevleri ve sınıfları tutulmuştur ve artık ATL kitaplığının bir parçasıdır. ATL Sunucusu ile ilişkilendirilmiş birkaç dosya artık Visual Studio'nun parçası değildir.
Bazı işlevler artık DLL'ye eklenmez. Bunlar hala içeri aktarma kitaplığında bulunur. Bu, işlevleri statik olarak kullanan kodu etkilemez. Yalnızca bu işlevleri dinamik olarak kullanan kodu etkiler.
PROP_ENTRY ve PROP_ENTRY_EX makroları kullanım dışı bırakıldı ve güvenlik nedeniyle PROP_ENTRY_TYPE ve PROP_ENTRY_TYPE_EX makrolarla değiştirildi.
ATL/MFC Paylaşılan Sınıfları
ATL, CRT bağımlılığı olmadan oluşturulamaz. Visual Studio'nun önceki sürümlerinde, bir ATL projesini CRT'ye en az bağımlı hale getirmek için kullanabilirsiniz
#define ATL_MIN_CRT
. Visual Studio 2008'de, ATL_MIN_CRT tanımlanıp tanımlanmadığına bakılmaksızın tüm ATL projeleri en az CRT'ye bağımlıdır.ATL Server kod tabanı CodePlex'te paylaşılan kaynak projesi olarak yayımlanmıştır ve Visual Studio'nun bir parçası olarak yüklenmemiştir. atlenc.h dosyasından veri kodlama ve kod çözme sınıfları ve atlutil.h ve atlpath.h'den yardımcı program işlevleri ve sınıfları tutulmuştur ve artık ATL kitaplığının bir parçasıdır. ATL Sunucusu ile ilişkilendirilmiş birkaç dosya artık Visual Studio'nun parçası değildir.
Bazı işlevler artık DLL'ye eklenmez. Bunlar hala içeri aktarma kitaplığında bulunur. Bu, işlevleri statik olarak kullanan kodu etkilemez. Yalnızca bu işlevleri dinamik olarak kullanan kodu etkiler.
MFC
CTime
Sınıf: SınıfCTime
artık 1/1/1970 C.E. yerine 1/1/1900 C.E. tarihinden başlayarak tarihleri kabul eder.MFC iletişim kutularındaki denetimlerin sekme sırası: MFC ActiveX denetimi sekme sırasına eklenirse, MFC iletişim kutusundaki birden çok denetimin doğru sekme sırası bozulr. Bu değişiklik bu sorunu düzeltmektedir.
Örneğin, ActiveX denetimine ve çeşitli düzenleme denetimlerine sahip bir MFC iletişim kutusu uygulaması oluşturun. ActiveX denetimini düzenleme denetimlerinin sekme sırasının ortasına yerleştirin. Uygulamayı başlatın, sekme sırası ActiveX denetiminden sonra gelen bir düzenleme denetimine tıklayın ve ardından sekme tuşuna basın. Bu değişiklikten önce odak, sekme sırasına göre bir sonraki düzenleme denetimi yerine ActiveX denetiminden sonra düzenleme denetimine gitti.
CFileDialog
Sınıf: SınıfınCFileDialog
özel şablonları Windows Vista'ya otomatik olarak taşınabilir. Bunlar hala kullanılabilir, ancak Windows Vista stili iletişim kutularının ek işlevlerine veya görünümlerine sahip olmayacaktır.CWnd
Sınıf veCFrameWnd
Sınıf:CWnd::GetMenuBarInfo
yöntemi kaldırıldı.yöntemi
CFrameWnd::GetMenuBarInfo
artık sanal olmayan bir yöntemdir. Daha fazla bilgi için bkz . Windows SDK'sında GetMenuBarInfo İşlevi .MFC ISAPI desteği: MFC artık Internet Server Uygulama Programlama Arabirimi (ISAPI) ile uygulama derlemeyi desteklemiyor. BIR ISAPI uygulaması oluşturmak istiyorsanız, DOĞRUDAN ISAPI uzantılarını çağırın.
Kullanım dışı BıRAKıLAN ANSI API'leri: Birkaç MFC yönteminin ANSI sürümleri kullanım dışıdır. Bu yöntemlerin Unicode sürümlerini gelecekteki uygulamalarınızda kullanın. Daha fazla bilgi için bkz . Windows Vista Ortak Denetimleri için Derleme Gereksinimleri.
Visual Studio 2005'in Önemli Değişiklikleri
CRT
Birçok işlev kullanım dışı bırakıldı. Bkz. Kullanım Dışı CRT İşlevleri.
Birçok işlev artık parametrelerini doğrular ve geçersiz parametreler verilirse yürütmeyi durdurur. Bu doğrulama, geçersiz parametreler geçiren ve işlevi yoksayarak veya yalnızca bir hata kodu döndüren kodu bozabilir. Bkz. Parametre Doğrulama.
-2 dosya tanımlayıcısı değeri artık bunu belirtmek
stdout
için kullanılır vestderr
çıkış için kullanılamaz, örneğin konsol penceresi olmayan bir Windows uygulamasında. Kullanılan önceki değer -1'ydi. Daha fazla bilgi için bkz . _fileno.Tek iş parçacıklı CRT kitaplıkları (libc.lib ve libcd.lib) kaldırıldı. Çok iş parçacıklı CRT kitaplıklarını kullanın. Derleyici
/ML
bayrağı artık desteklenmiyor. Çok iş parçacıklı kod ile tek iş parçacıklı kod arasındaki performans farkının büyük olasılıkla önemli olduğu durumlarda bazı işlevlerin kilitlenmeyen sürümleri eklenmiştir.Çift pow (int, int) pow aşırı yüklemesi, standarda daha uygun olması için kaldırıldı.
%n biçim belirticisi artık printf işlev ailesinin hiçbirinde varsayılan olarak desteklenmemektedir çünkü doğası gereği güvenli değildir. %n ile karşılaşılırsa, varsayılan davranış geçersiz parametre işleyicisini çağırmaktır. %n desteğini etkinleştirmek için kullanın
_set_printf_count_output
(ayrıca bkz_get_printf_count_output
. ).sprintf
şimdi imzalı sıfırın negatif işaretini yazdırır.swprintf
Standart ile uyumlu olacak şekilde değiştirilmiştir; artık bir boyut parametresi gerektiriyor. Boyut parametresi olmadan biçimiswprintf
kullanım dışı bırakıldı._set_security_error_handler
kaldırıldı. Bu işleve yapılan çağrıları kaldırın; varsayılan işleyici, güvenlik hatalarıyla başa çıkmanın çok daha güvenli bir yoludur.time_t
artık 64 bit bir değerdir (_USE_32BIT_TIME_T tanımlanmadığı sürece)._spawn
,_wspawn
İşlevleri artık C Standardı tarafından belirtilen başarıda dokunulmadan bırakılırerrno
.RTC artık varsayılan olarak geniş karakterler kullanıyor.
veya ile
/CLR
/CLR:PURE
derlenen uygulamalar için kayan nokta denetimi sözcük desteği işlevleri kullanım dışı bırakıldı. Etkilenen işlevler ,_clear87
,_clearfp
,_control87
,_controlfp
,_fpreset
, ,_status87
._statusfp
_CRT_MANAGED_FP_NO_DEPRECATE tanımlayarak kullanımdan kaldırma uyarısını devre dışı bırakabilirsiniz, ancak bu işlevlerin yönetilen kodda kullanımı tahmin edilemez ve desteklenmez.Bazı işlevler artık sabit işaretçiler döndürmektedir. _CONST_RETURN tanımlanarak eski, en iyi olmayan davranış yeniden etkinleştirilebilir. Etkilenen işlevler şunlardır:
memchr, wmemchr
strchr, wcschr, _mbschr, _mbschr_l
strpbrk, wcspbrk, _mbspbrk, _mbspbrk_l
strrchr, wcsrchr, _mbsrchr, _mbsrchr_l
strstr, wcsstr, _mbsstr, _mbsstr_l
Setargv.obj veya Wsetargv.obj ile bağlantı oluştururken, komut satırında joker karakteri çift tırnak içine alarak genişletmeyi engellemek artık mümkün değildir. Daha fazla bilgi için bkz . Joker Karakter Bağımsız Değişkenlerini Genişletme.
Standart Kitaplık (2005)
Özel durum sınıfı (üst bilgide
<exception>
bulunur) ad alanınastd
taşındı. Önceki sürümlerde bu sınıf genel ad alanındaydı. Özel durum sınıfının bulunamadığını belirten hataları çözmek için aşağıdaki using deyimini kodunuza ekleyin:using namespace std;
çağrılırken
valarray::resize()
öğesininvalarray
içeriği kaybolur ve varsayılan değerlerle değiştirilir.resize()
yöntemi, bir vektör gibi dinamik olarak büyütmek yerine öğesinivalarray
yeniden başlatmaya yöneliktir.Hata Ayıklama Yineleyicileri: C-Runtime Kitaplığı'nın hata ayıklama sürümüyle oluşturulmuş ve yineleyicileri yanlış kullanan uygulamalar çalışma zamanında onayları görmeye başlayabilir. Bu onayları devre dışı bırakmak için, _HAS_ITERATOR_DEBUGGING (
_ITERATOR_DEBUG_LEVEL
Yerine Visual Studio 2010'a geçtikten sonra) 0 olarak tanımlamanız gerekir. Daha fazla bilgi için bkz . Yineleyici Desteğinde Hata Ayıklama
Visual C++ .NET 2003 Hataya Neden Olan Değişiklikler
Derleyici
Tanımlanan önişlemci yönergesi (C2004) için artık kapatma parantezleri gerekiyor.
Açık özelleştirmeler artık birincil şablondan şablon parametrelerini bulmaz (Derleyici Hatası C2146).
Korumalı üyeye (n) yalnızca (n) üyesi olduğu sınıftan (A) devralan bir sınıfın (B) üye işlevi aracılığıyla erişilebilir (Derleyici Hatası C2247).
Derleyicide geliştirilmiş erişilebilirlik denetimleri artık erişilemeyen temel sınıfları algılar (Derleyici Hatası C2248).
Yıkıcı ve/veya kopya oluşturucuya erişilemiyorsa (C2316) bir özel durum yakalanamaz.
İşlevlerin işaretçilerindeki varsayılan bağımsız değişkenlere artık izin verilmiyor (Derleyici Hatası C2383).
Statik veri üyesi türetilmiş sınıf aracılığıyla başlatılamıyor (Derleyici Hatası C2477).
'nin başlatılmasına
typedef
standart tarafından izin verilmez ve şimdi derleyici hatası oluşturur (Derleyici Hatası C2513).bool
artık uygun bir türdür (Derleyici Hatası C2632).UDC artık aşırı yüklenmiş işleçlerle (C2666) belirsizlik oluşturabilir.
Daha fazla ifade artık geçerli null işaretçi sabitleri olarak kabul edilir (Derleyici Hatası C2668).
şablon<> artık derleyicinin daha önce bunu ima ettiği yerlerde gereklidir (Derleyici Hatası C2768).
Bir üye işlevinin sınıf dışındaki açık uzmanlığı, işlev zaten bir şablon sınıfı özelleştirmesi (Derleyici Hatası C2910) aracılığıyla açıkça özelleştirilmişse geçerli değildir.
Kayan nokta türü olmayan şablon parametrelerine artık izin verilmiyor (Derleyici Hatası C2993).
Sınıf şablonlarına şablon türü bağımsız değişkenleri (C3206) olarak izin verilmez.
Arkadaş işlevi adları artık ad alanı (Derleyici Hatası C3767) ile kullanılmayacaktır.
Derleyici artık makroda fazladan virgül (C4002) kabul etmeyecektir.
Form başlatıcısı () ile yapılandırılmış POD türündeki bir nesne varsayılan olarak başlatılır (C4345).
Bağımlı bir ad bir tür (Derleyici Uyarısı (düzey 1) C4346 olarak ele alınacaksa artık typename gereklidir.
Hatalı şablon özelleştirmeleri olarak kabul edilen işlevler artık bu şekilde değerlendirilmez (C4347).
Statik veri üyeleri türetilmiş sınıf (C4356) aracılığıyla başlatılamaz.
Bir dönüş türünde (Derleyici Uyarısı (düzey 3) C4686) kullanılmadan önce sınıf şablonu özelleştirmesinin tanımlanması gerekir.
Derleyici artık ulaşılamayan kod (C4702) bildiriyor.