Visual C++ 변경 기록 2003 - 2015Visual C++ change history 2003 - 2015

이 문서에서는 Visual C++ 2015에서 Visual Studio 2003까지 모든 주요 변경 내용을 설명하며, 이 문서에서 사용된 “새 동작" 또는 “현재"라는 용어는 Visual Studio 2015 이상 버전을 가리킵니다.This article describes all the breaking changes from Visual Studio 2015 going back to Visual Studio 2003, and in this article the terms "new behavior" or "now" refer to Visual Studio 2015 and later. "이전 동작" 및 "이전"은 Visual Studio 2013 이하 릴리스를 나타냅니다.The terms "old behavior" and "before" refer to Visual Studio 2013 and earlier releases.

Visual Studio 2017에 대한 자세한 내용은 Visual Studio 2017의 Visual C++에 대한 새로운 기능Visual Studio 2017의 Visual C++에서 규칙 향상을 참조하세요.For information about Visual Studio 2017, see What's new for Visual C++ in Visual Studio 2017 and Conformance Improvements in Visual C++ in Visual Studio 2017.

참고

Visual Studio 2015 ~ Visual Studio 2017에서 새로운 이진 변경 내용이 없습니다.There are no binary breaking changes between Visual Studio 2015 and Visual Studio 2017.

새 버전의 Visual C++ 컴파일러로 업그레이드하는 경우 이전에 컴파일하고 올바르게 실행된 코드에서 컴파일 및/또는 런타임 오류가 발생할 수 있습니다.When you upgrade to a new version of the Visual C++ compiler, you might encounter compilation and/or runtime errors in code that previously compiled and ran correctly. 그러한 문제가 발생하는 새 버전의 변경 사항은 주요 변경 사항이라고 하고 일반적으로 C++ 언어 표준, 함수 서명 또는 메모리의 레이아웃 개체 수정에 필요합니다.Changes in the new version that cause such problems are known as breaking changes, and typically they're required by modifications in the C++ language standard, function signatures, or the layout of objects in memory.

검색 및 진단하기 어려운 런타임 오류를 방지하려면 다양한 버전의 컴파일러를 사용하여 컴파일된 바이너리에 정적으로 연결하지 않는 것이 좋습니다.To avoid run-time errors that are difficult to detect and diagnose, we recommend that you never statically link to binaries that were compiled by using different versions of the compiler. 또한 EXE 또는 DLL 프로젝트를 업그레이드하는 경우 연결되는 라이브러리를 업그레이드해야 합니다.Also, when you upgrade an EXE or DLL project, make sure to upgrade the libraries that it links to. CRT(C 런타임) 형식 또는 C++ 표준 라이브러리(C++ 표준 라이브러리) 형식을 사용하는 경우, 다양한 버전의 컴파일러를 사용하여 컴파일된 바이너리(DLL 포함) 간에 이 두 형식을 전달하지 마세요.If you're using CRT (C Runtime) or C++ Standard Library (C++ Standard Library) types, don't pass them between binaries (including DLLs) that were compiled by using different versions of the compiler. 자세한 내용은 DLL 경계를 넘어 CRT 개체를 전달할 때 발생할 수 있는 오류를 참조하세요.For more information, see Potential Errors Passing CRT Objects Across DLL Boundaries.

또한 COM 인터페이스 또는 POD 개체가 아닌 개체에 대한 특정 레이아웃에 의존하는 코드는 작성하지 않는 것이 좋습니다.We further recommend that you never write code that depends on a particular layout for an object that is not a COM interface or a POD object. 그러한 코드를 작성하는 경우 업그레이드한 후 작동하는지 확인해야 합니다.If you do write such code, then you must ensure that it works after you upgrade. 자세한 내용은 ABI 경계의 이식성을 참조하세요.For more information, see Portability At ABI Boundaries.

또한 컴파일러 규칙 개선 작업이 진행 중이므로 컴파일러에서 기존 소스 코드를 인식하는 방식이 변경될 수 있습니다.Additionally, ongoing improvements to compiler conformance can sometimes change how the compiler understands your existing source code. 이로 인해 빌드 중 새로운 오류 또는 다른 오류가 발생하거나, 이전에 빌드되어 올바르게 실행되는 것처럼 보이는 코드가 다르게 동작할 수도 있습니다.When this happens, you might encounter new or different errors during your build, or even behavioral differences in code that previously built and seemed to run correctly. 이 문서에 설명된 것과 같은 주요 변경 내용은 아니지만 이러한 문제를 해결하기 위해 소스 코드를 변경해야 할 수도 있습니다.Although these are not breaking changes like the ones discussed in this document, source code changes might be needed to resolve these issues.

  1. CRT(C 런타임) 라이브러리 주요 변경 내용C Runtime (CRT) Library Breaking Changes

  2. 표준 C++ 및 C++ 표준 라이브러리 주요 변경 내용Standard C++ and C++ Standard Library Breaking Changes

  3. MFC 및 ATL 주요 변경 내용MFC and ATL Breaking Changes

  4. 동시성 런타임 주요 변경 내용Concurrency Runtime Breaking Changes

Visual C++ 2015 규칙 변경 내용Visual C++ 2015 Conformance Changes

CRT(C 런타임 라이브러리)C Runtime Library (CRT)

일반 변경 내용General Changes

  • 리팩터링된 이진 파일 CRT 라이브러리는 두 개의 다른 이진 파일로 리팩터링되었습니다. 즉 유니버설 CRT(ucrtbase)에는 대부분의 표준 기능이 포함되어 있으며, VC 런타임 라이브러리(vcruntime)에는 예외 처리 및 내장 함수와 같은 컴파일러 관련 기능이 포함되어 있습니다.Refactored binaries The CRT Library has been refactored into a two different binaries, a Universal CRT (ucrtbase), which contains most of the standard functionality, and a VC Runtime Library (vcruntime), which contains the compiler-related functionality, such as exception handling, and intrinsics. 링커는 자동으로 새 기본 라이브러리를 사용하므로 기본 프로젝트 설정을 사용하면 이 변경이 영향을 미치지 않습니다.If you are using the default project settings, then this change does not impact you since the linker will use the new default libraries automatically. 프로젝트의 링커 속성 모든 기본 라이브러리 무시 로 설정했거나 명령줄에서 /NODEFAULTLIB 링커 옵션을 사용 중이면 추가 종속성 속성에서 라이브러리 목록을 업데이트하여 새 리팩터링된 라이브러리를 포함해야 합니다.If you have set the project's Linker property Ignore All Default Libraries to Yes or you are using the /NODEFAULTLIB linker option on the command line, then you must update your list of libraries (in the Additional Dependencies property) to include the new, refactored libraries. 이전 CRT 라이브러리(libcmt.lib, libcmtd.lib, msvcrt.lib, msvcrtd.lib)를 해당하는 리팩터링된 라이브러리로 바꿉니다.Replace the old CRT library (libcmt.lib, libcmtd.lib, msvcrt.lib, msvcrtd.lib) with the equivalent refactored libraries. 두 리팩터링된 라이브러리에는 각각 정적(.lib) 및 동적(.dll) 버전과 릴리스(접미사 없음) 및 디버그("d" 접미사 사용) 버전이 있습니다.For each of the two refactored libraries, there are static (.lib) and dynamic (.dll) versions, and release (with no suffix) and debug versions (with the "d" suffix). 동적 버전에는 연결할 가져오기 라이브러리가 포함됩니다.The dynamic versions have an import library that you link with. 리팩터링된 두 라이브러리는 유니버설 CRT(구체적으로 ucrtbase.dll 또는 .lib, ucrtbased.dll 또는 .lib)와 VC 런타임 라이브러리(libvcruntime.lib, vcruntime버전.dll, libvcruntimed.lib 및 vcruntimed버전.dll)입니다.The two refactored libraries are Universal CRT, specifically ucrtbase.dll or .lib, ucrtbased.dll or .lib, and the VC runtime library, libvcruntime.lib, vcruntimeversion.dll, libvcruntimed.lib, and vcruntimedversion.dll. Visual Studio 2015 및 Visual Studio 2017의 버전은 모두 140입니다.The version in both Visual Studio 2015 and Visual Studio 2017 is 140. CRT 라이브러리 기능을 참조하세요.See CRT Library Features.

<locale.h><locale.h>

  • localeconv 이전에 오류 없이 컴파일했던 위치에서 localeconv 함수는 현재 per-thread locale이 사용될 때 제대로 작동합니다.localeconv The localeconv function declared in locale.h now works correctly when per-thread locale is enabled. 이전 라이브러리 버전에서 이 함수는 스레드 로캘이 아니라 전역 로캘에 대해 lconv 데이터를 반환합니다.In previous versions of the library, this function would return the lconv data for the global locale, not the thread's locale.

    스레드 단위 로캘을 사용할 경우 localeconv 사용을 확인하여 코드에서 반환된 lconv 데이터가 전역 로캘과 관련된다고 가정하는지 확인하고 적절히 수정해야 합니다.If you use per thread locale, you should check your use of localeconv to see if your code assumes that the lconv data returned is for the global locale and modify it appropriately.

<math.h><math.h>

  • 수식 라이브러리 함수의 C++ 오버로드 이전 버전에서 <math.h>는 수식 라이브러리 함수에 대한 일부 C++ 오버로드를 정의했습니다.C++ overloads of math library functions In previous versions, <math.h> defined some, but not all, of the C++ overloads for the math library functions. <cmath>는 나머지 오버로드를 정의하므로 모든 오버로드를 가져오려면 <cmath> 헤더를 포함해야 했습니다.<cmath> defined the remaining overloads, so to get all of the overloads, one needed to include the <cmath> header. 이로 인해 <math.h>만 포함된 코드에서는 함수 오버로드 확인에 대한 문제가 발생했습니다.This led to problems with function overload resolution in code that only included <math.h>. 현재 모든 C++ 오버로드는 <math.h>에서 제거되었고 <cmath>에만 있습니다.Now, all C++ overloads have been removed from <math.h> and are now present only in <cmath>.

    오류를 해결하려면 를 포함하여 <math.h>에서 제거된 함수 선언을 가져옵니다.To resolve errors, include to get the declarations of the functions that were removed from <math.h>. 다음 표에서는 이동된 함수를 보여 줍니다.The following table lists the functions that were moved.

    이동된 함수:Functions that were moved:

    1. double abs(double) 및 float abs(float)double abs(double) and float abs(float)

    2. 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)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)

    3. 부동 소수점 함수 acos, acosh, asin, asinh, atan, atanh, atan2, cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, exp2, expm1, fabs, fdim, floor, fma, fmax, fmin, fmod, frexp, hypot, ilogb, ldexp, lgamma, llrint, llround, log, log10, log1p, log2, lrint, lround, modf, nearbyint, nextafter, nexttoward, remainder, remquo, rint, round, scalbln, scalbn, sin, sinh, sqrt, tan, tanh, tgamma, trunc의 float 및 long double 버전float and long double versions of floating point functions acos, acosh, asin, asinh, atan, atanh, atan2, cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, exp2, expm1, fabs, fdim, floor, fma, fmax, fmin, fmod, frexp, hypot, ilogb, ldexp, lgamma, llrint, llround, log, log10, log1p, log2, lrint, lround, modf, nearbyint, nextafter, nexttoward, remainder, remquo, rint, round, scalbln, scalbn, sin, sinh, sqrt, tan, tanh, tgamma, trunc

      math.h 헤더만 포함된 abs를 부동 소수점 형식과 함께 사용하는 코드가 있으면 부동 소수점 버전을 더 이상 사용할 수 없으므로 현재 호출은 부동 소수점 인수가 포함되더라도 abs(int)로 확인됩니다.If you have code that uses abs with a floating point type that only includes the math.h header, the floating point versions will no longer be available, so the call, even with a floating point argument, now resolves to abs(int). 이로 인해 오류가 발생합니다.This produces the error:

    warning C4244: 'argument' : conversion from 'float' to 'int', possible loss of data  
    

    이 경고를 해결하려면 abs에 대한 호출을 abs의 부동 소수점 버전(예: double 인수에 대한 fabs 또는 float 인수에 대한 fabsf)으로 바꾸거나, cmath 헤더를 포함하고 abs를 계속 사용합니다.The fix for this warning is to replace the call to abs with a floating point version of abs, such as fabs for a double argument or fabsf for a float argument, or include the cmath header and continue to use abs.

  • 부동 소수점 적합성 NaN 및 무한대와 같은 특수한 경우 입력과 관련된 IEEE-754 및 C11 Annex F 사양에 대한 적합성을 향상하고자 수식 라이브러리가 많이 변경되었습니다.Floating point conformance Many changes to the math library have been made to improve conformance to the IEEE-754 and C11 Annex F specifications with respect to special case inputs such as NaNs and infinities. 예를 들어 이전 라이브러리 버전에서 종종 오류로 처리되었던 자동 NaN 입력은 더 이상 오류로 처리되지 않습니다.For example, quiet NaN inputs, which were often treated as errors in previous versions of the library, are no longer treated as errors. IEEE 754 표준 (영문) 및 C11 표준(영문)의 부록 F를 참조하세요.See IEEE 754 Standard and Annex F of the C11 Standard.

    이 변경 내용 때문에 컴파일 시간 오류가 발생하지 않지만, 프로그램이 표준에 따라 다르고 더 올바르게 동작할 수 있습니다.These changes won't cause compile-time errors, but might cause programs to behave differently and more correctly according to the standard.

  • FLT_ROUNDS Visual Studio 2013에서 FLT_ROUNDS 매크로는 상수 식으로 확장되었고, 이는 반올림 모드가 런타임에 fesetround 호출 등을 통해 구성 가능하기 때문에 올바르지 않았습니다.FLT_ROUNDS In Visual Studio 2013, the FLT_ROUNDS macro expanded to a constant expression, which was incorrect because the rounding mode is configurable at runtime, for example, by calling fesetround. 현재 FLT_ROUNDS 매크로는 동적이고 현재 반올림 모드를 올바르게 반영합니다.The FLT_ROUNDS macro is now dynamic and correctly reflects the current rounding mode.

<new> 및 <new.h><new> and <new.h>

  • new 및 delete 이전 라이브러리 버전에서는 구현 시 정의된 연산자 new 및 delete 함수를 런타임 라이브러리 DLL(예: msvcr120.dll)에서 내보냈습니다.new and delete In previous versions of the library, the implementation-defined operator new and delete functions were exported from the runtime library DLL (for example, msvcr120.dll). 현재 이들 연산자 함수는 런타임 라이브러리 DLL을 사용할 때라도 항상 정적으로 이진 파일에 연결됩니다.These operator functions are now always statically linked into your binaries, even when using the runtime library DLLs.

    이는 네이티브 또는 혼합 코드(/clr)에 대한 주요 변경 내용이 아니지만 /clr:pure로 컴파일된 코드의 경우 이로 인해 코드가 컴파일되지 않을 수 있습니다.This is not a breaking change for native or mixed code (/clr), however for code compiled as /clr:pure, this might cause your code to fail to compile. 코드를 /clr:pure로 컴파일할 경우 이 변경으로 인한 빌드 오류를 해결하려면 #include <new> 또는 #include <new.h>를 추가해야 할 수 있습니다.If you compile code as /clr:pure, you may need to add #include <new> or #include <new.h> to work around build errors due to this change. /clr:pure는 Visual Studio 2015에서 사용되지 않으므로 이후 릴리스에서 제거될 예정입니다.Note that /clr:pure is deprecated in Visual Studio 2015 and might be removed in future releases.

<process.h><process.h>

  • _beginthread 및 _beginthreadex 이전에 오류 없이 컴파일했던 위치에서 _beginthread_beginthreadex 함수는 현재 스레드 기간에 대한 스레드 프로시저가 정의되어 있는 모듈에 대한 참조를 포함합니다._beginthread and _beginthreadex The _beginthread and _beginthreadex functions now hold a reference to the module in which the thread procedure is defined for the duration of the thread. 이를 통해 스레드 실행이 완료될 때까지 모듈이 언로드되지 않도록 보장할 수 있습니다.This helps to ensure that modules are not unloaded until a thread has run to completion.

<stdarg.h><stdarg.h>

  • va_start 및 참조 형식 C++ 코드를 컴파일할 때 현재 va_start는 컴파일 시간에 전달된 인수가 참조 형식이 아닌지 검사합니다.va_start and reference types When compiling C++ code, va_start now validates at compile-time that the argument passed to it is not of reference type. 참조 형식 인수는 C++ 표준에 따라 금지됩니다.Reference-type arguments are prohibited by the C++ Standard.

<stdio.h> 및 <conio.h><stdio.h> and <conio.h>

  • printf 및 scanf 함수 패밀리는 현재 인라인으로 정의됩니다.The printf and scanf family of functions are now defined inline. 모든 printf 및 scanf 함수의 정의는 <stdio.h>, <conio.h> 및 기타 CRT 헤더로 인라인으로 이동되었습니다.The definitions of all of the printf and scanf functions have been moved inline into <stdio.h>, <conio.h>, and other CRT headers. 이 주요 변경 내용으로 인해 해당하는 CRT 헤더를 포함하지 않고 이들 함수를 로컬로 선언한 프로그램에 대한 링커 오류(LNK2019, 확인되지 않은 외부 기호)가 발생합니다.This is a breaking change that leads to a linker error (LNK2019, unresolved external symbol) for any programs that declared these functions locally without including the appropriate CRT headers. 가능하면 코드를 업데이트하여 인라인 함수 및 CRT 헤더를 포함(#include <stdio.h> 추가)해야 하지만, 이들 헤더 파일을 포함하도록 코드를 수정하지 않으려면 대체 솔루션으로 링커 입력 legacy_stdio_definitions.lib에 추가 라이브러리를 추가합니다.If possible, you should update the code to include the CRT headers (that is, add #include <stdio.h>) and the inline functions, but if you do not want to modify your code to include these header files, an alternative solution is to add an additional library to your linker input, legacy_stdio_definitions.lib.

    이 라이브러리를 IDE의 링커 입력에 추가하려면 프로젝트 노드의 상황에 맞는 메뉴를 열고, 속성을 선택하고, 프로젝트 속성 대화 상자에서 링커를 선택하고, 링커 입력 을 편집하여 legacy_stdio_definitions.lib를 세미콜론으로 구분된 목록에 추가합니다.To add this library to your linker input in the IDE, open the context menu for the project node, choose Properties, then in the Project Properties dialog box, choose Linker, and edit the Linker Input to add legacy_stdio_definitions.lib to the semi-colon-separated list.

    프로젝트가 Visual C++ 2015 이전의 릴리스로 컴파일된 정적 라이브러리와 연결되면 링커에서 확인되지 않은 외부 기호가 보고될 수 있습니다.If your project links with static libraries that were compiled with a release of Visual C++ earlier than 2015, the linker might report an unresolved external symbol. 이들 오류는 iob, _iob_func에 대한 내부 stdio 정의 또는 _imp\* 형식의 특정 stdio 함수에 대한 관련 가져오기를 참조할 수 있습니다.These errors might reference internal stdio definitions for iob, _iob_func, or related imports for certain stdio functions in the form of _imp\*. 프로젝트를 업그레이드할 때 Visual C++ 컴파일러 및 라이브러리의 최신 버전으로 모든 정적 라이브러리를 다시 컴파일하는 것이 좋습니다.Microsoft recommends that you recompile all static libraries with the latest version of the Visual C++ compiler and libraries when you upgrade a project. 라이브러리가 소스를 사용할 수 없는 타사 라이브러리이면 타사로부터 업데이트된 라이브러리를 요청하거나 Visual C++ 컴파일러 및 라이브러리의 이전 버전으로 컴파일하는 별도의 DLL로 해당 라이브러리 사용을 캡슐화해야 합니다.If the library is a third-party library for which source is not available, you should either request an updated binary from the third party or encapsulate your usage of that library into a separate DLL that you compile with the older version of the Visual C++ compiler and libraries.

    경고

    Windows SDK 8.1 이하와 연결되어 있으면 이러한 확인되지 않은 외부 기호 오류가 발생할 수 있습니다.If you are linking with Windows SDK 8.1 or earlier, you might encounter these unresolved external symbol errors. 이 경우 앞에 설명된 대로 링커 입력에 legacy_stdio_definitions.lib를 추가하여 오류를 해결해야 합니다.In that case, you should resolve the error by adding legacy_stdio_definitions.lib to the linker input as described previously.

    확인되지 않은 기호 오류를 해결하려면 dumpbin.exe를 사용하여 이진 파일에 정의된 기호를 검사해 볼 수 있습니다.To troubleshoot unresolved symbol errors, you can try using dumpbin.exe to examine the symbols defined in a binary. 다음 명령줄을 실행하여 라이브러리에 정의된 기호를 확인해 보세요.Try the following command line to view symbols defined in a library.

    dumpbin.exe /LINKERMEMBER somelibrary.lib  
    
  • gets 및 _getws 이전에 오류 없이 컴파일했던 위치에서 gets_getws 함수가 제거되었습니다.gets and _getws The gets and _getws functions have been removed. gets 함수는 안전하게 사용할 수 없으므로 C11의 C 표준 라이브러리에서 제거되었습니다.The gets function was removed from the C Standard Library in C11 because it cannot be used securely. _getws 함수는 gets와 동일한 Microsoft 확장이지만 전각 문자열에 해당했습니다.The _getws function was a Microsoft extension that was equivalent to gets but for wide strings. 이들 함수 대신 fgets, fgetws, gets_s_getws_s를 사용하는 것이 좋습니다.As alternatives to these functions, consider use of fgets, fgetws, gets_s, and _getws_s.

  • _cgets 및 _cgetws 이전에 오류 없이 컴파일했던 위치에서 _cgets_cgetws 함수가 제거되었습니다._cgets and _cgetws The _cgets and _cgetws functions have been removed. 이들 함수 대신 _cgets_s_cgetws_s를 사용하는 것이 좋습니다.As alternatives to these functions, consider use of _cgets_s and _cgetws_s.

  • 무한대 및 NaN 서식 지정 이전 버전에서 무한대 및 NaN은 일련의 Visual C++ 관련 센티널 문자열을 사용하여 서식이 지정됩니다.Infinity and NaN Formatting In previous versions, infinities and NaNs would be formatted using a set of Visual C++-specific sentinel strings.

    • 무한대: 1.#INFInfinity: 1.#INF

    • 자동 NaN: 1.#QNANQuiet NaN: 1.#QNAN

    • 신호 NaN: 1.#SNANSignaling NaN: 1.#SNAN

    • 무한 NaN: 1.#INDIndefinite NaN: 1.#IND

      이들 문자열 앞에 부호가 추가될 수 있고 필드 너비 및 정밀도에 따라 서식이 약간 다르게 지정되었을 수 있습니다. #INF는 2자리 정밀도로 "반올림"되므로 경우에 따라 비정상적인 효과로 인해 printf("%.2f\n", INFINITY)가 1.#J를 인쇄할 수 있습니다.Any of these may have been prefixed by a sign and may have been formatted slightly differently depending on field width and precision (sometimes with unusual effects, e.g. printf("%.2f\n", INFINITY) would print 1.#J because the #INF would be "rounded" to a precision of 2 digits). C99는 무한대 및 NaN 서식을 지정하는 방법에 대한 새로운 요구 사항을 새로 추가했습니다.C99 introduced new requirements on how infinities and NaNs are to be formatted. Visual C++ 구현은 현재 이들 요구 사항을 준수합니다.The Visual C++ implementation now conforms to these requirements. 새 문자열은 다음과 같습니다.The new strings are as follows:

    • 무한대: infInfinity: inf

    • 자동 NaN: nanQuiet NaN: nan

    • 신호 NaN: nan(snan)Signaling NaN: nan(snan)

    • 무한 NaN: nan(ind)Indefinite NaN:nan(ind)

      이들 문자열 앞에 부호가 추가될 수 있습니다.Any of these may be prefixed by a sign. 대문자 서식 지정자가 사용되면(%f 대신 %F) 문자열은 요구된 대로 대문자로 인쇄됩니다(inf 대신 INF).If a capital format specifier is used (%F instead of %f) then the strings are printed in capital letters (INF instead of inf), as is required.

      scanf 함수는 이들 새 문자열을 구문 분석하도록 수정되었으므로 이들 문자열은 printf 및 scanf를 통해 왕복됩니다.The scanf functions have been modified to parse these new strings, so these strings will round-trip through printf and scanf.

  • 부동 소수점 서식 지정 및 구문 분석 정확성을 향상하고자 새로운 부동 소수점 서식 지정 및 구문 분석 알고리즘이 새로 추가되었습니다.Floating point formatting and parsing New floating point formatting and parsing algorithms have been introduced to improve correctness. 이 변경은 함수의 printfscanf 패밀리와 strtod 등의 함수에 영향을 미칩니다.This change affects the printf and scanf families of functions, as well as functions like strtod.

    이전 서식 지정 알고리즘에서는 제한된 자릿수만 생성되고 나머지 소수 자릿수는 0으로 채워집니다.The old formatting algorithms would generate only a limited number of digits, then would fill the remaining decimal places with zero. 일반적으로 다시 원래 부동 소수점 값으로 왕복할 문자열을 생성하려면 이것으로 충분하지만 정확한 값이나 가장 가까운 10진수 표현이 필요한 경우에는 적절하지 않습니다.This is usually good enough to generate strings that will round-trip back to the original floating point value, but it's not great if you want the exact value (or the closest decimal representation thereof). 새 서식 지정 알고리즘에서는 값을 표현하는 데 필요한 만큼 자릿수가 생성되거나 지정된 정밀도가 채워집니다.The new formatting algorithms generate as many digits as are required to represent the value (or to fill the specified precision). 향상의 예로 2의 거듭제곱을 인쇄할 때 결과를 살펴보세요.As an example of the improvement; consider the results when printing a large power of two:

    printf("%.0f\n", pow(2.0, 80))  
    
        Old:  1208925819614629200000000    New:  1208925819614629174706176  
    

    이전 구문 분석 알고리즘에서는 입력 문자열에서 최대 17자리만 고려되고 나머지 자릿수는 무시됩니다.The old parsing algorithms would consider only up to 17 significant digits from the input string and would discard the rest of the digits. 문자열로 표현되는 값의 매우 가까운 근사치를 생성하려면 이것으로 충분하고 결과는 대개 올바르게 반올림됨 결과에 매우 가깝습니다.This is sufficient to generate a very close approximation of the value represented by the string, and the result is usually very close to the correctly rounded result. 새 구현에서는 모든 제공된 자릿수를 고려하고 모든 입력에 대한 올바르게 반올림된 결과를 생성합니다(최대 768자리 길이).The new implementation considers all present digits and produces the correctly rounded result for all inputs (up to 768 digits in length). 또한 현재 이들 함수는 반올림 모드를 따릅니다(fesetround를 통해 제어 가능).In addition, these functions now respect the rounding mode (controllable via fesetround). 이들 함수가 다른 결과를 출력할 수 있으므로 이는 잠재적으로 중요한 동작 변경입니다.This is a potentially breaking behavior change because these functions might output different results. 새 결과는 항상 이전 결과보다 더 정확합니다.The new results are always more correct than the old results.

  • 16진수 및 무한대/NaN 부동 소수점 구문 분석 부동 소수점 구문 분석 알고리즘은 현재 16진수 부동 소수점 문자열(예: %a 및 %A printf 서식 지정자에서 생성된 항목) 및 위 설명대로 printf 함수에서 생성된 모든 무한대 및 NaN 문자열을 구문 분석합니다.Hexadecimal and infinity/NaN floating point parsing The floating point parsing algorithms will now parse hexadecimal floating point strings (such as those generated by the %a and %A printf format specifiers) and all infinity and NaN strings that are generated by the printf functions, as described above.

  • %A 및 %a 영(0) 채우기 %a 및 %A 서식 지정자는 부동 소수점 수의 서식을 16진수 가수 및 이진 지수로 지정합니다.%A and %a zero padding The %a and %A format specifiers format a floating point number as a hexadecimal mantissa and binary exponent. 이전 버전에서 printf 함수는 문자열을 영(0)으로 올바르게 채우지 않습니다.In previous versions, the printf functions would incorrectly zero-pad strings. 예를 들어 printf("%07.0a\n", 1.0)은 0x01p+0을 인쇄해야 하는데 00x1p+0을 인쇄합니다.For example, printf("%07.0a\n", 1.0) would print 00x1p+0, where it should print 0x01p+0. 이 문제는 수정되었습니다.This has been fixed.

  • %A 및 %a 정밀도 이전 라이브러리 버전에서 %A 및 %a 서식 지정자의 기본 정밀도는 6이었습니다.%A and %a precision The default precision of the %A and %a format specifiers was 6 in previous versions of the library. 현재 기본 정밀도는 C 표준에 따라 13입니다.The default precision is now 13 for conformance with the C Standard.

    이는 %A 또는 %a와 함께 서식 문자열을 사용하는 함수 출력의 런타임 동작 변경입니다.This is a runtime behavior change in the output of any function that uses a format string with %A or %a. 이전 동작에서 %A 지정자를 사용하는 출력은 "1.1A2B3Cp+111"일 수 있습니다.In the old behavior, the output using the %A specifier might be "1.1A2B3Cp+111". 현재 같은 값의 출력은 "1.1A2B3C4D5E6F7p+111"입니다.Now the output for the same value is "1.1A2B3C4D5E6F7p+111". 이전 동작을 가져오려면 정밀도(예: %.6A)를 지정하면 됩니다.To get the old behavior, you can specify the precision, for example, %.6A. 전체 자릿수 사양을 참조하세요.See Precision Specification.

  • %F 지정자 현재 %F 서식/변환 지정자가 지원됩니다.%F specifier The %F format/conversion specifier is now supported. 이는 무한대 및 NaN이 대문자로 서식 지정된다는 점을 제외하고 %f 서식 지정자와 일치하는 기능입니다.It is functionally equivalent to the %f format specifier, except that infinities and NaNs are formatted using capital letters.

    이전 버전에서는 F 및 N을 길이 수정자로 구문 분석하는 데 구현이 사용되었습니다.In previous versions, the implementation used to parse F and N as length modifiers. 이 동작은 분할된 주소 공간의 보존 기간부터 계속 존재했습니다. 이들 길이 수정자는 %Fp 또는 %Ns에서와 같이 각각 먼 포인터와 가까운 포인터를 나타내는 데 사용되었습니다.This behavior dated back to the age of segmented address spaces: these length modifiers were used to indicate far and near pointers, respectively, as in %Fp or %Ns. 이 동작이 제거되었습니다.This behavior has been removed. %F가 나타나면 현재 이는 %F 서식 지정자로 처리되고, %N이 나타나면 현재 이는 잘못된 매개 변수로 처리됩니다.If %F is encountered, it is now treated as the %F format specifier; if %N is encountered, it is now treated as an invalid parameter.

  • 지수 서식 지정 %e 및 %E 서식 지정자는 부동 소수점 수의 서식을 10진수 가수 및 지수로 지정합니다.Exponent formatting The %e and %E format specifiers format a floating point number as a decimal mantissa and exponent. 경우에 따라 %g 및 %G 서식 지정자는 숫자 서식을 이 형식으로 지정합니다.The %g and %G format specifiers also format numbers in this form in some cases. 이전 버전에서 CRT는 항상 3자리 지수가 포함된 문자열을 생성합니다.In previous versions, the CRT would always generate strings with three-digit exponents. 예를 들어 printf("%e\n", 1.0)는 1.000000e+000을 인쇄합니다.For example, printf("%e\n", 1.0) would print 1.000000e+000. 이 결과는 올바르지 않습니다. C에서는 지수가 1자리 또는 2자리로만 표현 가능할 경우 2자리만 인쇄되어야 합니다.This was incorrect: C requires that if the exponent is representable using only one or two digits, then only two digits are to be printed.

    Visual Studio 2005에서 전역 규칙 스위치 _set_output_format이 추가되었습니다.In Visual Studio 2005 a global conformance switch was added: _set_output_format. 프로그램은 _TWO_DIGIT_EXPONENT 인수와 함께 이 함수를 호출하여 규칙 지수 인쇄가 가능하도록 설정합니다.A program could call this function with the argument _TWO_DIGIT_EXPONENT, to enable conforming exponent printing. 기본 동작이 표준 준수 지수 인쇄 모드로 변경되었습니다.The default behavior has been changed to the standards-conforming exponent printing mode.

  • 서식 문자열 유효성 검사 이전 버전에서 printf 및 scanf 함수는 경우에 따라 비정상적인 효과를 가진 잘못된 서식 문자열을 대부분 자동으로 수락합니다.Format string validation In previous versions, the printf and scanf functions would silently accept many invalid format strings, sometimes with unusual effects. 예를 들어 %hlhlhld가 %d로 처리됩니다.For example, %hlhlhld would be treated as %d. 현재 모든 잘못된 서식 문자열은 잘못된 매개 변수로 처리됩니다.All invalid format strings are now treated as invalid parameters.

  • fopen 모드 문자열 유효성 검사fopen mode string validation

    이전 버전에서 fopen 함수 패밀리는 몇몇 잘못된 모드 문자열(예: r+b+)을 자동으로 수락했습니다.In previous versions, the fopen family of functions silently accepted some invalid mode strings (e.g. r+b+). 현재는 잘못된 모드 문자열을 인식하여 잘못된 매개 변수로 처리됩니다.Invalid mode strings are now detected and treated as invalid parameters.

  • _O_U8TEXT 모드_O_U8TEXT mode

    현재 _setmode 함수는 _O_U8TEXT 모드에서 열린 스트림의 모드를 올바르게 보고합니다.The _setmode function now correctly reports the mode for streams opened in_O_U8TEXT mode. 이전 라이브러리 버전에서는 해당 스트림을 _O_WTEXT에서 열린 것으로 보고했습니다.In previous versions of the library, it would report such streams as being opened in _O_WTEXT.

    이는 코드가 인코딩이 UTF-8인 스트림에 대한 _O_WTEXT 모드를 해석할 경우 주요 변경 내용입니다.This is a breaking change if your code interprets the _O_WTEXT mode for streams where the encoding is UTF-8. 응용 프로그램이 UTF_8을 지원하지 않으면 점점 더 일반화되는 이 인코딩에 대한 지원을 추가하는 것이 좋습니다.If your application doesn't support UTF_8, consider adding support for this increasingly common encoding.

  • snprintf 및 vsnprintf 이전에 오류 없이 컴파일했던 위치에서 snprintfvsnprintf 함수가 구현됩니다.snprintf and vsnprintf The snprintf and vsnprintf functions are now implemented. 이전 코드에서는 이들 함수의 매크로 버전이 CRT 라이브러리에서 구현되지 않았기 때문에 매크로 버전을 정의에 제공했지만 새 버전에서는 더 이상 필요하지 않습니다.Older code often provided definitions macro versions of these functions because they were not implemented by the CRT library, but these are no longer needed in newer versions. 현재 <stdio.h>를 포함하기 전에 snprintf 또는 vsnprintf가 매크로로 정의되면 컴파일이 실패하고 매크로가 정의된 위치를 나타내는 오류가 발생합니다.If snprintf or vsnprintf is defined as a macro before including <stdio.h>, compilation now fails with an error that indicates where the macro was defined.

    일반적으로 이 문제를 해결하려면 사용자 코드에서 snprintf 또는 vsnprintf의 선언을 삭제합니다.Normally, the fix to this problem is to delete any declarations of snprintf or vsnprintf in user code.

  • tmpnam이 사용 가능한 파일 이름을 생성함 이전 버전에서 tmpnam 및 tmpnam_s 함수는 드라이브 루트(예: \sd3c.)에 파일 이름을 생성했습니다.tmpnam Generates Usable File Names In previous versions, the tmpnam and tmpnam_s functions generated file names in the root of the drive (such as \sd3c.). 현재 이들 함수는 임시 디렉터리에 사용 가능한 파일 이름 경로를 생성합니다.These functions now generate usable file name paths in a temporary directory.

  • FILE 캡슐화 이전 버전에서 FILE 형식은 <stdio.h>에서 완전히 정의되었으므로 사용자 코드가 FILE에 도달하고 internal을 수정할 수 있었습니다.FILE Encapsulation In previous versions, the FILE type was completely defined in <stdio.h>, so it was possible for user code to reach into a FILE and modify its internals. stdio 라이브러리가 구현 세부 정보를 숨기도록 변경되었습니다.The stdio library has been changed to hide implementation details. 이와 함께 <stdio.h>에 정의된 FILE은 현재 불투명 형식이고 해당 멤버는 CRT 외부에서 액세스할 수 없습니다.As part of this, FILE as defined in <stdio.h> is now an opaque type and its members are inaccessible from outside of the CRT itself.

  • _outp 및 _inp _outp, _outpw, _outpd, _inp, _inpw_inpd 함수가 제거되었습니다._outp and _inp The functions _outp, _outpw, _outpd, _inp, _inpw, and _inpd have been removed.

<stdlib.h>, <malloc.h> 및 <sys/stat.h><stdlib.h>, <malloc.h>, and <sys/stat.h>

  • strtof 및 wcstof The strtof 및 wcstof functions failed to set errno to ERANGE when the value was not representable as a float.strtof and wcstof The strtof and wcstof functions failed to set errno to ERANGE when the value was not representable as a float. 이 문제는 수정되었습니다.This has been fixed. 이 오류는 이들 두 함수에만 발생했고 strtod, wcstod, strtold 및 wcstold 함수는 영향을 받지 않았습니다. 이는 런타임 관련 주요 변경 내용입니다.(Note that this error was specific to these two functions; the strtod, wcstod, strtold, and wcstold functions were unaffected.) This is a runtime breaking change.

  • 맞춤 할당 함수 이전 버전에서 맞춤 할당 함수(_aligned_malloc, _aligned_offset_malloc 등)는 정렬이 0인 블록에 대한 요청을 자동으로 수락했습니다.Aligned allocation functions In previous versions, the aligned allocation functions (_aligned_malloc, _aligned_offset_malloc, etc.) would silently accept requests for a block with an alignment of 0. 요청된 맞춤은 0이 아닌 2의 거듭제곱이어야 합니다.The requested alignment must be a power of two, which zero is not. 이 문제는 해결되었고 요청된 맞춤 0은 현재 잘못된 매개 변수로 처리됩니다.This has been fixed, and a requested alignment of 0 is now treated as an invalid parameter. 이는 런타임 관련 주요 변경 내용입니다.This is a runtime breaking change.

  • 힙 함수 _heapadd, _heapset 및 _heapused 함수가 제거되었습니다.Heap functions The _heapadd, _heapset, and _heapused functions have been removed. Windows 힙을 사용하도록 CRT가 업데이트된 후에는 이들 함수가 작동하지 않았습니다.These functions have been nonfunctional since the CRT was updated to use the Windows heap.

  • smallheap smalheap 링크 옵션이 제거되었습니다.smallheap The smalheap link option has been removed. 링크 옵션을 참조하세요.See Link Options.

<string.h><string.h>

  • wcstok wcstok 함수의 서명이 C 표준에 필요한 서명과 일치하도록 변경되었습니다.wcstok The signature of the wcstok function has been changed to match what is required by the C Standard. 이전 라이브러리 버전에서 이 함수의 서명은 다음과 같았습니다.In previous versions of the library, the signature of this function was:

    wchar_t* wcstok(wchar_t*, wchar_t const*)  
    

    내부 스레드 단위 컨텍스트를 사용하여 strtok의 경우와 마찬가지로 호출 전체에서 상태를 추적했습니다.It used an internal, per-thread context to track state across calls, as is done for strtok. 현재 이 함수는 시그니처 wchar_t* wcstok(wchar_t*, wchar_t const*, wchar_t**)를 포함하고 호출자가 컨텍스트를 세 번째 인수로 함수에 전달하도록 요구합니다.The function now has the signature wchar_t* wcstok(wchar_t*, wchar_t const*, wchar_t**), and requires the caller to pass the context as a third argument to the function.

    쉽게 이식하도록 이전 서명과 함께 새 _wcstok 함수가 추가되었습니다.A new _wcstok function has been added with the old signature to ease porting. C++ 코드를 컴파일할 때 이전 서명이 포함된 wcstok의 인라인 오버로드도 있습니다.When compiling C++ code, there is also an inline overload of wcstok that has the old signature. 이 오버로드는 deprecated로 선언되었습니다.This overload is declared as deprecated. C 코드에서 _CRT_NON_CONFORMING_WCSTOK를 정의하여 _wcstok를 현재 위치에서 사용하도록 할 수 있습니다.In C code, you may define_CRT_NON_CONFORMING_WCSTOK to cause _wcstok to be used in place of wcstok.

<time.h><time.h>

  • clock 이전 버전에서 clock 함수는 Windows API GetSystemTimeAsFileTime을 사용하여 구현되었습니다.clock In previous versions, the clock function was implemented using the Windows API GetSystemTimeAsFileTime. 이 구현을 통해 clock 함수는 시스템 시간에 따라 달라지므로 단조일 필요가 없었습니다.With this implementation, the clock function was sensitive to the system time, and was thus not necessarily monotonic. clock 함수는 QueryPerformanceCounter (영문)를 기준으로 다시 구현되었으며 현재는 단조입니다.The clock function has been reimplemented in terms of QueryPerformanceCounter and is now monotonic.

  • fstat 및 _utime 이전 버전에서 _stat, fstat_utime 함수는 일광 절약 시간제를 잘못 처리합니다.fstat and _utime In previous versions, the _stat, fstat, and _utime functions handle daylight savings time incorrectly. Visual Studio 2013 이전에는 이들 함수가 모두 표준시 시간을 일광 절약 시간인 것처럼 잘못 조정했습니다.Prior to Visual Studio 2013, all of these functions incorrectly adjusted standard time times as if they were in daylight time.

    Visual Studio 2013에서 이 문제는 _stat 함수 패밀리에서 수정되었지만 fstat 및 _utime 함수 패밀리에서는 비슷한 문제가 수정되지 않았습니다.In Visual Studio 2013, the problem was fixed in the _stat family of functions, but the similar problems in the fstat and _utime families of functions were not fixed. 이로 인해 함수가 일치하지 않아 문제가 발생했습니다.This led to problems due to the inconsistency between the functions. 현재 fstat 및 _utime 함수 패밀리가 수정되었으므로 현재 이들 함수는 모두 일광 절약 시간제를 올바르고 일관되게 처리합니다.The fstat and _utime families of functions have now been fixed, so all of these functions now handle daylight savings time correctly and consistently.

  • asctime 이전 버전에서 asctime 함수는 한 자리 일 단위의 앞에 0을 추가했습니다(예: Fri Jun 06 08:00:00 2014).asctime In previous versions, the asctime function would pad single-digit days with a leading zero, for example: Fri Jun 06 08:00:00 2014. 사양에 따라 해당 일 단위의 앞에는 공백이 추가되어야 합니다(예: Fri Jun 6 08:00:00 2014).The specification requires that such days be padded with a leading space, e.g. Fri Jun 6 08:00:00 2014. 이 문제는 수정되었습니다.This has been fixed.

  • strftime 및 wcsftime The strftime 및 wcsftime functions now support the %C, %D, %e, %F, %g, %G, %h, %n, %r, %R, %t, %T, %u, and %V format specifiers.strftime and wcsftime The strftime and wcsftime functions now support the %C, %D, %e, %F, %g, %G, %h, %n, %r, %R, %t, %T, %u, and %V format specifiers. 또한 E 및 O 수정자는 구문 분석되지만 무시됩니다.Additionally, the E and O modifiers are parsed but ignored.

    %c 서식 지정자는 현재 로캘에 대한 "적절한 날짜 및 시간 표현"을 생성하도록 지정됩니다.The %c format specifier is specified as producing an "appropriate date and time representation" for the current locale. C 로캘에서 이 표현은 %a %b %e %T %Y와 같아야 합니다.In the C locale, this representation is required to be the same as %a %b %e %T %Y. 이 표현은 asctime에서 생성된 것과 같은 형식입니다.This is the same form as is produced by asctime. 이전 버전에서 %c 서식 지정자는 MM/DD/YY HH:MM:SS 표현을 사용하여 시간 서식을 잘못 지정했습니다.In previous versions, the %c format specifier incorrectly formatted times using a MM/DD/YY HH:MM:SS representation. 이 문제는 수정되었습니다.This has been fixed.

  • timespec 및 TIME_UTC 현재 <time.h> 헤더는 C11 표준에 따라 timespec 형식 및 timespec_get 함수를 정의합니다.timespec and TIME_UTC The <time.h> header now defines the timespec type and the timespec_get function from the C11 Standard. 또한 현재 timespec_get 함수와 함께 사용할 TIME_UTC 매크로가 정의됩니다.In addition, the TIME_UTC macro, for use with the timespec_get function, is now defined. 이는 이들에 대해 충돌하는 정의가 있는 코드의 주요 변경 내용입니다.This is a breaking change for code that has a conflicting definition for any of these.

  • CLOCKS_PER_SEC 현재 CLOCKS_PER_SEC 매크로는 C 언어에 필요한 형식 clock_t의 정수로 확장됩니다.CLOCKS_PER_SEC The CLOCKS_PER_SEC macro now expands to an integer of type clock_t, as required by the C language.

C++ 표준 라이브러리C++ Standard Library

새로운 최적화 및 디버깅 검사를 사용하려면 C++ 표준 라이브러리의 Visual Studio 구현은 버전별로 바이너리 호환성을 의도적으로 변경합니다.To enable new optimizations and debugging checks, the Visual Studio implementation of the C++ Standard Library intentionally breaks binary compatibility from one version to the next. 따라서 C++ 표준 라이브러리가 사용되면 서로 다른 버전을 사용하여 컴파일된 개체 파일 및 정적 라이브러리를 하나의 바이너리(EXE 또는 DLL)에 혼합할 수 없고 C++ 표준 라이브러리 개체는 서로 다른 버전을 사용하여 컴파일된 바이너리 사이에서 전달할 수 없습니다.Therefore, when the C++ Standard Library is used, object files and static libraries that are compiled by using different versions can't be mixed in one binary (EXE or DLL), and C++ Standard Library objects can't be passed between binaries that are compiled by using different versions. 그렇게 혼합하면 _MSC_VER 불일치에 대한 링커 오류를 내보냅니다.Such mixing emits linker errors about _MSC_VER mismatches. _MSC_VER은 컴파일러의 주 버전(예: Visual Studio 2013의 경우 1800)이 포함된 매크로입니다. 이 검사에서는 DLL 혼합을 비롯하여 Visual C++ 2008 또는 이전 버전과 관련된 혼합을 감지할 수 없습니다.(_MSC_VER is the macro that contains the compiler's major version—for example, 1800 for Visual Studio 2013.) This check cannot detect DLL mixing, and cannot detect mixing that involves Visual C++ 2008 or earlier.

  • C++ 표준 라이브러리 포함 파일 C++ 표준 라이브러리 헤더의 include 구조체에 몇 가지 변경 내용이 적용되었습니다.C++ Standard Library include files Some changes have been made to the include structure in the C++ Standard Library headers. C++ 표준 라이브러리 헤더는 서로 지정되지 않는 방식으로 포함할 수 있습니다.C++ Standard Library headers are allowed to include each other in unspecified ways. 일반적으로 C++ 표준에 따라 필요한 모든 헤더를 신중하게 포함하고 다른 C++ 표준 라이브러리 헤더를 포함하는 C++ 표준 라이브러리 헤더를 사용하지 않도록 코드를 작성해야 합니다.In general, you should write your code so that it carefully includes all of the headers that it needs according to the C++ standard and doesn't rely on which C++ Standard Library headers include which other C++ Standard Library headers. 이렇게 하면 버전 및 플랫폼 간에 코드를 이식할 수 있습니다.This makes code portable across versions and platforms. Visual Studio 2015에서 두 개 이상의 헤더 변경 내용이 사용자 코드에 영향을 줍니다.At least two header changes in Visual Studio 2015 affect user code. 첫 번째, <string>은 더 이상 <iterator>를 포함하지 않습니다.First, <string> no longer includes <iterator>. 두 번째, <tuple>은 현재 모든 <array>를 포함하지 않고 std::array를 선언하여 다음 생성자 구문 조합을 통해 코드를 분할합니다. 코드에 "array" 변수가 있고, using 지시문 "using namespace std;"를 포함하고, 현재 std::array를 선언하는 <tuple>이 포함된 C++ 표준 라이브러리 헤더(예: <functional>)를 포함합니다.Second, <tuple> now declares std::array without including all of <array>, which can break code through the following combination of code constructs: your code has a variable named "array", and you have a using-directive "using namespace std;", and you include a C++ Standard Library header (such as <functional>) that includes <tuple>, which now declares std::array.

  • steady_clock steady_clock의 <chrono> 구현은 지속성 및 단조성에 대한 C++ 표준 요구 사항을 충족하도록 변경되었습니다.steady_clock The <chrono> implementation of steady_clock has changed to meet the C++ Standard requirements for steadiness and monotonicity. 이제 steady_clock은 QueryPerformanceCounter (영문)를 기반으로 하고 high_resolution_clock은 steady_clock에 대한 typedef입니다.steady_clock is now based on QueryPerformanceCounter and high_resolution_clock is now a typedef for steady_clock. 따라서 Visual C++에서 steady_clock::time_point는 현재 chrono::time_point<steady_clock>에 대한 typedef이나, 다른 구현에 이를 반드시 적용할 필요는 없습니다.As a result, in Visual C++ steady_clock::time_point is now a typedef for chrono::time_point<steady_clock>; however, this is not necessarily the case for other implementations.

  • allocator 및 const 현재 양쪽에서 const 인수를 수락하려면 allocator 같음/같지 않음 비교가 필요합니다.allocators and const We now require allocator equality/inequality comparisons to accept const arguments on both sides. allocator가 이들 연산자를 다음과 같이 정의할 경우:If your allocators define these operators as follows:

    bool operator==(const MyAlloc& other)  
    

    이들 연산자를 업데이트하여 const 멤버로 선언해야 합니다.You should update these to declare them as const members.

    bool operator==(const MyAlloc& other) const  
    
  • const elements C++ 표준에서는 const 요소의 컨테이너(예: vector<const T> 또는 set<const T>)를 항상 금지했습니다.const elements The C++ standard has always forbidden containers of const elements (such as vector<const T> or set<const T>). Visual C++ 2013 이하에서는 해당 컨테이너를 허용했습니다.Visual C++ 2013 and earlier accepted such containers. 현재 버전에서는 해당 컨테이너가 컴파일되지 않습니다.In the current version, such containers fail to compile.

  • std::allocator::deallocate Visual C++ 2013 이하에서 std::allocator::deallocate(p, n)는 n으로 전달된 인수를 무시했습니다.std::allocator::deallocate In Visual C++ 2013 and earlier, std::allocator::deallocate(p, n) ignored the argument passed in for n. C++ 표준에서 n은 항상 p를 반환한 allocate의 호출에 첫 번째 인수로 전달된 값과 같아야 합니다.The C++ standard has always required that n be equal to the value passed as the first argument to the invocation of allocate which returned p. 그러나 현재 버전에서는 n 값이 검사됩니다.However, in the current version, the value of n is inspected. 표준에 필요한 값과 다른 n에 대한 인수를 전달하는 코드는 런타임에 충돌을 가져올 수 있습니다.Code that passes arguments for n that differ from what the standard requires might crash at runtime.

  • hash_map 및 hash_set 비표준 헤더 파일 hash_map 및 hash_set은 Visual Studio 2015에서 사용되지 않고 이후 릴리스에서 제거될 예정입니다.hash_map and hash_set The non-standard header files hash_map and hash_set are deprecated in Visual Studio 2015 and will be removed in a future release. 대신에 unordered_map 및 unordered_set을 사용하세요.Use unordered_map and unordered_set instead.

  • 비교 연산자 및 operator() 현재 연관 컨테이너(<map> 패밀리)에서 const 호출 가능 함수 호출 연산자를 포함하려면 비교 연산자가 필요합니다.comparators and operator() Associative containers (the <map> family) now require their comparators to have const-callable function call operators. 현재 비교 연산자 클래스 선언에서 다음 코드는 컴파일되지 않습니다.The following code in a comparator class declaration now fails to compile:

    bool operator()(const X& a, const X& b)  
    

    이 오류를 해결하려면 함수 선언을 다음으로 변경합니다.To resolve this error, change the function declaration to:

    bool operator()(const X& a, const X& b) const  
    
  • 형식 특성 The old names for 형식 특성 from an earlier version of the C++ draft standard have been removed.type traits The old names for type traits from an earlier version of the C++ draft standard have been removed. 이 이름은 C++11에서 변경되었고 Visual Studio 2015에서 C++11 값으로 업데이트되었습니다.These were changed in C++11 and have been updated to the C++11 values in Visual Studio 2015. 다음 표에서는 이전 이름과 새 이름을 보여 줍니다.The following table shows the old and new names.

    이전 이름Old name 새 이름New name
    add_referenceadd_reference add_lvalue_referenceadd_lvalue_reference
    has_default_constructorhas_default_constructor is_default_constructibleis_default_constructible
    has_copy_constructorhas_copy_constructor is_copy_constructibleis_copy_constructible
    has_move_constructorhas_move_constructor is_move_constructibleis_move_constructible
    has_nothrow_constructorhas_nothrow_constructor is_nothrow_default_constructibleis_nothrow_default_constructible
    has_nothrow_default_constructorhas_nothrow_default_constructor is_nothrow_default_constructibleis_nothrow_default_constructible
    has_nothrow_copyhas_nothrow_copy is_nothrow_copy_constructibleis_nothrow_copy_constructible
    has_nothrow_copy_constructorhas_nothrow_copy_constructor is_nothrow_copy_constructibleis_nothrow_copy_constructible
    has_nothrow_move_constructorhas_nothrow_move_constructor is_nothrow_move_constructibleis_nothrow_move_constructible
    has_nothrow_assignhas_nothrow_assign is_nothrow_copy_assignableis_nothrow_copy_assignable
    has_nothrow_copy_assignhas_nothrow_copy_assign is_nothrow_copy_assignableis_nothrow_copy_assignable
    has_nothrow_move_assignhas_nothrow_move_assign is_nothrow_move_assignableis_nothrow_move_assignable
    has_trivial_constructorhas_trivial_constructor is_trivially_default_constructibleis_trivially_default_constructible
    has_trivial_default_constructorhas_trivial_default_constructor is_trivially_default_constructibleis_trivially_default_constructible
    has_trivial_copyhas_trivial_copy is_trivially_copy_constructibleis_trivially_copy_constructible
    has_trivial_move_constructorhas_trivial_move_constructor is_trivially_move_constructibleis_trivially_move_constructible
    has_trivial_assignhas_trivial_assign is_trivially_copy_assignableis_trivially_copy_assignable
    has_trivial_move_assignhas_trivial_move_assign is_trivially_move_assignableis_trivially_move_assignable
    has_trivial_destructorhas_trivial_destructor is_trivially_destructibleis_trivially_destructible
  • launch::any 및 launch::sync 정책 The nonstandard launch::any 및 launch::sync 정책 were removed.launch::any and launch::sync policies The nonstandard launch::any and launch::sync policies were removed. 대신에 launch::any의 경우 launch:async | launch:deferred를 사용합니다.Instead, for launch::any, use launch:async | launch:deferred. launch::sync의 경우 launch::deferred를 사용합니다.For launch::sync, use launch::deferred. launch 열거형을 참조하세요.See launch Enumeration.

MFC 및 ATLMFC and ATL

  • MFC(Microsoft Foundation Classes) 는 큰 크기로 인해 더 이상 Visual Studio의 "일반" 설치에 포함되지 않습니다.Microsoft Foundation Classes (MFC) is no longer included in a "Typical" install of Visual Studio because of its large size. MFC를 설치하려면 Visual Studio 2015 설치 프로그램에서 사용자 지정 설치 옵션을 선택합니다.To install MFC, choose the Custom install option in Visual Studio 2015 setup. Visual Studio 2015가 설치되어 있으면 Visual Studio 설치 프로그램을 다시 실행하고 사용자 지정 설치 옵션을 선택하고 Microsoft Foundation Classes를 선택하여 MFC를 설치할 수 있습니다.If you already have Visual Studio 2015 installed, you can install MFC by re-running Visual Studio setup, choosing the Custom install option, and choosing Microsoft Foundation Classes. 제어판, 프로그램 및 기능에서 또는 설치 미디어에서 Visual Studio 설치 프로그램을 다시 실행할 수 있습니다.You can re-run Visual Studio setup from the Control Panel, Programs and Features, or from the installation media.

    Visual C++ 재배포 가능 패키지에는 이 라이브러리가 계속 포함됩니다.The Visual C++ Redistributable Package still includes this library.

동시성 런타임Concurrency Runtime

  • concurrency::Context::Yield와 충돌하는 Windows.h의 Yield 매크로입니다. 이전 동시성 런타임은 Windows.h h에 정의된 Yield 매크로와 concurrency::Context::Yield 함수의 충돌을 피하려고 #undef를 사용하여 Yield 매크로의 정의를 해제했습니다.Yield macro from Windows.h conflicting with concurrency::Context::Yield The Concurrency Runtime previously used #undef to undefine the Yield macro to avoid conflicts between the Yield macro defined in Windows.h h and the concurrency::Context::Yield function. 이 #undef는 제거되었고 새로운 충돌하지 않는 동등한 API 호출 concurrency::Context::YieldExecution 이 추가되었습니다.This #undef has been removed and a new non-conflicting equivalent API call concurrency::Context::YieldExecution has been added. Yield 충돌을 해결하려면 코드를 업데이트하여 대신 YieldExecution 함수를 호출하거나, 다음 예제와 같이 호출 쪽에서 Yield 함수 이름을 괄호로 묶습니다.To work around conflicts with Yield, you can either update your code to call the YieldExecution function instead, or surround the Yield function name with parentheses at call sites, as in the following example:

    (concurrency::Context::Yield)();  
    

Visual C++ 2015의 컴파일러 규칙 향상Compiler Conformance Improvements in Visual C++ 2015

이전 버전에서 코드를 업그레이드하는 경우 Visual C++ 2015의 규칙 향상으로 인한 컴파일러 오류가 발생할 수도 있습니다.When upgrading code from previous versions, you might also encounter compiler errors that are due to conformance improvements made in Visual C++ 2015. 이러한 향상된 기능 때문에 이전 버전의 Visual C++에서 이진 호환성이 중단되지는 않지만 이전에는 발생하지 않았던 컴파일러 오류가 생성될 수 있습니다.These improvements do not break binary compatibility from earlier versions of Visual C++, but they can produce compiler errors where none were emitted before. 자세한 내용은 Visual C++ 2003 ~ 2015의 새로운 기능을 참조하세요.For more information, see Visual C++ What's New 2003 through 2015.

Visual C++ 2015에서 컴파일러 규칙 개선 작업이 진행 중이므로 컴파일러에서 기존 소스 코드를 인식하는 방식이 변경될 수 있습니다.In Visual C++ 2015, ongoing improvements to compiler conformance can sometimes change how the compiler understands your existing source code. 이로 인해 빌드 중 새로운 오류 또는 다른 오류가 발생하거나, 이전에 빌드되어 올바르게 실행되는 것처럼 보이는 코드가 다르게 동작할 수도 있습니다.When this happens, you might encounter new or different errors during your build, or even behavioral differences in code that previously built and seemed to run correctly.

다행히 이러한 차이는 대부분의 소스 코드에 거의 또는 전혀 영향을 주지 않으며, 차이를 해결하기 위해 소스 코드 변경이나 기타 변경이 필요한 경우에도 대체로 간단히 처리할 수 있는 사소한 수정입니다.Fortunately, these differences have little or no impact on most of your source code and when source code or other changes are needed to address these differences, fixes are usually small and straight-forward. 이전에는 허용되는 소스 코드였지만 변경해야 할 수 있는 코드(이전) 및 수정 코드(이후)의 많은 예가 포함되어 있습니다.We've included many examples of previously-acceptable source code that might need to be changed (before) and the fixes to correct them (after).

이러한 차이가 소스 코드나 다른 빌드 아티팩트에 영향을 줄 수도 있지만 Visual C++ 버전 업데이트 간의 이진 호환성에는 영향을 주지 않습니다.Although these differences can affect your source code or other build artifacts, they don't affect binary compatibility between updates to Visual C++ versions. 보다 심각한 종류의 변경인 주요 변경 내용은 이진 호환성에 영향을 줄 수 있지만 이러한 종류의 이진 호환성 중단은 Visual C++의 주 버전 간에만 발생합니다.A more-severe kind of change, the breaking change can affect binary compatibility, but these kinds of binary compatibility breaks only occur between major versions of Visual C++. 예를 들어 Visual C++ 2013과 Visual C++ 2015 간에 발생합니다.For example, between Visual C++ 2013 and Visual C++ 2015. Visual C++ 2013과 Visual C++ 2015 사이에 발생한 주요 변경 내용에 대한 자세한 내용은 Visual C++ 2015 규칙 변경 내용을 참조하세요.For information on the breaking changes that occurred between Visual C++ 2013 and Visual C++ 2015, see Visual C++ 2015 Conformance Changes.

Visual C++ 2015의 규칙 향상Conformance Improvements in Visual C++ 2015

  • /Zc:forScope- 옵션/Zc:forScope- option

    /Zc:forScope- 컴파일러 옵션은 사용되지 않으므로 이후 릴리스에서 제거될 예정입니다.The compiler option /Zc:forScope- is deprecated and will be removed in a future release.

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

    옵션은 대개 표준에 따라 범위를 벗어나야 하는 지점 뒤에서 루프 변수를 사용하는 비표준 코드를 허용하려고 사용됩니다.The option was usually used in order to allow nonstandard code that uses loop variables after the point where, according to the standard, they should have gone out of scope. /Za를 사용하지 않으면 루프 끝에 for 루프 변수를 항상 사용할 수 있으므로 /Za 옵션으로 컴파일할 경우에만 필요합니다.It was only necessary when you are compiling with the /Za option, since without /Za, using a for loop variable after the end of the loop is always allowed. 표준 준수가 중요하지 않으면(예: 코드가 다른 컴파일러에 이식 가능하지 않은 경우) /Za 옵션을 해제하거나 언어 확장 사용 안 함 속성을 아니요로 설정할 수 있습니다.If you don't care about standards conformance (for example, if your code isn't meant to portable to other compilers), you could turn off the /Za option (or set the Disable Language Extensions property to No). 이식 가능한 표준 규격 코드를 작성해야 하면 변수의 선언을 루프 외부 지점으로 이동하여 표준을 따르도록 코드를 다시 작성해야 합니다.If you do care about writing portable, standards-compliant code, you should rewrite your code so that it conforms to the standard by moving the declaration of such variables to a point outside the loop.

    // C2065 expected  
    int main() {  
        // Uncomment the following line to resolve.  
        // int i;  
        for (int i = 0; i < 1; i++);  
        i = 20;   // i has already gone out of scope under /Za  
    }  
    
  • /Zg 컴파일러 옵션/Zg compiler option

    /Zg 컴파일러 옵션(함수 프로토타입 생성)은 더 이상 사용할 수 없습니다.The /Zg compiler option (Generate Function Prototypes) is no longer available. 이 컴파일러 옵션은 이미 사용되지 않습니다.This compiler option was previously deprecated.

  • mstest.exe를 사용하여 명령줄에서 C++/CLI에 대한 단위 테스트를 더 이상 실행할 수 없습니다.You can no longer run unit tests with C++/CLI from the command-line with mstest.exe. 대신에 vstest.console.exe를 사용하세요.Instead, use vstest.console.exe. VSTest.Console.exe 명령줄 옵션을 참조하세요.See VSTest.Console.exe command-line options.

  • mutable 키워드mutable keyword

    이전에 오류 없이 컴파일했던 위치에서 mutable 저장소 클래스 지정자가 더 이상 허용되지 않습니다.The mutable storage class specifier is no longer allowed in places where previously it compiled without error. 현재 컴파일러에서는 오류 C2071(저장소 클래스가 잘못되었습니다.)을 표시합니다.Now, the compiler gives error C2071 (illegal storage class). 표준에 따라 mutable 지정자는 클래스 데이터 멤버의 이름에만 적용되고 const 또는 static으로 선언된 이름과 참조 멤버에는 적용할 수 없습니다.According to the standard, the mutable specifier can be applied only to names of class data members, and cannot be applied to names declared const or static, and cannot be applied to reference members.

    예를 들어, 다음 코드를 고려하세요.For example, consider the following code:

    struct S   
    {  
        mutable int &r;  
    };  
    

    이전 Visual C++ 컴파일러 버전에서는 이를 허용했으나 현재 컴파일러에서는 다음 오류를 표시합니다.Previous versions of the Visual C++ compiler accepted this, but now the compiler gives the following error:

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

    오류를 수정하려면 중복 mutable 키워드를 제거하세요.To fix the error, simply remove the redundant mutable keyword.

  • char_16_t 및 char32_tchar_16_t and char32_t

    char16_t 또는 char32_t 형식은 현재 기본 제공으로 처리되므로 typedef에서 이들 형식을 별칭으로 더 이상 사용할 수 없습니다.You can no longer use char16_t or char32_t as aliases in a typedef, because these types are now treated as built-in. 사용자와 라이브러리 작성자가 char16_t 및 char32_t를 각각 uint16_t 및 uint32_t의 별칭으로 정의하는 것이 일반적이었습니다.It was common for users and library authors to define char16_t and char32_t as aliases of uint16_t and uint32_t, respectively.

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

    코드를 업데이트하려면 typedef 선언을 제거하고 이들 이름과 충돌하는 다른 식별자의 이름을 바꿉니다.To update your code, remove the typedef declarations and rename any other identifiers that collide with these names.

  • 비형식 템플릿 매개 변수Non-type template parameters

    이제는 비형식 템플릿 매개 변수가 포함된 특정 코드에 명시적 템플릿 인수를 제공하면 형식 호환성 검사가 정확하게 수행됩니다.Certain code that involves non-type template parameters is now correctly checked for type compatibility when you provide explicit template arguments. 예를 들어 다음 코드는 이전 Visual C++ 버전에서는 오류 없이 컴파일되었습니다.For example, the following code compiled without error in previous versions of Visual C++.

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

    템플릿 매개 변수 형식이 템플릿 인수와 일치하지 않기 때문에 현재 컴파일러에서 제대로 오류를 표시합니다. 매개 변수는 const 멤버의 포인터이나 f 함수는 비const입니다.The current compiler correctly gives an error, because the template parameter type doesn't match the template argument (the parameter is a pointer to a const member, but the function f is non-const):

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

    코드에서 이 오류를 해결하려면 사용하는 템플릿 인수 형식이 템플릿 매개 변수의 선언된 형식과 일치해야 합니다.To address this error in your code, make sure that the type of the template argument you use matches the declared type of the template parameter.

  • __declspec(align)__declspec(align)

    컴파일러가 함수에서 __declspec(align) 을 더 이상 허용하지 않습니다.The compiler no longer accepts __declspec(align) on functions. 이는 항상 무시되었지만 현재는 컴파일러 오류가 생성됩니다.This was always ignored, but now it produces a compiler error.

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

    이 문제를 수정하려면 함수 선언에서 __declspec(align) 을 제거합니다.To fix this problem, remove __declspec(align) from the function declaration. 아무런 영향이 없으므로 제거해도 아무것도 변경되지 않습니다.Since it had no effect, removing it does not change anything.

  • 예외 처리Exception handling

    예외 처리에 대한 몇 가지 변경 내용이 있습니다.There are a couple of changes to exception handling. 먼저 예외 개체는 복사 가능하거나 이동 가능해야 합니다.First, exception objects have to be either copyable or movable. 다음 코드는 --- --- Visual Studio 2013의 Visual C++Visual C++ in Visual Studio 2013에서 컴파일되었지만 --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015에서는 컴파일되지 않습니다.The following code compiled in --- --- Visual Studio 2013의 Visual C++Visual C++ in Visual Studio 2013, but does not compile in --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015:

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

    문제는 복사 생성자가 private이라는 점이므로 일반적인 예외 처리 과정으로는 개체를 복사할 수 없습니다.The problem is that the copy constructor is private, so the object cannot be copied as happens in the normal course of handling an exception. 복사 생성자가 explicit로 선언될 경우에도 마찬가지입니다.The same applies when the copy constructor is declared explicit.

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

    코드를 업데이트하려면 예외 개체에 대한 복사 생성자가 public이고 explicit로 표시되지 않아야 합니다.To update your code, make sure that the copy constructor for your exception object is public and not marked explicit.

    값으로 예외를 catch하려면 예외 개체가 복사 가능해야 합니다.Catching an exception by value also requires the exception object to be copyable. 다음 코드는 --- --- Visual Studio 2013의 Visual C++Visual C++ in Visual Studio 2013에서 컴파일되었지만 --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015에서는 컴파일되지 않습니다.The following code compiled in --- --- Visual Studio 2013의 Visual C++Visual C++ in Visual Studio 2013, but does not compile in --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015:

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

    참조에 대한 catch 의 매개 변수 형식을 변경하여 이 문제를 해결할 수 있습니다.You can fix this issue by changing the parameter type for the catch to a reference.

    catch (D& d)  
    {  
    }  
    
  • 매크로 뒤의 문자열 리터럴String literals followed by macros

    현재 컴파일러는 사용자 정의 리터럴을 지원합니다.The compiler now supports user defined literals. 따라서 중간 공백 없이 매크로 뒤의 문자열 리터럴은 오류나 예기치 않은 결과를 생성할 수 있는 사용자 정의 리터럴로 해석됩니다.As a consequence, string literals followed by macros without any intervening whitespace are interpreted as user-defined literals, which might produce errors or unexpected results. 예를 들어 이전 컴파일러에서는 다음 코드가 성공적으로 컴파일되었습니다.For example, in previous compilers the following code compiled successfully:

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

    컴파일러에서 이 코드는 매크로 뒤의 문자열 리터럴 "hello"로 해석되고 “there”로 확장되었고 두 문자열 리터럴은 하나로 연결되었습니다.The compiler interpreted this as a string literal "hello" followed by a macro, which is expanded "there", and then the two string literals were concatenated into one. --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015에서 컴파일러는 이 코드를 사용자 정의 리터럴로 해석하지만 일치하는 사용자 정의 리터럴 _x가 정의되지 않았으므로 오류가 발생합니다.In --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015, the compiler interprets this as a user-defined literal, but since there is no matching user-defined literal _x defined, it gives an error.

    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?  
    

    이 문제를 수정하려면 문자열 리터럴과 매크로 사이에 공백을 추가합니다.To fix this problem, add a space between the string literal and the macro.

  • 인접 문자열 리터럴Adjacent string literals

    이전과 비슷하게 문자열 구문 분석의 관련 변경 내용 때문에 공백이 없는 인접 문자열 리터럴(전각 또는 반각 문자 문자열 리터럴)은 이전 Visual C++ 릴리스에서 하나의 연결된 문자열로 해석되었습니다.Similarly to the previous, due to related changes in string parsing, adjacent string literals (either wide or narrow character string literals) without any whitespace were interpreted as a single concatenated string in previous releases of Visaul C++. --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015에서는 현재 두 문자열 사이에 공백을 추가해야 합니다.In --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015, you must now add whitespace between the two strings. 예를 들어 다음 코드를 변경해야 합니다.For example, the following code must be changed:

    char * str = "abc""def";  
    

    두 문자열 사이에 공백을 추가하면 됩니다.Simply add a space in between the two strings.

    char * str = "abc" "def";  
    
  • Placement new 및 deletePlacement new and delete

    delete 연산자는 C++14 표준을 준수하도록 변경되었습니다.A change has been made to the delete operator in order to bring it into conformance with C++14 standard. 표준 변경에 대한 자세한 내용은 C++ 크기 지정된 할당 해제(영문)를 참조하세요.Details of the standards change can be found at C++ Sized Deallocation. 변경을 통해 size 매개 변수를 사용하는 전역 delete 연산자의 형식이 추가됩니다.The changes add a form of the global delete operator that takes a size parameter. 주요 변경 내용에 따르면 이전에는 placement new 연산자와 일치하도록 같은 서명으로 delete 연산자를 사용하면 placement new가 사용된 지점에서 컴파일러 오류(C2956)가 발생했습니다. 이 지점은 컴파일러가 해당하는 일치 delete 연산자를 식별하려고 하는 코드의 위치이기 때문입니다.The breaking change is that if you were previously using an operator delete with the same signature (to correspond with a placement new operator), you will receive a compiler error (C2956, which occurs at the point where the placement new is used, since that's the position in code where the compiler tries to identify an appropriate matching delete operator).

    void operator delete(void *, size_t) 함수는 C++11의 placement new 함수 "void * 연산자 new(size_t, size_t)"와 일치하는 placement delete 연산자였습니다.The function void operator delete(void *, size_t) was a placement delete operator corresponding to the placement new function "void * operator new(size_t, size_t)" in C++11. C++14 크기 지정된 할당 해제를 사용하면 이 delete 함수는 현재 usual deallocation 함수 (전역 delete 연산자)입니다.With C++14 sized deallocation, this delete function is now a usual deallocation function (global delete operator). 표준에 따르면 placement new를 사용하여 해당하는 delete 함수를 조회하고 usual deallocation 함수를 찾으면 프로그램에 잘못된 형식이 사용됩니다.The standard requires that if the use of a placement new looks up a corresponding delete function and finds a usual deallocation function, the program is ill-formed.

    예를 들어 코드에서 placement new 및 placement delete를 둘 다 정의한다고 가정합니다.For example, suppose your code defines both a placement new and a placement delete:

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

    정의한 placement delete 연산자와 새 전역 크기 지정된 delete 연산자 간에 함수 서명이 일치하기 때문에 문제가 발생합니다.The problem occurs because of the match in function signatures between a placement delete operator you've defined, and the new global sized delete operator. placement new 및 delete 연산자에 대해 size_t 이외의 다른 연산자를 사용할 수 있는지를 고려하세요.Consider whether you can use a different type other than size_t for any placement new and delete operators. size_t typedef의 형식은 컴파일러에 따라 결정되고 Visual C++에서는 부호 없는 int에 대한 typedef입니다.Note that the type of the size_t typedef is compiler-dependent; it is a typedef for unsigned int in Visual C++. 이 문제를 해결하려면 다음과 같은 열거된 형식을 사용하는 것이 좋습니다.A good solution is to use an enumerated type such as this:

    enum class my_type : size_t {};  
    

    그다음에 size_t 대신 이 형식을 두 번째 인수로 사용하도록 placement new 및 delete의 정의를 변경합니다.Then, change your definition of placement new and delete to use this type as the second argument instead of size_t. placement new에 대한 호출을 업데이트하여 새 형식을 전달하고(예: static_cast<my_type> 을 사용하여 정수 값에서 변환) new 및 delete의 정의를 업데이트하여 다시 정수 형식으로 캐스팅해야 합니다.You’ll also need to update the calls to placement new to pass the new type (for example, by using static_cast<my_type> to convert from the integer value) and update the definition of new and delete to cast back to the integer type. 여기에 열거형을 사용할 필요가 없고 size_t 멤버가 있는 클래스 형식도 사용할 수 있습니다.You don’t need to use an enum for this; a class type with a size_t member would also work.

    또 다른 솔루션은 placement new를 함께 제거하는 것입니다.An alternative solution is that you might be able to eliminate the placement new altogether. 코드에서 placement new를 사용하여 placement 인수가 할당되거나 삭제되는 개체 크기와 같은 메모리 풀을 구현하면 사용자 지정 메모리 풀 코드를 바꾸는 데는 크기 지정된 할당 해제 기능이 적합할 수 있고, placement 함수를 제거하고 placement 대신에 인수가 두 개인 delete 연산자만 사용할 수 있습니다.If your code uses placement new to implement a memory pool where the placement argument is the size of the object being allocated or deleted, then sized deallocation feature might be suitable to replace your own custom memory pool code, and you can get rid of the placement functions and just use your own two-argument delete operator instead of the placement functions.

    코드를 바로 업데이트하지 않으려면 컴파일러 옵션 /Zc:sizedDealloc-를 사용하여 이전 동작으로 되돌릴 수 있습니다.If you don't want to update your code immediately, you can revert to the old behavior by using the compiler option /Zc:sizedDealloc-. 이 옵션을 사용하면 인수가 두 개인 delete 함수가 존재하지 않으므로 placement delete 연산자와 충돌하지 않습니다.If you use this option, the two-argument delete functions don’t exist and won't cause a conflict with your placement delete operator.

  • 공용 구조체 데이터 멤버Union data members

    공용 구조체의 데이터 멤버는 더 이상 참조 형식을 포함할 수 없습니다.Data members of unions can no longer have reference types. --- --- Visual Studio 2013의 Visual C++Visual C++ in Visual Studio 2013에서는 다음 코드가 성공적으로 컴파일되었지만 --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015에서는 오류가 발생합니다.The following code compiled successfully in --- --- Visual Studio 2013의 Visual C++Visual C++ in Visual Studio 2013, but produces an error in --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015.

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

    앞의 코드에서 발생하는 오류는 다음과 같습니다.The preceding code produces the following errors:

    
    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  
    

    이 문제를 해결하려면 참조 형식을 포인터 또는 값으로 변경합니다.To address this issue, change reference types either to a pointer or a value. 형식을 포인터로 변경하려면 공용 구조체 필드를 사용하는 코드를 변경해야 합니다.Changing the type to a pointer requires changes in the code that uses the union field. 코드를 값으로 변경하면 공용 구조체에 저장된 데이터가 변경되며, union 형식의 필드는 같은 메모리를 공유하므로 이 변경이 다른 필드에 영향을 미칩니다.Changing the code to a value would change the data stored in the union, which affects other fields since fields in union types share the same memory. 값 크기에 따라 공용 구조체 크기도 변경할 수 있습니다.Depending on the size of the value, it might also change the size of the union.

  • 현재 익명 공용 구조체는 표준을 더 준수합니다.Anonymous unions are now more conformant to the standard. 이전 컴파일러 버전에서는 익명 공용 구조체에 대한 명시적 생성자 및 소멸자를 생성했습니다.Previous versions of the compiler generated an explicit constructor and destructor for anonymous unions. 이 기능은 --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015에서 삭제되었습니다.These are deleted in --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015.

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

    앞의 코드는 --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015에서 다음 오류를 생성합니다.The preceding code generates the following error in --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015:

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

    이 문제를 해결하려면 생성자 및/또는 소멸자의 정의를 제공하세요.To resolve this issue, provide your own definitions of the constructor and/or destructor.

    struct S   
    {  
        // Provide a default constructor by adding an empty function body.  
        S() {}  
    };  
    
    union   
    {  
        struct   
        {  
            S s;  
        };  
    } u;  
    
  • 익명 구조체가 있는 공용 구조체Unions with anonymous structs

    공용 구조체에서 익명 구조체 멤버의 런타임 동작이 표준을 준수하도록 변경되었습니다.In order to conform with the standard, the runtime behavior has changed for members of anonymous structures in unions. 해당 공용 구조체가 생성될 때 공용 구조체의 익명 구조체 멤버에 대한 생성자가 더 이상 암시적으로 호출되지 않습니다.The constructor for anonymous structure members in a union is no longer implicitly called when such a union is created. 또한 공용 구조체가 범위를 벗어날 때 공용 구조체의 익명 구조체 멤버에 대한 소멸자가 더 이상 암시적으로 호출되지 않습니다.Also, the destructor for anonymous structure members in a union is no longer implicitly called when the union goes out of scope. 소멸자가 있는 명명된 구조체 S 멤버가 포함된 익명 구조체가 공용 구조체 U에 들어 있는 다음 코드를 고려하세요.Consider the following code, in which a union U contains an anonymous structure that contains a member which is a named structure S that has a destructor.

    #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의 Visual C++Visual C++ in Visual Studio 2013에서 S에 대한 생성자는 공용 구조체가 생성될 때 호출되고 S에 대한 소멸자는 f 함수의 스택이 정리될 때 호출됩니다.In --- --- Visual Studio 2013의 Visual C++Visual C++ in Visual Studio 2013, the constructor for S is called when the union is created, and the destructor for S is called when the stack for function f is cleaned up. 그러나 --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015에서는 생성자와 소멸자가 호출되지 않습니다.But in --- --- Visual Studio 2015의 Visual C++Visual C++ in Visual Studio 2015, the constructor and destructor are not called. 컴파일러에서 이 동작 변경에 대해 경고를 표시합니다.The compiler gives a warning about this behavior change.

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

    원래 동작을 복원하려면 익명 구조체에 이름을 지정합니다.To restore the original behavior, give the anonymous structure a name. 익명이 아닌 구조체의 런타임 동작은 컴파일러 버전과 관계없이 동일합니다.The runtime behavior of non-anonymous structures is the same, regardless of the compiler version.

    #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;  
    }  
    

    또는 생성자 및 소멸자 코드를 새 함수로 이동하고 공용 구조체에 대한 생성자 및 소멸자에서 이들 함수에 호출을 추가하세요.Alternatively, try moving the constructor and destructor code into new functions, and add calls to these functions from the constructor and destructor for the union.

    #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;  
    }  
    
  • 템플릿 확인Template resolution

    템플릿의 이름 확인에 대한 변경 내용이 있습니다.Changes have been made to name resolution for templates. C++에서 이름을 확인할 후보를 고려할 때 잠재적인 일치 항목으로 고려 중인 하나 이상의 이름에서 잘못된 템플릿 인스턴스화가 생성될 수 있습니다.In C++, when considering candidates for the resolution of a name, it can be the case that one or more names under consideration as potential matches produces an invalid template instantiation. 보통 이들 잘못된 인스턴스화 때문에 컴파일러 오류가 발생하지는 않습니다. 이 원칙을 SFINAE(Substitution Failure Is Not An Error)라고 합니다.These invalid instantiations do not normally cause compiler errors, a principle which is known as SFINAE (Substitution Failure Is Not An Error).

    현재 SFINAE에 따라 컴파일러가 클래스 템플릿의 특수화를 인스턴스화해야 하면 이 프로세스 중에 발생하는 오류는 컴파일러 오류입니다.Now, if SFINAE requires the compiler to instantiate the specialization of a class template, then any errors that occur during this process are compiler errors. 이전 버전에서는 컴파일러가 해당 오류를 무시합니다.In previous versions, the compiler would ignore such errors. 예를 들어, 다음 코드를 고려하세요.For example, consider the following code:

    #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);  
    }  
    

    현재 컴파일러로 컴파일할 경우 다음 오류가 발생합니다.If you compile with the current compiler, you get the following error:

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

    이는 is_base_of의 첫 번째 호출 지점에서 'D' 클래스가 아직 정의되지 않았기 때문입니다.This is because at the point of the first invocation of the is_base_of the class 'D' has not yet been defined.

    이 경우 문제를 해결하려면 클래스가 정의될 때까지 이러한 형식 특성을 사용하지 마세요.In this case, the fix is not to use such type traits until the class has been defined. B 및 D의 정의를 코드 파일의 시작 부분으로 이동하면 오류가 해결됩니다.If you move the definitions of B and D to the beginning of the code file, the error is resolved. 정의가 헤더 파일에 있으면 헤더 파일의 include 문 순서를 확인하여 문제가 있는 템플릿이 사용되기 전에 클래스 정의가 컴파일되는지 확인합니다.If the definitions are in header files, check the order of the include statements for the header files to make sure that any class definitions are compiled before the problematic templates are used.

  • 복사 생성자Copy constructors

    --- --- Visual Studio 2013Visual Studio 2013 및 Visual Studio 2015에서 컴파일러는 클래스에 사용자 정의 이동 생성자가 있지만 사용자 정의 복사 생성자가 없을 경우 해당 클래스에 대한 복사 생성자를 생성합니다.In both --- --- Visual Studio 2013Visual Studio 2013 and Visual Studio 2015, the compiler generates a copy constructor for a class if that class has a user-defined move constructor but no user-defined copy constructor. Dev14에서는 생성된 복사 생성자가 "= delete"로 표시됩니다.In Dev14, this implicitly generated copy constructor is also marked "= delete".

  • extern “C”로 선언된 main에는 이제 반환 형식이 필요합니다.main declared as extern "C" now requires a return type.

다음 코드는 C4430을 생성합니다.The following code now produces C4430.

extern "C" __cdecl main(){} // C4430

오류를 해결하려면 반환 형식을 추가합니다.To fix the error, add the return type:

extern "C" int __cdecl main(){} // OK
  • typename이 멤버 이니셜라이저에서 허용되지 않음typename is not allowed in a member initializer

다음 코드는 C2059를 생성합니다.The following code now produces C2059:

template<typename T>
struct S1 : public T::type
{
   S1() : typename T::type() // C2059
   {
   }
};

struct S2 {
   typedef S2 type;
};

S1<S2> s;

오류를 해결하려면 이니셜라이저에서 typename을 제거합니다.To fix the error, remove typename from the initializer:

S1() : T::type() // OK
...
  • 명시적 특수화의 저장소 클래스가 무시됩니다.The storage class on explicit specializations is ignored.

다음 코드에서 정적 저장소 클래스 지정자가 무시됩니다.In the following code, the static storage class specifier is ignored

template <typename T>
void myfunc(T h)
{
}

template<>
static void myfunc(double h) // static is ignored
{
}
  • 클래스 템플릿 내부 static_assert에서 사용되는 상수가 항상 실패합니다.A constant used in a static_assert inside a class template will always fail.

다음 코드를 사용하면 static_assert가 항상 실패합니다.The following code causes the static_assert to always fail:

template <size_t some_value>
struct S1
{
    static_assert(false, "default not valid"); // always invoked

};

//other partial specializations here

이 문제를 해결하려면 값을 구조체로 래핑합니다.To work around this, wrap the value in a struct:

template <size_t some_value>
struct constant_false {
    static const bool value = false;
};

template <size_t some_value>
struct S1
{
    static_assert(constant_false<some_value>::value, "default not valid");
};

//other partial specializations here
  • 정방향 선언에 적용된 규칙. (C에만 적용됨)Rules enforced for forward declarations. (Applies only to C.)

다음 코드는 C2065를 생성합니다.The following code now produces C2065:

struct token_s;
typedef int BOOL;
typedef int INT;



typedef int(*PFNTERM)(PTOKEN, BOOL, INT); // C2065: 'PTOKEN' : undeclared identifier

문제를 해결하려면 적절한 정방향 선언을 추가합니다.To fix the problem add the proper forward declarations:

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);
  • 함수 포인터 형식의 더 일관된 적용More consistent enforcement of function pointer types

다음 코드는 C2197을 생성합니다.The following code now produces C2197:

typedef int(*F1)(int);
typedef int(*F2)(int, int);

void func(F1 f, int v1, int v2)
{
    f(v1, v2); // C2197
}
  • 오버로드된 함수에 대한 모호한 호출Ambiguous calls to overloaded functions

다음 코드는 C266을 생성합니다. ‘N::bind’: 오버로드된 함수에 대한 모호한 호출The following code now produces C266: 'N::bind': ambiguous call to overloaded function

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
    }
};

오류를 해결하려면 bind: N::bind(...)에 대한 호출을 정규화합니다. 하지만 이 변경이 선언되지 않은 식별자를 통한 매니페스트인 경우에는(C2065) ‘using’ 선언을 사용하여 이 오류를 해결하는 것이 좋습니다.To fix the error, you can fully qualify the call to bind: N::bind(...). However, if this change is manifest through an undeclared identifier (C2065), then it may be appropriate to fix this with a 'using' declaration instead.

이 패턴은 ComPtr 및 Microsoft::WRL 네임스페이스의 기타 형식에서 자주 발생합니다.This pattern happens frequently with ComPtr and other types in the Microsoft::WRL namespace.

  • 잘못된 주소 수정Fix incorrect address of

다음 코드는 C2440을 생성합니다. ‘=’: ‘type *’에서 ‘type’으로 변환할 수 없습니다.The following code now produces C2440: '=': cannot convert from 'type *' to 'type'. 오류를 해결하려면 &(type)를 (type)로 변경하고 (&f())를 (f())로 변경합니다.To fix the error, change &(type) to (type) and (&f()) to (f()).

\\ C
typedef void (*type)(void);

void f(int i, type p);
void g(int);
void h(void)
{
    f(0, &(type)g);
}

\\ C++
typedef void(*type)(void);

type f();

void g(type);

void h()
{
    g(&f());
}
  • 문자열 리터럴이 상수 배열임String literal is a constant array

다음 코드는 C2664를 생성합니다. ‘void f(void )’: 인수 1을 ‘const char ()[2]’에서 ‘void ’로 변환할 수 없습니다.The following code now produces C2664: 'void f(void *)': cannot convert argument 1 from 'const char ()[2]' to 'void *'

void f(void *);

void h(void)
{
    f(&__FUNCTION__); 
    void *p = &"";
}

오류를 해결하려면 함수 매개 변수 형식을 ‘const void’로 변경하거나 h의 본문을 다음과 같이 변경합니다.To fix the error, change the function parameter type to 'const void', or else change the body of h to look like this:

void h(void)
{
    char name[] = __FUNCTION__;
    f( name); 
    void *p = &"";
}
  • C++11 UDL 문자열C++11 UDL strings

다음 코드는 오류 C3688을 생성합니다. 잘못된 리터럴 접미사 ‘L’; 리터럴 연산자 또는 리터럴 연산자 템플릿 ‘operator ""L’을 찾을 수 없습니다.The following code now produces error C3688: invalid literal suffix 'L'; literal operator or literal operator template 'operator ""L' not found

#define MACRO

#define STRCAT(x, y) x\#\#y

int main(){

    auto *val1 = L"string"MACRO;
    auto *val2 = L"hello "L"world";

    std::cout << STRCAT(L"hi ", L"there");
}

오류를 해결하려면 코드를 다음으로 변경합니다.To fix the error, change the code to this:

#define MACRO

// Remove ##. Strings are automatically
// concatenated so they are not 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");
}

위의 예제에서 MACRO는 더 이상 두 개의 토큰으로 구문 분석되지 않습니다(문자열 뒤에 매크로가 나옴).In the example above, MACRO is no longer parsed as two tokens (a string followed by a macro). 이제 단일 토큰 UDL로 구문 분석됩니다.Now it is parsed as a single token UDL. L""L""에도 동일하게 적용됩니다. 이전에는 L"" 및 L""로 구문 분석되었고 지금은 L""L 및 ""로 구문 분석됩니다.The same applies to L""L"", which was parsed previously as L"" and L"", and is now parsed as L""L and "".

문자열 연결 규칙도 L“a” “b”가 L“ab”와 같음을 의미하는 표준 준수에 추가되었습니다.String concatenation rules were also brought into compliance with the standard, which means L"a" "b" is equivalent to L"ab". 이전 버전의 Visual Studio에서는 문자 너비가 다른 문자열의 연결을 허용하지 않았습니다.Previous editions of Visual Studio did not accept concatenation of strings with different character width.

  • C++11 빈 문자가 제거됨C++11 empty character removed

다음 코드는 오류 C2137을 생성합니다. 빈 문자 상수The following code now produces error C2137: empty character constant

bool check(wchar_t c){
    return c == L''; //implicit null character
}

오류를 해결하려면 코드를 다음으로 변경합니다.To fix the error, change the code to this:

bool check(wchar_t c){
    return c == L'\0';
}
  • MFC 예외는 복사할 수 없으므로 값으로 catch할 수 없음MFC exceptions can't be caught by value because they are not copyable

이제 MFC 응용 프로그램의 다음 코드는 오류 C2316을 발생시킵니다. ‘D’: 소멸자 및(또는) 복사 생성자가 액세스할 수 없는 상태이거나 삭제되었으므로 catch될 수 없습니다.The following code in an MFC application now causes error C2316: 'D': cannot be caught as the destructor and/or copy constructor are inaccessible or deleted

struct B {
public:
    B();
private:
    B(const B &);
};

struct D : public B {
};

int main()
{
    try
    {
    }
    catch (D) // C2316
    {
    }
}

코드를 수정하려면 catch 블록을 ‘catch (const D &)’로 변경할 수 있지만 대개 MFC TRY/CATCH 매크로를 사용하는 것이 더 좋은 해결 방법입니다.To fix the code, you can change the catch block to `catch (const D &)' but the better solution is usually to use the MFC TRY/CATCH macros.

  • 이제 alignof가 키워드임alignof is now a keyword

다음 코드는 오류 C2332를 생성합니다. ‘class’: 태그 이름이 누락되었습니다.The following code now produces error C2332: 'class': missing tag name. 코드를 수정하려면 클래스 이름을 바꿔야 합니다. 그러지 않으면 클래스가 alignof와 같은 작업을 수행할 경우 클래스를 새 키워드로 바꾸면 됩니다.To fix the code you must rename the class or, if the class is performing the same work as alignof, just replace the class with the new keyword.

class alignof{}
  • 이제 constexpr이 키워드임constexpr is now a keyword

다음 코드는 이제 오류 C2059를 생성합니다. 구문 오류: ‘)’.The following code now produces error C2059: syntax error: ')'. 코드를 수정하려면 “constexpr”이라는 함수 또는 변수 이름을 바꿔야 합니다.To fix the code, you must rename any function or variable names that are called "constexpr".

int constexpr() {return 1;}
  • 이동 가능한 형식은 const일 수 없음Movable types cannot be const

함수가 이동하지 않으려는 형식을 반환하면 반환 형식은 const이면 안 됩니다.When a function returns a type that is intended to be moved, its return type should not be const.

  • 삭제된 복사 생성자Deleted copy constructors

다음 코드는 C2280을 반환합니다. ‘S::S(S &&)’: 삭제된 함수를 참조하려고 합니다.The following code now produces C2280 'S::S(S &&)': attempting to reference a deleted function:

struct S{
    S(int, int);
    S(const S&) = delete;
    S(S&&) = delete;
};

S s2 = S(2, 3); //C2280

오류를 해결하려면 S2에 대한 직접 초기화를 사용합니다.To fix the error, use direct initialization for S2:

struct S{
    S(int, int);
    S(const S&) = delete;
    S(S&&) = delete;
};

S s2 = {2,3}; //OK
  • 람다 캡처가 없을 경우에만 생성되는 함수 포인터로의 변환Conversion to function pointer only generated when no lambda capture

다음 코드는 Visual Studio 2015에서 C2664를 생성합니다.The following code produces C2664 in Visual Studio 2015.

void func(int(*)(int)) {}

int main() {

    func([=](int val) { return val; });
}

오류를 해결하려면 캡처 목록에서 =을 제거합니다.To fix the error, remove the = from the capture list.

  • 변환 연산자가 포함된 모호한 호출Ambiguous calls involving conversion operators

다음 코드는 오류 C2440을 생성합니다. ‘type cast’: ‘S2’에서 ‘S1’으로 변환할 수 없습니다.The following code now produces error C2440: 'type cast': cannot convert from 'S2' to 'S1':

struct S1 {
    S1(int);
};

struct S2 {
    operator S1();
    operator int();
};

void f(S2 s2)
{

    (S1)s2;

}

오류를 해결하려면 변환 연산자를 명시적으로 호출합니다.To fix the error, explicitly call the conversion operator:

void f(S2 s2)
{
    //Explicitly call the conversion operator
    s2.operator S1();
    // Or
    S1((int)s2);
}

다음 코드는 오류 C2593을 생성합니다. ‘operator =’이 모호합니다.The following code now produces error C2593: 'operator =' is ambiguous:

struct S1 {};

struct S2 {
    operator S1&();
    operator S1() const;
};

void f(S1 *p, S2 s)
{
    *p = s;
}

오류를 해결하려면 변환 연산자를 명시적으로 호출합니다.To fix the error, explicitly call the conversion operator:

void f(S1 *p, S2 s)
{
       *p = s.operator S1&();
}
  • NSDMI(비정적 데이터 멤버 초기화)에서 잘못된 복사 초기화 수정Fix invalid copy initialization in non-static data member initialization (NSDMI)

다음 코드는 오류 C2664를 생성합니다. ‘S1::S1(S1 &&)’: 인수 1을 ‘bool’에서 ‘const S1 &’로 변환할 수 없습니다.The following code now produces error C2664: 'S1::S1(S1 &&)': cannot convert argument 1 from 'bool' to 'const S1 &':

struct S1 {
    explicit S1(bool);
};

struct S2 {
    S1 s2 = true; // error
};

오류를 해결하려면 직접 초기화를 사용합니다.To fix the error, use direct initialization:

struct S2 {
S1 s1{true}; // OK
};
  • decltype 문의 내부에서 생성자 액세스Accessing constructors inside decltype statements

다음 코드는 C2248을 생성합니다. ‘S::S’: 클래스 ‘S’에서 선언된 전용 멤버에 액세스할 수 없습니다.The following code now produces C2248: 'S::S': cannot access private member declared in class 'S':

class S {
    S();
public:
    int i;
};

class S2 {
    auto f() -> decltype(S().i);
};

오류를 해결하려면 S2에 대한 friend 선언을 S에 추가합니다.To fix the error, add a friend declaration for S2 in S:

class S {
    S();
    friend class S2; // Make S2 a friend
public:
    int i;
};
  • 람다의 기본 ctor가 암시적으로 삭제됨Default ctor of lambda is implicitly deleted

다음 코드는 오류 C3497을 생성합니다. 람다의 인스턴스를 생성할 수 없습니다.The following code now produces error C3497: you cannot construct an instance of a lambda:

void func(){
    auto lambda = [](){};    

    decltype(lambda) other;
}

오류를 해결하려면 기본 생성자를 호출할 필요성을 제거합니다.To fix the error, remove the need for the default constructor to be called. 람다가 아무것도 캡처하지 않으면 함수 포인터로 캐스트될 수 있습니다.If the lambda does not capture anything then it can be cast to a function pointer.

  • 삭제된 대입 연산자가 있는 람다Lambdas with a deleted assignment operator

다음 코드는 오류 C2280을 생성합니다.The following code now produces error C2280:

#include <memory>
#include <type_traits>

template <typename T, typename D>
std::unique_ptr<T, typename std::remove_reference<D &&>::type> wrap_unique(T *p, D &&d);

void f(int i)
{
    auto encodedMsg = wrap_unique<unsigned char>(nullptr, [i](unsigned char *p) {
    });
    encodedMsg = std::move(encodedMsg);
}

오류를 해결하려면 람다를 functor 클래스로 바꾸거나 대입 연산자를 사용할 필요성을 제거합니다.To fix the error, replace the lambda with a functor class or remove the need to use the assignment operator.

  • 삭제된 복사 생성자가 포함된 개체를 이동하려고 함Attempting to move an object with deleted copy constructor

다음 코드는 오류 C2280을 생성합니다. ‘moveable::moveable(const moveable &)’: 삭제된 함수를 참조하려고 합니다.The following code now produces error C2280: 'moveable::moveable(const moveable &)': attempting to reference a deleted function

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;
};

오류를 해결하려면 std::move를 사용합니다.To fix the error, use std::move instead:

S(moveable && m) :
    m_m(std::move(m))
  • 로컬 클래스가 나중에 같은 함수에서 정의된 다른 로컬 클래스를 참조할 수 없음Local class can't reference other local class defined later in the same function

다음 코드는 오류 C2079를 생성합니다. ‘s’가 정의되지 않은 구조체 ‘main::S2’를 사용합니다.The following code now produces error C2079: 's' uses undefined struct 'main::S2'

int main()
{
    struct S2;
    struct S1 {
        void f() {
            S2 s;
        }
    };
    struct S2 {};
}

오류를 해결하려면 S2의 정의를 위로 이동합니다.To fix the error, move up the definition of S2:

int main()
{
    struct S2 { //moved up
    };

struct S1 {
    void f() {
        S2 s;
        }
    };
}
  • 파생된 ctor의 본문에서 보호된 기본 ctor를 호출할 수 없습니다.Cannot call a protected base ctor in the body of derived ctor.

다음 코드는 오류 C2248을 생성합니다. ‘S1::S1’: 클래스 ‘S1’에서 선언된 보호된 멤버에 액세스할 수 없습니다.The following code now produces error C2248: 'S1::S1': cannot access protected member declared in class 'S1'

struct S1 {
protected:
    S1();
};

struct S2 : public S1 {
    S2() {
        S1();
    }
};

오류를 해결하려면 S2에서 S1() 호출을 생성자에서 제거하고 필요한 경우 다른 함수에 삽입합니다.To fix the error, in S2 remove the call to S1() from the constructor and if necessary put it in another function.

  • {}는 포인터로의 변환을 방지함{} prevents conversion to pointer

다음 코드는 C2439를 생성합니다. ‘S::p’: 멤버를 초기화할 수 없습니다.The following code now produces C2439 'S::p': member could not be initialized

struct S {
    S() : p({ 0 }) {}
    void *p;
};

오류를 해결하려면 0을 둘러싼 중괄호를 제거하거나 이 예제에 표시된 대로 nullptr를 사용합니다.To fix the error, remove the braces from around the 0 or else use nullptr instead, as shown in this example:

struct S {
    S() : p(nullptr) {}
    void *p;
};
  • 괄호가 있는 잘못된 매크로 정의 및 사용Incorrect macro definition and usage with parentheses

다음 예제는 오류 C2008을 생성합니다. ‘;’: 매크로 정의에 사용할 수 없습니다.The following example now produces error C2008: ';': unexpected in macro definition

#define A; //cause of error

struct S {
    A(); // error
};

문제를 해결하려면 맨 위 줄을 #define A();로 변경합니다.To fix the problem change the top line to #define A();

다음 코드는 오류 C2059를 생성합니다. 구문 오류: ‘)’.The following code produces error C2059: syntax error: ')'


//notice the space after 'A'
#define A () ;

struct S {
    A();
};

코드를 수정하려면 A와 () 사이에서 공백을 제거합니다.To fix the code remove the space between A and ().

다음 코드는 오류 C2091을 생성합니다. 함수가 함수를 반환합니다.The following code produces error C2091: function returns function:


#define DECLARE void f()

struct S {
    DECLARE();
};

오류를 해결하려면 S에서 DECLARE 뒤의 괄호를 제거합니다. DECLARE;.To fix the error, remove the parentheses after DECLARE in S: DECLARE;.

다음 코드는 오류 C2062를 생성합니다. 형식 ‘int’를 사용할 수 없습니다.The following code produces error C2062: type 'int' unexpected

#define A (int)

struct S {
    A a;
};

문제를 해결하려면 다음과 같이 A를 정의합니다.To fix the problem, define A like this:

#define A int
  • 선언의 추가 괄호Extra parens in declarations

다음 코드는 오류 C2062를 생성합니다. 형식 ‘int’를 사용할 수 없습니다.The following code produces error C2062: type 'int' unexpected


struct S {
    int i;
    (int)j;
};

오류를 해결하려면 j에서 괄호를 제거합니다.To fix the error, remove the parens from j. 쉽게 구별할 수 있도록 괄호가 필요하면 typedef를 사용합니다.If the parens are needed for clarity, then use a typedef.

  • 컴파일러에서 생성되는 생성자 및 __declspec(novtable)Compiler-generated constructors and __declspec(novtable)

Visual Studio 2015에서는 가상 기본 클래스가 포함된 추상 클래스의 인라인 컴파일러에서 생성된 생성자가 __declspec(dllimport)과 함께 사용될 경우 부적절한 __declspec(novtable) 사용을 노출할 가능성이 큽니다.In Visual Studio 2015, there is an increased likelihood that inline compiler-generated constructors of abstract classes with virtual base classes may expose improper usage of __declspec(novtable) when used in combination with __declspec(dllimport).

  • auto에 direct-list-initialization의 단일 식이 필요함 다음 코드는 오류 C3518을 생성합니다. ‘testPositions’: direct-list-initialization 컨텍스트에서 ‘auto’에 대한 형식은 하나의 이니셜라이저 식에서만 추론할 수 있습니다.auto requires single expression in direct-list-initialization The following code now produces error C3518: 'testPositions': in a direct-list-initialization context the type for 'auto' can only be deduced from a single initializer expression
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}
};

오류를 해결하기 위해 testPositions를 다음과 같이 초기화할 수 있습니다.To fix the error, one possibility is to initialize testPositions as follows:

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에 대한 형식 및 형식 포인터 확인Checking types vs. pointers to types for is_convertible

다음 코드에서는 정적 어설션이 실패합니다.The following code now causes the static assertion to fail.

struct B1 {
private:
    B1(const B1 &);
};
struct B2 : public B1 {};
struct D : public B2 {};

static_assert(std::is_convertible<D, B2>::value, "fail");

오류를 해결하려면 D 및 B2에 대한 포인터를 비교하도록 static_assert를 변경합니다.To fix the error, change the static_assert so that it compares pointers to D and B2:

static_assert(std::is_convertible<D*, B2*>::value, "fail");
  • declspec(novtable) 선언이 일관성을 유지해야 함declspec(novtable) declarations must be consistent

declspec 선언은 모든 라이브러리에서 일관성을 유지해야 합니다.declspec declarations must be consistent across all libraries. 다음 코드는 ODR(단일 정의 규칙) 위반을 생성합니다.The following code will now produce a one-definition rule (ODR) violation:


//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;

업데이트 1의 규칙 향상Conformance Improvements in Update 1

  • 개인 가상 기본 클래스 및 간접 상속Private virtual base classes and indirect inheritance

    이전 버전의 컴파일러에서는 파생 클래스에서 간접적으로 파생된private virtual 기본 클래스의 멤버 함수를 호출할 수 있었습니다.Previous versions of the compiler allowed a derived class to call member functions of its indirectly-derivedprivate virtual base classes. 이 이전 동작은 올바르지 않으며 C++ 표준을 따르지 않습니다.This old behavior was incorrect and does not conform to the C++ standard. 컴파일러는 이러한 방식으로 작성된 코드를 더 이상 허용하지 않으며, 결과적으로 컴파일러 오류 C2280이 발생합니다.The compiler no longer accepts code written in this way and issues compiler error C2280 as a result.

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

    예제(이전)Example (before)

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

    예제(이후)Example (after)

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

    또는-or -

    class base;  // as above  
    
    class middle : private virtual base {};  
    class top : public virtual middle, private virtual bottom {};  
    
    void destroy(top *p)  
    {  
        delete p;  
    }  
    
  • 오버로드된 operator new 및 operator deleteOverloaded operator new and operator delete

    이전 버전의 컴파일러에서는 멤버가 아닌 operator new 및 멤버가 아닌 operator delete 를 정적으로 선언할 수 있었으며 전역 네임스페이스 이외의 네임스페이스에서 선언할 수 있었습니다.Previous versions of the compiler allowed non-member operator new and non-member operator delete to be declared static, and to be declared in namespaces other than the global namespace. 이 이전 동작은 프로그램에서 프로그래머가 의도한 new 또는 delete 연산자 구현을 호출하지 않아서 잘못된 자동 런타임 동작이 발생하는 위험을 초래했습니다.This old behavior created a risk that the program would not call the new or delete operator implementation that the programmer intended, resulting in silent bad runtime behavior. 컴파일러는 이러한 방식으로 작성된 코드를 더 이상 허용하지 않으며, 대신 컴파일러 오류 C2323이 발생합니다.The compiler no longer accepts code written in this way and issues compiler error C2323 instead.

    
    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.  
    

    예제(이전)Example (before)

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

    예제(이후)Example (after)

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

    또한 컴파일러가 특정 진단을 제공하지는 않지만, 인라인 operator new는 잘못된 형식으로 간주됩니다.Additionally, although the compiler doesn't give a specific diagnostic, inline operator new is considered ill-formed.

  • 비클래스 형식에서 'operator type()'(사용자 정의 변환) 호출Calling 'operator type()' (user-defined conversion) on non-class types

    이전 버전의 컴파일러에서는 'operator type()'을 자동으로 무시하면서 비클래스 형식에서 호출할 수 있었습니다.Previous versions of the compiler allowed 'operator type()' to be called on non-class types while silently ignoring it. 이 이전 동작으로 잘못된 코드가 자동으로 생성되어 예기치 않은 런타임 동작이 발생하는 위험이 초래되었습니다.This old behavior created a risk of silent bad code generation, resulting in unpredictable runtime behavior. 컴파일러는 이러한 방식으로 작성된 코드를 더 이상 허용하지 않으며, 대신 컴파일러 오류 C2228이 발생합니다.The compiler no longer accepts code written in this way and issues compiler error C2228 instead.

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

    예제(이전)Example (before)

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

    예제(이후)Example (after)

    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'  
    }  
    
  • 상세 형식 지정자의 중복 typenameRedundant typename in elaborated type specifiers

    이전 버전의 컴파일러에서는 상세 형식 지정자에 typename 이 허용되었습니다. 이러한 방식으로 작성된 코드는 의미 체계가 잘못되었습니다.Previous versions of the compiler allowed typename in an elaborated type specifiers; code written in this way is semantically incorrect. 컴파일러는 이러한 방식으로 작성된 코드를 더 이상 허용하지 않으며, 대신 컴파일러 오류 C3406이 발생합니다.The compiler no longer accepts code written in this way and issues compiler error C3406 instead.

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

    예제(이전)Example (before)

    template <typename class T>  
    class container;  
    

    예제(이후)Example (after)

    template <class T>  // alternatively, could be 'template <typename T>'; 'typename' is not elaborating a type specifier in this case  
    class container;  
    
  • 이니셜라이저 목록에서 배열의 형식 추론Type deduction of arrays from an initializer list

    이전 버전의 컴파일러는 이니셜라이저 목록에서 배열의 형식 추론을 지원하지 않았습니다.Previous versions of the compiler did not support type deduction of arrays from an initializer list. 이제 컴파일러가 이러한 형태의 형식 추론을 지원합니다. 결과적으로 이니셜라이저 목록을 사용한 함수 템플릿 호출은 이제 모호하거나 이전 버전의 컴파일러와 다른 오버로드가 선택될 수 있습니다.The compiler now supports this form of type deduction and, as a result, calls to function templates using initializer lists might now be ambiguous or a different overload might be chosen than in previous versions of the compiler. 이러한 문제를 해결하려면 이제 프로그램에서 프로그래머가 의도한 오버로드를 명시적으로 지정해야 합니다.To resolve these issues, the program must now explicitly specify the overload that the programmer intended.

    이 새로운 동작으로 오버로드 확인에서 기록 후보와 똑같이 우수한 추가 후보를 고려하게 되는 경우, 호출이 모호해지며 결과적으로 컴파일러에서 컴파일러 오류 C2668이 발생합니다.When this new behavior causes overload resolution to consider an additional candidate that is equally as good as the historic candidate, the call becomes ambiguous and the compiler issues compiler error C2668 as a result.

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

    예제 1: 오버로드된 함수에 대한 호출이 모호합니다(이전).Example 1: Ambiguous call to overloaded function (before)

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

    예제 1: 오버로드된 함수에 대한 호출이 모호합니다(이후).Example 1: ambiguous call to overloaded function (after)

    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);   
    }  
    

    이 새로운 동작으로 오버로드 확인에서 기록 후보보다 더 일치되는 추가 후보를 고려하게 되는 경우, 호출이 새 후보로 명확하게 확인되므로 프로그래머가 의도한 것과 다른 프로그램 동작 변경을 초래할 수 있습니다.When this new behavior causes overload resolution to consider an additional candidate that is a better match than the historic candidate, the call resolves unambiguously to the new candidate, causing a change in program behavior that is probably different than the programmer intended.

    예제 2: 오버로드 확인의 변경(이전)Example 2: change in overload resolution (before)

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

    예제 2: 오버로드 확인의 변경(이후)Example 2: change in overload resolution (after)

    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 문 경고의 복원Restoration of switch statement warnings

    이전 버전의 컴파일러에서는 switch 문과 관련된 기존 경고를 제거했습니다. 이제 이러한 경고가 복원되었습니다.A Previous version of the compiler removed previously-existing warnings related to switch statements; these warnings have now been restored. 이제 컴파일러에서 복원된 경고가 발생합니다. 이제 특정 사례(기본 사례 포함)와 관련된 경고가 switch 문의 마지막 줄 대신, 잘못된 사례가 포함된 줄에서 발생합니다.The compiler now issues the restored warnings, and warnings related to specific cases (including the default case) are now issued on the line containing the offending case, rather than on the last line of the switch statement. 이제 과거와는 다른 줄에서 해당 경고가 발생하므로 이전에 #pragma warning(disable:####) 을 사용하면 표시되지 않았던 경고가 더 이상 의도한 대로 숨겨지지 않을 수 있습니다.As a result of now issuing those warnings on different lines than in the past, warnings previously suppressed by using #pragma warning(disable:####) may no longer be suppressed as intended. 이러한 경고를 의도한 대로 표시하지 않으려면 #pragma warning(disable:####) 지시문을 잠재적으로 잘못된 첫 번째 사례 위의 줄로 이동해야 할 수 있습니다.To suppress these warnings as intended, it might be necessary to move the #pragma warning(disable:####) directive to a line above the first potentially-offending case. 다음은 복원된 경고입니다.The following are the restored warnings.

    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의 예제(이전)Example of C4063 (before)

    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의 예제(이후)Example of C4063 (after)

    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;  
        }  
    };  
    

    복원된 다른 경고의 예는 해당 설명서에 제공됩니다.Examples of the other restored warnings are provided in their documentation.

  • #include: 경로 이름에 부모 디렉터리 지정자 '..' 사용 (/Wall /WX에만 영향을 줌)#include: use of parent-directory specifier '..' in pathname (only affects /Wall /WX)

    이전 버전의 컴파일러에서는Previous versions of the compiler did not detect the use of the parent-directory specifier '..' #include 지시문의 경로 이름에서 부모 디렉터리 지정자('..')의 사용을 검색하지 못했습니다.in the pathname of #include directives. 이러한 방식으로 작성된 코드는 일반적으로 프로젝트 상대 경로를 부정확하게 사용하여 프로젝트의 외부에 존재하는 헤더를 포함합니다.Code written in this way is usually intended to include headers that exist outside of the project by incorrectly using project-relative paths. 이 이전 동작은 프로그램이 프로그래머가 의도한 것과 다른 소스 파일을 포함하여 컴파일되거나 이러한 상대 경로가 다른 빌드 환경으로 이식되지 않는 위험을 초래했습니다.This old behavior created a risk that the program could be compiled by including a different source file than the programmer intended, or that these relative paths would not be portable to other build environments. 이제 컴파일러는 이러한 방식으로 작성된 코드를 검색하여 프로그래머에게 알립니다. 그리고 사용하도록 설정된 경우 선택적으로 컴파일러 경고 C4464가 발생합니다.The compiler now detects and notifies the programmer of code written in this way and issues an optional compiler warning C4464, if enabled.

    warning C4464: relative include path contains '..'  
    

    예제(이전)Example (before)

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

    예제(이후)Example (after)

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

    또한 컴파일러가 특정 진단을 제공하지는 않지만, 프로젝트의 Include 디렉터리를 지정하는 데 부모 디렉터리 지정자("..")를 사용하지 않는 것이 좋습니다.Additionally, although the compiler does not give a specific diagnostic, we also recommend that the parent-directory specifier ".." should note be used to specify your project's include directories.

  • #pragma optimize()에서 헤더 파일의 끝을 넘어 확장 (/Wall /WX에만 영향을 줌)#pragma optimize() extends past end of header file (only affects /Wall /WX)

    이전 버전의 컴파일러에서는 변환 단위 내에 포함된 헤더 파일을 이스케이프하는 최적화 플래그 설정에 대한 변경 내용을 검색하지 못했습니다.Previous versions of the compiler did not detect changes to optimization flag settings that escape a header file included within a translation unit. 이제 컴파일러는 이러한 방식으로 작성된 코드를 검색하여 프로그래머에게 알립니다. 그리고 사용하도록 설정된 경우 잘못된 #include의 위치에서 선택적으로 컴파일러 경고 C4426이 발생합니다.The compiler now detects and notifies the programmer of code written in this way and issues an optional compiler warning C4426 at the location of the offending #include, if enabled. 이 경고는 변경 내용이 명령줄 인수에 의해 컴파일러에 설정된 최적화 플래그와 충돌하는 경우에만 발생합니다.This warning is only issued if the changes conflict with the optimization flags set by command-line arguments to the compiler.

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

    예제(이전)Example (before)

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

    예제(이후)Example (after)

    // C4426.h  
    #pragma optimize("g", off)  
                ...  
    #pragma optimize("", on)  // restores optimization flags set via command-line arguments  
    // C4426.h ends  
    
    // C4426.cpp  
    #include "C4426.h"  
    
  • #pragma warning(push)#pragma warning(pop) (/Wall /WX에만 영향을 줌)Mismatched #pragma warning(push) and #pragma warning(pop) (only affects /Wall /WX)

    이전 버전의 컴파일러는 다른 소스 파일에서 #pragma warning(push) 상태 변경이 #pragma warning(pop) 상태 변경과 쌍을 이루는 것(의도되는 경우가 드묾)을 검색하지 못했습니다.Previous versions of the compiler did not detect #pragma warning(push) state changes being paired with #pragma warning(pop) state changes in a different source file, which is rarely intended. 이 이전 동작으로 프로그램이 프로그래머가 의도한 것과 다르게 설정된 경고 집합으로 컴파일되어 잘못된 자동 런타임 동작이 발생하는 위험이 초래됩니다.This old behavior created a risk that the program would be compiled with a different set of warnings enabled than the programmer intended, possibly resulting in silent bad runtime behavior. 이제 컴파일러는 이러한 방식으로 작성된 코드를 검색하여 프로그래머에게 알립니다. 그리고 사용하도록 설정된 경우 일치하는 #pragma warning(pop)의 위치에서 선택적으로 컴파일러 경고 C5031이 발생합니다.The compiler now detects and notifies the programmer of code written in this way and issues an optional compiler warning C5031 at the location of the matching #pragma warning(pop), if enabled. 이 경고에는 해당 #pragma warning(push)의 위치를 참조하는 참고가 포함되어 있습니다.This warning includes a note referencing the location of the corresponding #pragma warning(push).

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

    예제(이전)Example (before)

    // 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  
    ...  
    

    예제(이후)Example (after)

    // 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"  
    ...  
    

    드물긴 하지만 의도적으로 이러한 코드를 작성하는 경우가 있습니다.Though uncommon, code written in this way is sometimes intentional. 이러한 방식으로 작성된 코드는 #include 순서의 변경에 민감합니다. 가능한 경우 소스 코드 파일에서 자동으로 포함된 방식으로 경고 상태를 관리하는 것이 좋습니다.Code written in this way is sensitive to changes in #include order; when possible, we recommend that source code files manage warning state in a self-contained way.

  • #pragma warning(push) 불일치 (/Wall /WX에만 영향을 줌)Unmatched #pragma warning(push) (only affects /Wall /WX)

    이전 버전의 컴파일러는 변환 단위의 끝에서 #pragma warning(push) 상태 변경 불일치를 검색하지 못했습니다.Previous versions of the compiler did not detect unmatched #pragma warning(push) state changes at the end of a translation unit. 이제 컴파일러는 이러한 방식으로 작성된 코드를 검색하여 프로그래머에게 알립니다. 그리고 사용하도록 설정된 경우 일치하지 않는 #pragma warning(push)의 위치에서 선택적으로 컴파일러 경고 C5032가 발생합니다.The compiler now detects and notifies the programmer of code written in this way and issues an optional compiler warning C5032 at the location of the unmatched #pragma warning(push), if enabled. 이 경고는 변환 단위에 컴파일 오류가 없는 경우에만 발생합니다.This warning is only issued if there are no compilation errors in the translation unit.

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

    예제(이전)Example (before)

    // 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  
    

    예제(이후)Example (after)

    // C5032.h  
    #pragma warning(push)  
    #pragma warning(disable:####)  
    ...  
    #pragma warning(pop) // matches #pragma warning (push) on line 1  
    // C5032.h ends  
    
    // C5032.cpp  
    #include "C5032.h"  
    ...  
    // C5032.cpp ends -- the translation unit is completed without unmatched #pragma warning(push)  
    
  • 개선된 #pragma warning 상태 추적의 결과로 추가 경고가 발생할 수 있습니다.Additional warnings might be issued as a result of improved #pragma warning state tracking

    이전 버전의 컴파일러는 의도된 모든 경고를 발생시키기에는 불충분한 수준으로 #pragma warning 상태 변경을 추적했습니다.Previous versions of the compiler tracked #pragma warning state changes insufficiently well to issue all intended warnings. 이 동작으로 프로그래머가 의도한 것과 다른 상황에서 특정 경고가 효과적으로 표시되지 않는 위험이 초래됩니다.This behavior created a risk that certain warnings would be effectively suppressed in circumstances different than the programmer intended. 이제 컴파일러는 #pragma warning 상태(특히 템플릿 내부의 #pragma warning 상태 변경과 관련된 내용)를 더욱 강력하게 추적하며, 선택적으로 새로운 경고 C5031 및 C5032가 발생합니다. 이러한 경고는 프로그래머가 #pragma warning(push)#pragma warning(pop)의 의도하지 않은 사용을 찾는 데 도움이 됩니다.The compiler now tracks #pragma warning state more robustly -- especially related to #pragma warning state changes inside of templates -- and optionally issues new warnings C5031 and C5032 which are intended to help the programmer locate unintended uses of #pragma warning(push) and #pragma warning(pop).

    개선된 #pragma warning 상태 변경 추적의 결과로, 이전에 제대로 표시되지 않은 경고 또는 이전에 잘못 진단된 문제와 관련된 경고가 이제 발생할 수 있습니다.As a result of improved #pragma warning state change tracking, warnings formerly incorrectly suppressed or warnings related to issues formerly misdiagnosed might now be issued.

  • 접근할 수 없는 코드의 개선된 IDImproved identification of unreachable code

    C++ 표준 라이브러리의 변경 및 이전 버전의 컴파일러에 비해 향상된 인라인 함수 호출 기능을 통해 컴파일러가 이제 특정 코드에 접근할 수 없음을 증명할 수 있습니다.C++ Standard Library changes and improved ability to inline function calls over previous versions of the compiler might allow the compiler to prove that certain code is now unreachable. 이 새로운 동작으로 경고 C4720의 인스턴스가 새로 그리고 더욱 자주 발생할 수 있습니다.This new behavior can result in new and more-frequently issued instances of warning C4720.

    warning C4720: unreachable code  
    

    최적화 프로세스에서 더 많은 함수 호출을 인라인하거나 중복 코드를 제거하거나 특정 코드에 접근할 수 없는지 확인할 수 있도록 하므로, 이 경고는 대개 최적화를 사용하면서 컴파일할 경우에만 발생할 수 있습니다.In many cases, this warning might only be issued when compiling with optimizations enabled, since optimizations may inline more function calls, eliminate redundant code, or otherwise make it possible to determine that certain code is unreachable. 경고 C4720의 새 인스턴스가 특히 std::find의 사용과 관련하여 try/catch 블록에서 자주 발생했음을 관찰했습니다.We have observed that new instances of warning C4720 have frequently occurred in try/catch blocks, especially in relation to use of std::find.

    예제(이전)Example (before)

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

    예제(이후)Example (after)

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

업데이트 2의 규칙 향상Conformance Improvements in Update 2

  • SFINAE 식에 대한 부분 지원으로 인해 추가 경고 및 오류가 발생할 수 있습니다.Additional warnings and errors might be issued as a result of partial support for expression SFINAE

    이전 버전의 컴파일러는 SFINAE 식에 대한 지원 부족으로 decltype 지정자 내의 특정 유형의 식을 구문 분석하지 않았습니다.Previous versions of the compiler did not parse certain kinds of expressions inside decltype specifiers due to lack of support for expression SFINAE. 이 이전 동작은 올바르지 않으며 C++ 표준을 따르지 않습니다.This old behavior was incorrect and does not conform to the C++ standard. 지속적인 규칙 향상으로 인해 이제 컴파일러는 이러한 식을 구문 분석하고 SFINAE 식에 대한 부분 지원을 합니다.The compiler now parses these expressions and has partial support for expression SFINAE due to ongoing conformance improvements. 결과적으로 이제 컴파일러는 이전 버전의 컴파일러가 구문 분석하지 않았던 식에서 경고 및 오류를 발생합니다.As a result, the compiler now issues warnings and errors found in expressions that previous versions of the compiler did not parse.

    이 새로운 동작이 아직 선언되지 않은 형식을 포함하는 decltype 식을 구문 분석할 때, 컴파일러는 결과적으로 오류 C2039를 발생합니다.When this new behavior parses a decltype expression that includes a type that has not yet been declared, the compiler issues compiler error C2039 as a result.

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

    예제 1: 선언되지 않은 형식 사용(이전)Example 1: use of an undeclared type (before)

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

    예제 1(이후)Example 1 (after)

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

    이 새로운 동작이 종속 이름이 형식임을 지정하기 위해 필요한 typename 키워드 사용이 누락된 decltype 식을 구문 분석할 때 컴파일러는 컴파일러 오류 C2923과 함께 컴파일러 경고 C4346을 발생합니다.When this new behavior parses a decltype expression that is missing a necessary use of the typename keyword to specify that a dependent name is a type, the compiler issues compiler warning C4346 together with compiler error C2923.

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

    예제 2: 종속 이름이 형식이 아님(이전)Example 2: dependent name is not a type (before)

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

    예제 2(이후)Example 2 (after)

    template < typename T> struct s1 { ... };  // as above  
    template < typename T> struct s2 { ... };  // as above  
    
    template < typename T>  
    T declval();  
    
    struct s  
    {  
        template < typename T>  
        auto f(T t) - > decltype(t(declval< S1< typename S2< T> ::type> ::type> ()));  
    };  
    
  • volatile 멤버 변수가 암시적으로 정의된 생성자와 대입 연산자를 막음volatile member variables prevent implicitly defined constructors and assignment operators

    이전 버전의 컴파일러는 volatile 멤버 변수가 있는 클래스가 기본 복사/이동 생성자 및 기본 복사 대입 연산자를 자동으로 생성하도록 허용했습니다.Previous versions of the compiler allowed a class that has volatile member variables to have default copy/move constructors and default copy/move assignment operators automatically generated. 이 이전 동작은 올바르지 않으며 C++ 표준을 따르지 않습니다.This old behavior was incorrect and does not conform to the C++ standard. 이제 컴파일러는 volatile 멤버 변수가 있는 클래스는 특수한 생성자 및 대입 연산자가 있는 것으로 간주하여 이러한 연산자의 기본 구현이 자동으로 생성되는 것을 막습니다.The compiler now considers a class that has volatile member variables to have non-trivial construction and assignment operators which prevents default implementations of these operators from being automatically generated. 이러한 클래스가 공용 구조체(또는 클래스 내의 익명 공용 구조체)의 멤버이면 공용 구조체(또는 익명 공용 구조체를 포함하는 클래스)의 복사/이동 생성자 및 복사/이동 대입 연산자는 삭제된 것으로 암시적으로 정의됩니다.When such a class is a member of a union (or an anonymous union inside of a class), the copy/move constructors and copy/move assignment operators of the union (or the class containing the unonymous union) will be implicitly defined as deleted. 명시적으로 정의하지 않고 공용 구조체(또는 익명 공용 구조체를 포함하는 클래스)를 만들거나 복사하려 하면 오류가 발생하며 컴파일러에서 결과적으로 컴파일러 오류 C2280을 발생합니다.Attempting to construct or copy the union (or class containing the anonymous union) without explicitly defining them is an error and the compiler issues compiler error C2280 as a result.

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

    예제(이전)Example (before)

    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  
    

    예제(이후)Example (after)

    struct A  
    {  
        int i; int j;   
    };  
    
    extern volatile A* pa;  
    
    A getA()  // returns an A instance copied from contents of pa  
    {  
        A a;  
        a.i = pa - > i;  
        a.j = pa - > j;  
        return a;  
    }  
    
    struct B;  // as above  
    
    B b1{ GetA() };  
    B b2(b1);  // error C2280  
    
  • 정적 멤버 함수는 cv 한정자를 지원하지 않습니다.Static member functions do not support cv-qualifiers.

    이전 버전의 Visual C++ 2015는 정적 멤버 함수에 cv 한정자가 포함되는 것을 허용했습니다.Previous versions of Visual C++ 2015 allowed static member functions to have cv-qualifiers. 이 동작은 Visual C++ 2015 및 Visual C++ 2015 업데이트 1에서의 문제 재발로 인한 것입니다. Visual C++ 2013 및 이전 버전의 Visual C++는 이런 식으로 작성된 코드를 거부합니다.This behavior is due to a regression in Visual C++ 2015 and Visual C++ 2015 Update 1; Visual C++ 2013 and previous versions of Visual C++ reject code written in this way. Visual C++ 2015 및 Visual C++ 2015 업데이트 1의 동작은 잘못되었으며 C++ 표준과 일치하지 않습니다.The behavior of Visual C++ 2015 and Visual C++ 2015 Update 1 is incorrect and does not conform to the C++ standard. Visual Studio 2015 업데이트 2는 이런 식으로 작성된 코드를 거부하며 대신 컴파일러 오류 C2511을 발생합니다.Visual Studio 2015 Update 2 rejects code written in this way and issues compiler error C2511 instead.

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

    예제(이전)Example (before)

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

    예제(이후)Example(after)

    struct A  
    {  
        static void func();  
    };  
    
    void A::func() {}  // removed const  
    
  • 열거형의 정방향 선언은 WinRT 코드에서 허용되지 않습니다(/ZW만 영향을 줌).Forward declaration of enum is not allowed in WinRT code (affects /ZW only)

    WinRT(Windows 런타임)에 대해 컴파일된 코드는 enum 형식이 정방향 선언되는 것을 허용하지 않습니다. /clr 컴파일러 스위치를 사용하여 관리되는 C++ 코드가 .Net Framework에 대해 컴파일되는 경우와 비슷합니다.Code compiled for the Windows Runtime (WinRT) doesn't allow enum types to be forward declared, similarly to when managed C++ code is compiled for the .Net Framework using the /clr compiler switch. 이 동작은 열거형의 크기를 항상 알 수 있으며 WinRT 형식 시스템에 올바르게 프로젝션될 수 있음을 확인합니다.This behavior is ensures that the size of an enumeration is always known and can be correctly projected to the WinRT type system. 컴파일러는 이러한 방식으로 작성된 코드를 거부하고 컴파일러 오류 C3197과 함께 컴파일러 오류 C2599를 발생합니다.The compiler rejects code written in this way and issues compiler error C2599 together with compiler error C3197.

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

    예제(이전)Example (before)

    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;  
        }  
    };  
    

    예제(이후)Example (after)

              // forward declaration of CustomEnum removed  
    
    namespace A {  
        public enum class CustomEnum : int32  
        {  
            Value1  
        };  
    }  
    
    public ref class Component sealed  
    {  
    public:  
        CustomEnum f()  
        {  
            return CustomEnum::Value1;  
        }  
    };  
    
  • 오버로드된 멤버가 아닌 연산자 new 및 연산자 delete는 인라인으로 선언할 수 없습니다(수준 1(/ W1)이 기본적으로 설정되어 있음).Overloaded non-member operator new and operator delete may not be declared inline (Level 1 (/W1) on-by-default)

    이전 버전의 컴파일러는 멤버가 아닌 연산자 new 및 연산자 delete 함수가 인라인으로 선언될 때 경고를 발생하지 않습니다.Previous versions of the compiler do not issue a warning when non-member operator new and operator delete functions are declared inline. 이 방식으로 작성된 코드는 형식이 잘못되었으며(진단이 필요하지 않음) 진단하기 힘들 수 있는 일치하지 않는 new 및 delete 연산자로 인해 특히 크기가 지정된 할당 해제와 함께 사용 시 메모리 문제를 일으킬 수 있습니다.Code written in this way is ill-formed (no diagnostic required) and can cause memory issues resulting from mismatched new and delete operators (especially when used together with sized deallocation) that can be difficult to diagnose. 이제 컴파일러는 이런 식으로 작성된 코드를 식별하기 위해 경고 C4595를 발생합니다.The compiler now issues compiler warning C4595 to help identify code written in this way.

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

    예제(이전)Example (before)

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

    예제(이후)Example (after)

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

    이러한 방식으로 작성된 코드를 수정하려면 연산자 정의를 헤더 파일에서 해당하는 소스 파일로 이동해야 합니다.Fixing code that's written in this way might require that the operator definitions be moved out of a header file and into a corresponding source file.

업데이트 3의 규칙 향상Conformance Improvements in Update 3

  • 이제 std::is_convertable이 자체 할당을 검색함(표준 라이브러리)std::is_convertable now detects self-assignment (standard library)

    이전 버전의 std::is_convertable 형식 특성은 복사 생성자가 삭제되거나 private인 경우 클래스 형식의 자체 할당을 제대로 검색하지 못했습니다.Previous versions of the std::is_convertable type-trait did not correctly detect self-assignment of a class type when its copy constructor is deleted or private. 이제 복사 생성자가 삭제되거나 private인 클래스 형식에 적용할 때 std::is_convertable<>::valuefalse로 올바르게 설정됩니다.Now, std::is_convertable<>::value is correctly set to false when applied to a class type with a deleted or private copy constructor.

    이 변경과 관련된 컴파일러 진단은 없습니다.There is no compiler diagnostic associated with this change.

    예제Example

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

    이전 버전의 Visual C++에서는 std::is_convertable<>::valuetrue로 잘못 설정되었기 때문에 이 예제의 맨 아래에 있는 정적 어설션이 성공합니다.In previous versions of Visual C++, the static assertions at the bottom of this example pass because std::is_convertable<>::value was incorrectly set to true. 이제 std::is_convertable<>::valuefalse로 올바르게 설정되므로 정적 어설션이 실패합니다.Now, std::is_convertable<>::value is correctly set to false, causing the static assertions to fail.

  • 기본값으로 설정되었거나 삭제된 trivial 복사 및 이동 생성자가 액세스 지정자를 따름Defaulted or deleted trivial copy and move constructors respect access specifiers

    이전 버전의 컴파일러에서는 호출을 허용하기 전에 기본값으로 설정되었거나 삭제된 trivial 복사 및 이동 생성자의 액세스 지정자를 확인하지 않았습니다.Previous versions of the compiler did not check the access specifier of defaulted or deleted trivial copy and move constructors before allowing them to be called. 이 이전 동작은 올바르지 않으며 C++ 표준을 따르지 않습니다.This old behavior was incorrect and does not conform to the C++ standard. 경우에 따라 이 이전 동작으로 잘못된 코드가 자동으로 생성되어 예기치 않은 런타임 동작이 발생하는 위험이 초래되었습니다.In some cases, this old behavior created a risk of silent bad code generation, resulting in unpredictable runtime behavior. 이제 컴파일러에서 기본값으로 설정되었거나 삭제된 trivial 복사 및 이동 생성자의 액세스 지정자를 검사하여 호출 가능 여부를 확인하고, 호출할 수 없는 경우 결과로 컴파일러 경고 C2248을 실행합니다.The compiler now checks the access specifier of defaulted or deleted trivial copy and move constructors to determine whether it can be called, and if not, issues compiler warning C2248 as a result.

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

    예제(이전)Example (before)

    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  
    }  
    

    예제(이후)Example (after)

    class S {  
    public:  
        S() = default;  
    private:  
        S(const S&) = default;  
    };  
    
    void f(const S&);  // pass S by reference  
    
    int main()  
    {  
        S s;  
        f(s);   
    }  
    
  • 특성 사용 ATL 코드 지원 중단(기본적으로 수준 1(/W1) 설정)Deprecation of attributed ATL code support (Level 1 (/W1) on-by-default)

    이전 버전의 컴파일러에서는 특성 사용 ATL 코드를 지원했습니다.Previous versions of the compiler supported attributed ATL code. Visual C++ 2008부터 시작된 특성 사용 ATL 코드 지원 제거의 다음 단계로 특성 사용 ATL 코드가 더 이상 사용되지 않습니다.As the next phase of removing support for attributed ATL code that began in Visual C++ 2008, attributed ATL code has been deprecated. 이제 컴파일러에서 사용되지 않는 이러한 종류의 코드를 식별하기 위해 컴파일러 경고 C4467을 실행합니다.The compiler now issues compiler warning C4467 to help identify this kind of deprecated code.

    warning C4467: Usage of ATL attributes is deprecated  
    

    컴파일러에서 지원이 제거될 때까지 특성 사용 ATL 코드를 계속 사용하려는 경우 /Wv:18 또는 /wd:4467 명령줄 인수를 컴파일러에 전달하거나 소스 코드에 #pragma warning(disable:4467)을 추가하여 이 경고를 해제할 수 있습니다.If you want to continue using attributed ATL code until support is removed from the compiler, you can disable this warning by passing the /Wv:18 or /wd:4467 command line arguments to the compiler, or by adding #pragma warning(disable:4467) in your source code.

    예제 1(이전)Example 1 (before)

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

    예제 1(이후)Example 1 (after)

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

    사용되지 않는 ATL 특성의 사용을 방지하기 위해 아래 예제 코드와 같이 IDL 파일을 만들 수 있습니다.Sometimes you might need or want to create an IDL file to avoid the use deprecated ATL attributes, as in the example code below

    예제 2(이전)Example 2 (before)

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

    먼저 *.idl 파일을 만듭니다. 생성된 vc140.idl 파일을 사용하여 인터페이스와 주석이 포함된 *.idl 파일을 가져올 수 있습니다.First, create the *.idl file; the vc140.idl generated file can be used to obtain an *.idl file containing the interfaces and annotations.

    그런 다음 빌드에 MIDL 단계를 추가하여 C++ 인터페이스 정의가 생성되었는지 확인합니다.Next, add a MIDL step to your build to make sure that the C++ interface definitions are generated.

    예제 2 IDL(이후)Example 2 IDL (after)

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

    아래 예제 코드와 같이 구현 파일에서 직접 ATL을 사용합니다.Then, use ATL directly in the implementation file, as in the example code below.

    예제 2 구현(이후)Example 2 Implementation (after)

    #include <idl.header.h>  
    #include <atlbase.h>  
    
    class ATL_NO_VTABLE CFooImpl :  
        public ICustom,  
        public ATL::CComObjectRootEx< CComMultiThreadModel>  
    {  
    public:  
        BEGIN_COM_MAP(CFooImpl)  
            COM_INTERFACE_ENTRY(ICustom)  
        END_COM_MAP()  
    };  
    
  • 미리 컴파일된 헤더(PCH) 파일 및 일치하지 않는 #include 지시문(/Wall /WX에만 적용)Precompiled header (PCH) files and mismatched #include directives (only affects /Wall /WX)

    이전 버전의 컴파일러에서는 미리 컴파일된 헤더(PCH) 파일을 사용할 때 -Yc-Yu 컴파일 간에 일치하지 않는 소스 파일의 #include 지시문을 허용했습니다.Previous versions of the compiler accepted mismatched #include directives in source files between -Yc and -Yu compilations when using precompiled header (PCH) files. 이런 방식으로 작성된 코드는 컴파일러에서 더 이상 허용되지 않습니다.Code written in this way is no longer accepted by the compiler. PCH 파일 사용 시 일치하지 않는 #include 지시문을 식별하기 위해 이제 컴파일러에서 컴파일러 경고 CC4598을 실행합니다.The compiler now issues compiler warning CC4598 to help identify mismatched #include directives when using PCH files.

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

    예제(이전):Example (before):

    X.cpp(-Ycc.h)X.cpp (-Ycc.h)

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

    Z.cpp(-Yuc.h)Z.cpp (-Yuc.h)

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

    예제(이후)Example (after)

    X.cpp(-Ycc.h)X.cpp (-Ycc.h)

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

    Z.cpp(-Yuc.h)Z.cpp (-Yuc.h)

    #include "a.h"  
    #include "b.h" // matched order relative to X.cpp  
    #include "c.h"  
    
  • 미리 컴파일된 헤더(PCH) 파일 및 일치하지 않는 include 지시문(/Wall /WX에만 적용)Precompiled header (PCH) files and mismatched include directories (only affects /Wall /WX)

    이전 버전의 컴파일러에서는 미리 컴파일된 헤더(PCH) 파일을 사용할 때 -Yc-Yu 컴파일 간에 일치하지 않는 컴파일러의 include 디렉터리(-I) 명령줄 인수를 허용했습니다.Previous versions of the compiler accepted mismatched include directory (-I) command line arguments to the compiler between -Yc and -Yu compilations when using precompiled header (PCH) files. 이런 방식으로 작성된 코드는 컴파일러에서 더 이상 허용되지 않습니다.Code written in this way is no longer accepted by the compiler. PCH 파일 사용 시 일치하지 않는 include 디렉터리(-I) 명령줄 인수를 식별하기 위해 이제 컴파일러에서 컴파일러 경고 CC4599를 실행합니다.The compiler now issues compiler warning CC4599 to help identify mismatched include directory (-I) command line arguments when using PCH files.

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

    예제(이전)Example (before)

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

    예제(이후)Example (after)

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

Visual C++ 2013 규칙 변경 내용Visual C++ 2013 Conformance Changes

컴파일러Compiler

  • final 키워드는 이제 이전에 컴파일되었을 수 있는 경우 확인되지 않은 기호 오류를 생성합니다.The final keyword now generates an unresolved symbol error where it would have compiled previously:

    struct S1 {  
        virtual void f() = 0;  
    };  
    
    struct S2 final : public S1 {  
        virtual void f();  
    };  
    
    int main(S2 *p)  
    {  
        p->f();  
    }  
    

    이전 버전에서는 호출이 가상 호출이기 때문에 오류가 발생하지 않았지만 런타임에 프로그램의 작동이 중단될 수 있었습니다.In earlier versions, an error wasn't issued because the call was a virtual call; nevertheless, the program would crash at runtime. 이제는 클래스가 final인 것으로 알려지기 때문에 링커 오류가 발생합니다.Now, a linker error is issued because the class is known to be final. 이 예제에서 오류를 해결하려면 S2::f의 정의가 포함된 obj에 대해 링크합니다.In this example, to fix the error, you would link against the obj that contains the definition of S2::f.

  • 네임스페이스의 friend 함수를 사용하는 경우 friend 함수를 참조하기 전에 다시 선언해야 합니다. 이렇게 하지 않으면 이제 컴파일러가 ISO C++ 표준을 준수하므로 오류가 발생합니다.When you use friend functions in namespaces, you must re-declare the friend function before you refer to it or you will get an error because the compiler now conforms to the ISO C++ Standard. 예를 들어 이것은 더 이상 컴파일되지 않습니다.For example, this no longer compiles:

    namespace NS {  
        class C {  
            void func(int);  
            friend void func(C* const) {}  
        };  
    
        void C::func(int) {  
            NS::func(this);  // error  
        }  
    }  
    

    이 코드를 수정하려면 friend 함수를 선언합니다.To correct this code, declare the friend function:

    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++ 표준은 클래스에서 명시적 특수화를 허용하지 않습니다.The C++ Standard does not allow explicit specialization in a class. Visual C++는 어떤 경우에는 명시적 특수화를 허용하지만, 다음 예제와 같은 경우에는 컴파일러가 두 번째 함수를 첫 번째 함수의 특수화로 간주하지 않기 때문에 이제 오류가 생성됩니다.Although Visual C++ allows it in some cases, in cases such as the following example, an error is now generated because the compiler doesn't consider the second function to be a specialization of the first one.

    template < int N>  
    class S {  
    public:  
        template  void f(T& val);  
        template < > void f(char val);  
    };  
    
    template class S< 1>;  
    

    이 코드를 수정하려면 두 번째 함수를 수정합니다.To correct this code, modify the second function:

    template <> void f(char& val);  
    
  • 다음 예제에서 Visual C++는 더 이상 두 함수를 구분하려고 시도하지 않으며 이제 오류를 생성합니다.Visual C++ no longer tries to disambiguate the two functions in the following example, and now emits an error:

    template< typename T> void Func(T* t = nullptr);  
    template< typename T> void Func(...);  
    
    int main() {  
        Func< int>(); // error  
    }  
    

    이 코드를 수정하려면 호출을 명확히 지정합니다.To correct this code, clarify the call:

    template< typename T> void Func(T* t = nullptr);  
    template< typename T> void Func(...);  
    
    int main() {  
        Func< int>(nullptr); // ok  
    }  
    
  • 컴파일러가 ISO C++11을 준수하도록 변경되기 전에는 다음 코드가 컴파일되고 x가 int 형식으로 확인되었을 것입니다.Before the compiler was made compliant with ISO C++11, the following code would have compiled and caused x to resolve to type int:

    auto x = {0};  
    int y = x;  
    

    이 코드는 이제 x를 std::initializer_list<int>의 형식으로 확인하고 x를 int 형식에 할당하려는 다음 줄에서 오류를 발생시킵니다. 기본적으로 변환은 없습니다. 이 코드를 수정하려면 int를 사용하여 auto를 바꿉니다.This code now resolves x to a type of std::initializer_list<int> and causes an error on the next line that tries to assign x to type int. (There is no conversion by default.) To correct this code, use int to replace auto:

    int x = {0};  
    int y = x;  
    
  • 오른쪽 값의 형식이 초기화되고 있는 왼쪽 값의 형식과 일치하지 않는 경우 집합체 초기화는 더 이상 허용되지 않고 ISO C++11 표준에서는 축소 변환 없이 작업하려면 균일 초기화가 필요하기 때문에 오류가 발생합니다.Aggregate initialization is no longer allowed when the type of the right-hand value does not match the type of the left-hand value that's being initialized, and an error is issued because the ISO C++11 Standard requires uniform initialization to work without narrowing conversions. 이전에는 축소 변환을 사용할 수 있는 경우 컴파일러 경고(수준 4) C4242 경고가 오류 대신 발생했을 것입니다.Previously, if a narrowing conversion was available, a Compiler Warning (level 4) C4242 warning would have been issued instead of an error.

    int i = 0;  
    char c = {i}; // error  
    

    이 코드를 수정하려면 명시적 축소 변환을 추가합니다.To correct this code, add an explicit narrowing conversion:

    int i = 0;  
    char c = {static_cast<char>(i)};  
    
  • 다음과 같은 초기화는 더 이상 허용되지 않습니다.The following initialization is no longer allowed:

    void *p = {{0}};  
    

    이 코드를 수정하려면 다음 형태 중 하나를 사용합니다.To correct this code, use either of these forms:

    void *p = 0;  
    // or  
    void *p = {0};  
    
  • 이름 조회가 변경되었습니다.Name lookup has changed. 다음 코드는 Visual Studio 2012의 Visual C++와 Visual Studio 2013의 Visual C++에서 다르게 확인됩니다.The following code is resolved differently in Visual C++ in Visual Studio 2012 and Visual C++ in Visual Studio 2013:

    enum class E1 { a };  
    enum class E2 { b };  
    
    int main()  
    {  
        typedef E2 E1;  
        E1::b;  
    }  
    

    Visual Studio 2012의 Visual C++에서는 E1::b 식의 E1이 전역 범위의 ::E1로 확인됩니다.In Visual C++ in Visual Studio 2012, the E1 in expression E1::b resolved to ::E1 in the global scope. Visual Studio 2013의 Visual C++에서는 E1::b 식의 E1이 main()의 typedef E2로 확인되고 ::E2 형식을 사용합니다.In Visual C++ in Visual Studio 2013, E1 in expression E1::b resolves to the typedef E2 definition in main() and has type ::E2.

  • 개체 레이아웃이 변경되었습니다.Object layout has changed. x64에서 클래스의 개체 레이아웃은 이전 릴리스에서 변경될 수 있습니다.On x64, the object layout of a class may change from previous releases. 가상 함수가 있지만 가상 함수가 포함된 기본 클래스가 없는 경우 컴파일러의 개체 모델은 데이터 멤버 레이아웃 뒤의 가상 함수 테이블에 포인터를 삽입합니다.If it has a virtual function but it doesn’t have a base class that has a virtual function, the object model of the compiler inserts a pointer to a virtual function table after the data member layout. 즉, 레이아웃이 최적의 상태가 아닌 경우도 있습니다.This means the layout may not be optimal in all cases. 이전 릴리스에서 x64 최적화를 하면 레이아웃 향상을 시도하지만 복잡한 코드 상황에서는 올바르게 작동하지 않기 때문에 Visual Studio 2013의 Visual C++에서 제거했습니다.In previous releases, an optimization for x64 would try to improve the layout for you, but because it failed to work correctly in complex code situations, it was removed in Visual C++ in Visual Studio 2013. 예를 들어 다음 코드를 고려합니다.For example, consider this code:

    __declspec(align(16)) struct S1 {  
    };  
    
    struct S2 {  
        virtual ~S2();  
        void *p;  
        S1 s;  
    };  
    
  • Visual Studio 2013의 Visual C++에서 x64의 sizeof(S2) 결과는 48이지만 이전 릴리스에서는 32로 계산됩니다.In Visual C++ in Visual Studio 2013, the result of sizeof(S2) on x64 is 48, but in previous releases, it evaluates to 32. Visual Studio 2013의 Visual C++에서 x64의 결과가 32로 계산되게 하려면 가상 함수가 포함된 더미 기본 클래스를 추가합니다.To make this evaluate to 32 in Visual C++ in Visual Studio 2013 for x64, add a dummy base class that has a virtual function:

    __declspec(align(16)) struct S1 {  
    };  
    
    struct dummy {  
        virtual ~dummy() {}  
    };  
    struct S2 : public dummy {  
        virtual ~S2();  
        void *p;  
        S1 s;  
    };  
    

    코드에서 이전 릴리스가 최적화 시도를 했을 수 있는 위치를 찾으려면 해당 릴리스의 컴파일러를 /W3 컴파일러 옵션과 함께 사용하고 경고 4370을 켭니다.To find places in your code that an earlier release would have tried to optimize, use a compiler from that release together with the /W3 compiler option and turn on Warning 4370. 예:For example:

    #pragma warning(default:4370)  
    
    __declspec(align(16)) struct S1 {  
    };  
    
    struct S2 {  
        virtual ~S2();  
        void *p;  
        S1 s;  
    };  
    

    Visual Studio 2013의 Visual C++ 이전 Visual C++ 컴파일러에서 이 코드는 다음 메시지를 출력합니다. 경고 C4370: 'S2': 압축 기능이 향상되어 이전 버전의 컴파일러에서 클래스 레이아웃이 변경되었습니다.On Visual C++ compilers before Visual C++ in Visual Studio 2013, this code outputs this message: warning C4370: 'S2' : layout of class has changed from a previous version of the compiler due to better packing

    x86 컴파일러는 모든 버전의 Visual C++에서 같은 차선의 레이아웃 문제가 있습니다.The x86 compiler has the same sub-optimal layout issue in all versions of Visual C++. 예를 들어 이 코드가 x86에 대해 컴파일되면For example, if this code is compiled for x86:

    struct S {  
        virtual ~S();  
        int i;  
        double d;  
    };  
    

    sizeof(S)의 결과는 24입니다.The result of sizeof(S) is 24. 그러나 x64에 대해 언급된 해결 방법을 사용하는 경우 16으로 줄어들 수 있습니다.However, this can be reduced to 16 if you use the workaround just mentioned for x64:

    struct dummy {  
        virtual ~dummy() {}  
    };  
    
    struct S : public dummy {  
        virtual ~S();  
        int i;  
        double d;  
    };  
    

표준 라이브러리Standard Library

Visual Studio 2013의 Visual C++는 Visual C++ 2010에서 구현된 _ITERATOR_DEBUG_LEVEL의 불일치와 RuntimeLibrary 불일치를 감지합니다.Visual C++ in Visual Studio 2013 detects mismatches in _ITERATOR_DEBUG_LEVEL, which was implemented in Visual C++ 2010, and RuntimeLibrary mismatches. 컴파일러 옵션 /MT(정적 릴리스), /MTd(정적 디버그), /MD(동적 릴리스) 및 /MDd(동적 디버그)가 혼합되면 이러한 현상이 발생합니다.These occur when compiler options /MT (static release), /MTd (static debug), /MD (dynamic release), and /MDd (dynamic debug) are mixed.

  • 코드에서 이전 릴리스의 시뮬레이트된 별칭 템플릿을 승인하는 경우 이를 변경해야 합니다.If your code acknowledges the previous release's simulated alias templates, you have to change it. 예를 들어 allocator_traits<A>::rebind_alloc<U>::other 대신 이제 allocator_traits<A>::rebind_alloc<U>로 지정해야 합니다.For example, instead of allocator_traits<A>::rebind_alloc<U>::other, now you have to say allocator_traits<A>::rebind_alloc<U>. ratio_add<R1, R2>::type이 더 이상 필요하지 않고 ratio_add<R1, R2>로 지정하는 것이 좋지만 감소된 비율에 대한 "type" typedef가 있으려면(이미 감소된 경우 같은 형식) ratio<N, D>가 필요하기 때문에 전자가 계속 컴파일됩니다.Although ratio_add<R1, R2>::type is no longer necessary and we now recommend that you say ratio_add<R1, R2>, the former will still compile because ratio<N, D> is required to have a "type" typedef for a reduced ratio, which will be the same type if it's already reduced.

  • std::min() 또는 std::max() 호출 시 #include <알고리즘>을 사용해야 합니다.You must use #include <algorithm> when you call std::min() or std::max().

  • 기존 코드에서 이전 릴리스의 시뮬레이트된 범위가 지정된 열거형을 사용하는 경우(범위가 지정되지 않은 일반적인 열거형이 네임스페이스에 래핑됨) 이를 변경해야 합니다.If your existing code uses the previous release’s simulated scoped enums—traditional unscoped enums wrapped in namespaces—you have to change it. 예를 들어 std::future_status::future_status 형식을 참조한 경우 이제 std::future_status로 지정해야 합니다.For example, if you referred to the type std::future_status::future_status, now you have to say std::future_status. 그러나 대부분의 코드는 영향을 받지 않습니다. 예를 들어 std::future_status::ready는 계속 컴파일됩니다.However, most code is unaffected—for example, std::future_status::ready still compiles.

  • explicit operator bool()이 operator unspecified-bool-type()보다 더 엄격합니다.explicit operator bool() is stricter than operator unspecified-bool-type(). explicit operator bool()은 bool로의 명시적 변환(예: shared_ptr<X> sp가 제공된 경우 static_cast<bool>(sp)과 bool b(sp)가 둘 다 유효함) 및 bool로의 부울 테스트 가능한 "상황에 맞는 변환"(예: if (sp), !sp, sp && 등)을 허용합니다.explicit operator bool() permits explicit conversions to bool—for example, given shared_ptr<X> sp, both static_cast<bool>(sp) and bool b(sp) are valid—and Boolean-testable "contextual conversions" to bool—for example, if (sp), !sp, sp && whatever. 그러나 explicit operator bool()은 bool로의 암시적 변환을 금지하므로 bool b = sp로 지정할 수 없으며, bool 반환 형식이 제공된 경우 return sp로 지정할 수 없습니다.However, explicit operator bool() forbids implicit conversions to bool, so you can't say bool b = sp; and given a bool return type, you can't say return sp.

  • 실제 variadic 템플릿이 구현되었으므로 _VARIADIC_MAX 및 관련 매크로는 영향을 주지 않습니다.Now that real variadic templates are implemented, _VARIADIC_MAX and related macros have no effect. _VARIADIC_MAX를 계속 정의하더라도 무시됩니다.If you're still defining _VARIADIC_MAX, it is just ignored. 다른 방식으로 시뮬레이션된 variadic 템플릿을 지원하기 위한 매크로 체계를 승인한 경우 코드를 변경해야 합니다.If you acknowledged our macro machinery intended to support simulated variadic templates in any other way, you have to change your code.

  • 일반적인 키워드 외에도 C++ 표준 라이브러리 헤더에서는 이제 상황에 맞는 키워드 "override" 및 "final"에 대한 매크로화가 금지됩니다.In addition to ordinary keywords, C++ Standard Library headers now forbid the macro-izing of the context-sensitive keywords "override" and "final".

  • reference_wrapper/ref()/cref()는 이제 임시 개체에 대한 바인딩을 금지합니다.reference_wrapper/ref()/cref() now forbid binding to temporary objects.

  • <random>은 이제 컴파일 타임 사전 조건을 엄격하게 적용합니다.<random> now strictly enforces its compile-time preconditions.

  • 다양한 C++ 표준 라이브러리 형식 특성에는 "T가 완전한 형식이어야 함"이라는 사전 조건이 있습니다.Various C++ Standard Library type traits have the precondition "T shall be a complete type". 이제는 컴파일러에서 이 조건을 더욱 엄격하게 적용하지만 모든 상황에서 적용할 수 있는 것은 아닙니다.Although the compiler now enforces this more strictly, it may not enforce it in all situations. C++ 표준 라이브러리 사전 조건을 위반하면 정의되지 않은 동작이 발생하기 때문에 표준에서는 적용이 보장되지 않습니다.(Because C++ Standard Library precondition violations trigger undefined behavior, the Standard doesn't guarantee enforcement.)

  • C++ 표준 라이브러리는 /clr:oldSyntax를 지원하지 않습니다.The C++ Standard Library does not support /clr:oldSyntax.

  • common_type<>에 대한 C++11 사양으로 인해 바람직하지 않은 예기치 않은 결과가 발생했습니다. 특히 common_type<int, int>::type이 int&&를 반환하게 됩니다.The C++11 specification for common_type<> had unexpected and undesired consequences; in particular, it makes common_type<int, int>::type return int&&. 따라서 Visual C++는 라이브러리 작업 그룹 문제에 대한 제안된 해결 방법 2141을 구현하며, 이를 통해 common_type<int, int="">::type이 int를 반환하게 됩니다.Therefore, Visual C++ implements the Proposed Resolution for Library Working Group issue 2141, which makes common_type<int, int="">::type return int.

    이 변경의 부작용으로 ID의 경우가 더 이상 작동하지 않습니다(common_type<T>가 T 형식을 생성하지 않는 경우도 있음).As a side-effect of this change, the identity case no longer works (common_type<T> does not always result in type T). 이는 제안된 해결 방법을 사용하여 컴파일되지만 이전 동작에 의존하는 모든 코드가 중단됩니다.This complies with the Proposed Resolution, but it breaks any code that relied on the previous behavior.

    ID 형식 특성이 필요한 경우 <type_traits>에 정의된 비표준 std::identity는 <void>에 대해 작동하지 않으므로 사용하지 마세요.If you require an identity type trait, don't use the non-standard std::identity that's defined in <type_traits> because it won't work for <void> . 대신 필요에 따라 고유한 ID 형식 특성을 구현합니다.Instead, implement your own identity type trait to suit your needs. 예를 들면 다음과 같습니다.Here's an example:

    template < typename T> struct Identity {  
        typedef T type;  
    };  
    

MFC 및 ATLMFC and ATL

  • Visual Studio 2013만 해당: 유니코드가 일반화되고 MBCS의 사용이 크게 줄었기 때문에 MFC MBCS 라이브러리는 Visual Studio에 포함되지 않습니다.Visual Studio 2013 only: MFC MBCS Library is not included in Visual Studio because Unicode is so popular and use of MBCS is significantly reduced. 여러 새로운 컨트롤과 메시지가 유니코드 전용이기 때문에 이 변경으로 인해 MFC는 Windows SDK 자체와 보다 밀접한 관계로 유지됩니다.This change also keeps MFC more closely aligned with the Windows SDK itself, because many of the new controls and messages are Unicode-only. 그러나 MFC MBCS 라이브러리를 계속 사용해야 하는 경우 MSDN 다운로드 센터의 Visual Studio 2013용 멀티바이트 MFC 라이브러리에서 다운로드할 수 있습니다.However, if you must continue to use the MFC MBCS library, you can download it from the MSDN Download Center at Multibyte MFC Library for Visual Studio 2013. Visual C++ 재배포 가능 패키지에는 이 라이브러리가 계속 포함됩니다.The Visual C++ Redistributable Package still includes this library. (참고: MBCS DLL은 Visual Studio 2015 이상의 Visual C++ 설치 구성 요소에 포함됩니다).(Note: The MBCS DLL is included in Visual C++ setup components in Visual Studio 2015 and later).

  • MFC 리본에 대한 접근성이 변경되었습니다.Accessibility for the MFC ribbon is changed. 한 수준의 아키텍처 대신 이제 계층적 아키텍처가 있습니다.Instead of a one-level architecture, there is now a hierarchical architecture. CRibbonBar::EnableSingleLevelAccessibilityMode()을 호출하여 이전 동작을 계속 사용할 수 있습니다.You can still use the old behavior by calling CRibbonBar::EnableSingleLevelAccessibilityMode().

  • CDatabase::GetConnect 메서드가 제거되었습니다.CDatabase::GetConnect method is removed. 보안을 강화하기 위해 이제 연결 문자열이 암호화되어 저장되며 필요할 경우에만 해독됩니다. 연결 문자열은 일반 텍스트로 반환될 수 없습니다.To improve security, the connection string is now stored encrypted and is decrypted only as needed; it cannot be returned as plain text. CDatabase::Dump 메서드를 사용하여 문자열을 가져올 수 있습니다.The string can be obtained by using the CDatabase::Dump method.

  • CWnd::OnPowerBroadcast의 서명이 변경되었습니다.Signature of CWnd::OnPowerBroadcast is changed. 이 메시지 처리기의 서명은 LPARAM을 두 번째 매개 변수로 사용하도록 변경되었습니다.The signature of this message handler is changed to take an LPARAM as the second parameter.

  • 서명이 메시지 처리기를 수용하도록 변경되었습니다.Signatures are changed to accommodate message handlers. 새로 추가된 ON_WM_* 메시지 처리기를 사용하기 위해 다음과 같은 함수의 매개 변수 목록이 변경되었습니다.The parameter lists of the following functions have been changed to use newly added ON_WM_* message handlers:

    • 메시지 맵에서 새로운 ON_WM_DISPLAYCHANGE 매크로를 사용할 수 있도록 CWnd::OnDisplayChange가 (WPARAM, LPARAM) 대신 (UINT, int, int)로 변경되었습니다.CWnd::OnDisplayChange changed to (UINT, int, int) instead of (WPARAM, LPARAM) so that the new ON_WM_DISPLAYCHANGE macro can be used in the message map.

    • 메시지 맵에서 새로운 ON_WM_DDE_INITIATE 매크로를 사용할 수 있도록 CFrameWnd::OnDDEInitiate가 (WPARAM, LPARAM) 대신 (CWnd, UINT, UNIT)로 변경되었습니다.CFrameWnd::OnDDEInitiate changed to (CWnd, UINT, UNIT) instead of (WPARAM, LPARAM) so that the new ON_WM_DDE_INITIATE macro can be used in the message map.

    • 메시지 맵에서 새로운 ON_WM_DDE_EXECUTE 매크로를 사용할 수 있도록 CFrameWnd::OnDDEExecute가 (WPARAM, LPARAM) 대신 (CWnd, HANDLE)로 변경되었습니다.CFrameWnd::OnDDEExecute changed to (CWnd, HANDLE) instead of (WPARAM, LPARAM) so that the new ON_WM_DDE_EXECUTE macro can be used in the message map.

    • 메시지 맵에서 새로운 ON_WM_DDE_TERMINATE 매크로를 사용할 수 있도록 CFrameWnd::OnDDETerminate가 매개 변수로 (WPARAM, LPARAM) 대신 (CWnd)로 변경되었습니다.CFrameWnd::OnDDETerminate changed to (CWnd) as the parameter instead of (WPARAM, LPARAM) so that the new ON_WM_DDE_TERMINATE macro can be used in the message map.

    • 메시지 맵에서 새로운 ON_WM_CUT 매크로를 사용할 수 있도록 CMFCMaskedEdit::OnCut이 (WPARAM, LPARAM) 대신 매개 변수를 사용하지 않는 함수로 변경되었습니다.CMFCMaskedEdit::OnCut changed to no parameters instead of (WPARAM, LPARAM) so that the new ON_WM_CUT macro can be used in the message map.

    • 메시지 맵에서 새로운 ON_WM_CLEAR 매크로를 사용할 수 있도록 CMFCMaskedEdit::OnClear가 (WPARAM, LPARAM) 대신 매개 변수를 사용하지 않는 함수로 변경되었습니다.CMFCMaskedEdit::OnClear changed to no parameters instead of (WPARAM, LPARAM) so that the new ON_WM_CLEAR macro can be used in the message map.

    • 메시지 맵에서 새로운 ON_WM_PASTE 매크로를 사용할 수 있도록 CMFCMaskedEdit::OnPaste가 (WPARAM, LPARAM) 대신 매개 변수를 사용하지 않는 함수로 변경되었습니다.CMFCMaskedEdit::OnPaste changed to no parameters instead of (WPARAM, LPARAM) so that the new ON_WM_PASTE macro can be used in the message map.

  • #ifdefs가 MFC 헤더 파일에서 제거되었습니다.#ifdefs in the MFC header files are removed. 지원되지 않는 Windows 버전(WINVER < 0x0501)과 관련된 MFC 헤더 파일의 여러 #ifdefs가 제거되었습니다.Numerous #ifdefs in the MFC header files related to unsupported versions of Windows (WINVER < 0x0501) are removed.

  • ATL DLL(atl120.dll)이 제거되었습니다.ATL DLL (atl120.dll) is removed. 이제 ATL은 헤더와 정적 라이브러리(atls.lib)로 제공됩니다.ATL is now provided as headers and a static library (atls.lib).

  • atlsd.lib, atlsn.lib 및 atlsnd.lib가 제거되었습니다.Atlsd.lib, atlsn.lib, and atlsnd.lib are removed. atls.lib에 debug/release와 관련된 문자 집합 종속성이 더 이상 없습니다.Atls.lib no longer has character-set dependencies or code that's specific for debug/release. atls.lib는 유니코드/ANSI 및 debug/release에 대해 동일하게 작동하기 때문에 한 버전의 라이브러리만 필요합니다.Because it works the same for Unicode/ANSI and debug/release, only one version of the library is required.

  • ATL DLL과 함께 ATL/MFC 추적 도구가 제거되고 추적 메커니즘이 간소화되었습니다.ATL/MFC Trace tool is removed together with the ATL DLL, and the tracing mechanism is simplified. CTraceCategory 생성자는 이제 하나의 매개 변수(범주 이름)를 사용하며, TRACE 매크로는 CRT 디버그 보고 함수를 호출합니다.The CTraceCategory constructor now takes one parameter (the category name), and the TRACE macros call the CRT debug reporting functions.

Visual C++ 2012의 주요 변경 내용Visual C++ 2012 Breaking Changes

컴파일러Compiler

  • /Yl 컴파일러 옵션이 변경되었습니다.The /Yl compiler option has changed. 기본적으로 컴파일러는 이 옵션을 사용하며, 특정 조건에서 LNK2011 오류가 발생할 수 있습니다.By default, the compiler uses this option, which can lead to LNK2011 errors under certain conditions. 자세한 내용은 /Yl(디버그 라이브러리에 대한 PCH 참조 삽입)를 참조하세요.For more information, see /Yl (Inject PCH Reference for Debug Library).

  • /clr을 사용하여 컴파일된 코드에서 enum class 키워드는 CLR(공용 언어 런타임) 열거형이 아니라 C++11 열거형을 정의합니다.In code that's compiled by using /clr, the enum class keyword defines a C++11 enum, not a common language runtime (CLR) enum. CLR 열거형을 정의하려면 해당 접근성에 대해 명시적이어야 합니다.To define a CLR enum, you must be explicit about its accessibility.

  • 템플릿 키워드를 사용하여 종속 이름(c + + 언어 표준 준수)을 명시적으로 구분할 수 있습니다.Use the template keyword to explicitly disambiguate a dependent name (C++ Language Standard compliance). 다음 예제에서 강조 표시된 템플릿 키워드는 모호성을 해결하는 데 필요합니다.In the following example, the highlighted template keyword is mandatory to resolve the ambiguity. 자세한 내용은 종속 형식의 이름 확인을 참조하세요.For more information, see Name Resolution for Dependent Types.

    template < typename X = "", typename = "" AY = "">  
    struct Container { typedef typename AY::template Rebind< X> ::Other AX; };  
    
  • 다음 예제와 같이 부동 소수점 형식의 상수 식은 더 이상 템플릿 인수로 허용되지 않습니다.Constant expression of type float is no longer allowed as a template argument, as shown in the following example.

    template<float n=3.14>  
    struct B {};  // error C2993: 'float': illegal type for non-type template parameter 'n'  
    
  • 다음 의사 코드 예제와 같이 /GS 명령줄 옵션을 사용하여 컴파일되고 off-by-one 취약성이 있는 코드로 인해 런타임 시 프로세스가 종료될 수 있습니다.Code that's compiled by using the /GS command-line option and that has an off-by-one vulnerability may lead to process termination at runtime, as shown in the following pseudocode example.

    char buf[MAX]; int cch; ManipulateString(buf, &cch); // ... buf[cch] = '\0'; // if cch >= MAX, process will terminate  
    
  • x86 빌드의 기본 아키텍처가 SSE2로 변경되었으므로 컴파일러에서 SSE 명령을 내보낼 수 있으며, XMM 레지스터를 사용하여 부동 소수점 계산을 수행합니다.The default architecture for x86 builds is changed to SSE2; therefore, the compiler may emit SSE instructions, and will use the XMM registers to perform floating-point calculations. 이전 동작으로 되돌리려면 /arch:IA32 컴파일러 플래그를 사용하여 아키텍처를 IA32로 지정합니다.If you want to revert to previous behavior, then use the /arch:IA32 compiler flag to specify the architecture as IA32.

  • 컴파일러에서 컴파일러 경고(수준 4) C4703 및 C4701 경고를 실행할 수도 있습니다(이전에 실행하지 않은 경우).The compiler may issue warnings Compiler Warning (level 4) C4703 and C4701 where previously it did not. 컴파일러는 포인터 형식의 초기화되지 않은 지역 변수 사용에 대해 보다 강력한 검사를 적용합니다.The compiler applies stronger checks for use of uninitialized local variables of pointer type.

  • 새 링커 플래그 /HIGHENTROPYVA가 지정된 경우 Windows 8에서는 일반적으로 메모리 할당 시 64비트 주소가 반환됩니다.When the new linker flag /HIGHENTROPYVA is specified, Windows 8 typically causes memory allocations to return a 64-bit address. Windows 8 이전에는 이러한 할당 시 2GB 미만의 주소가 반환된 경우가 더 많았습니다. 이로 인해 기존 코드에서 포인터 잘림 버그가 노출될 수 있습니다.(Prior to Windows 8, such allocations more often returned addresses that were less than 2 GB.) This may expose pointer truncation bugs in existing code. 이 스위치는 기본적으로 켜져 있습니다.By default, this switch is on. 이 동작을 사용하지 않으려면 /HIGHENTROPYVA:NO를 지정합니다.To disable this behavior, specify /HIGHENTROPYVA:NO.

  • 관리되는 컴파일러(Visual Basic/C#)는 관리 빌드에 대해서도 /HIGHENTROPYVA를 지원합니다.The managed compiler (Visual Basic/C#) also supports /HIGHENTROPYVA for managed builds. 그러나 이 경우에는 /HIGHENTROPYVAswitch가 기본적으로 꺼져 있습니다.However, in this case, the /HIGHENTROPYVAswitch is off by default.

IDEIDE

  • C++/CLI에서 Windows Forms 응용 프로그램을 만들지 않는 것이 좋지만 기존 C++/CLI UI 응용 프로그램의 유지 관리는 지원됩니다.Although we recommend that you do not create Windows Forms applications in C++/CLI, maintenance of existing C++/CLI UI applications is supported. Windows Forms 응용 프로그램이나 다른 .NET UI 응용 프로그램을 만들어야 하는 경우 C# 또는 Visual Basic을 사용합니다.If you have to create a Windows Forms application, or any other .NET UI application, use C# or Visual Basic. 상호 운용성 목적으로만 C++/CLI를 사용합니다.Use C++/CLI for interoperability purposes only.

병렬 패턴 라이브러리 및 동시성 런타임 라이브러리Parallel Patterns Library and Concurrency Runtime Library

UmsThreadDefault의 SchedulerType 열거형은 사용되지 않습니다.The SchedulerType enumeration of UmsThreadDefault is deprecated. UmsThreadDefault 사양은 사용되지 않음 경고를 생성하며, 내부적으로 ThreadScheduler에 다시 매핑됩니다.Specification of UmsThreadDefault produces a deprecated warning, and internally maps back to the ThreadScheduler.

표준 라이브러리Standard Library

  • C++98/03 및 C++11 표준 간의 주요 변경 내용에 따라 명시적 템플릿 인수를 사용하여 make_pair()를 호출하는 경우(예: make_pair<int, int>(x, y)) 일반적으로 Visual Studio 2012의 Visual C++에서 컴파일되지 않습니다.Following a breaking change between the C++98/03 and C++11 standards, using explicit template arguments to call make_pair()—as inmake_pair<int, int>(x, y)—typically does not compile in Visual C++ in Visual Studio 2012. 해결 방법은 make_pair(x, y)와 같이 항상 명시적 템플릿 인수 없이 make_pair()를 호출하는 것입니다.The solution is to always call make_pair()without explicit template arguments—as in make_pair(x, y). 명시적 템플릿 인수를 제공하면 이 함수의 목적에서 벗어납니다.Providing explicit template arguments defeats the purpose of the function. 결과 형식을 정밀하게 제어해야 하는 경우 pair<short, short>(int1, int2)와 같이 make_pair 대신 pair를 사용합니다.If you require precise control over the resulting type, use pair instead of make_pair—as in pair<short, short>(int1, int2).

  • C++98/03 및 C++11 표준 간의 또 다른 주요 변경 내용: A를 B로 암시적으로 변환할 수 있고, B를 C로 암시적으로 변환할 수 있지만 A를 C로 암시적으로 변환할 수 없는 경우 C++98/03 및 Visual C++ 2010에서는 pair<A, X>를 pair<C, X>로 변환할 수 있었습니다(암시적 또는 명시적).Another breaking change between the C++98/03 and C++11 standards: When A is implicitly convertible to B and B is implicitly convertible to C, but A is not implicitly convertible to C, C++98/03 and Visual C++ 2010 permitted pair<A, X> to be converted (implicitly or explicitly) to pair<C, X>. 다른 형식 X는 여기서 중요하지 않으며, 쌍의 첫 번째 형식과 관련이 없습니다. C++11 및 Visual Studio 2012의 Visual C++는 A를 C로 암시적으로 변환할 수 없음을 감지하기 때문에 오버로드 확인에서 쌍 변환을 제거합니다.(The other type, X, is not of interest here, and this is not specific to the first type in the pair.) Because C++11 and Visual C++ in Visual Studio 2012 detect that A is not implicitly convertible to C, they remove the pair conversion from overload resolution. 이는 다양한 시나리오에서 긍정적인 변경입니다.This is a positive change for many scenarios. 예를 들어 func(const pair<int, int>&) 및 func(const pair<string, string>&)를 오버로드하고 pair<const char *, const char *>를 사용하여 func()를 호출하면 이 변경과 함께 컴파일됩니다.For example, overloading func(const pair<int, int>&) and func(const pair<string, string>&), and calling func() with pair<const char *, const char *> will compile with this change. 그러나 이 변경으로 인해 적극적인 쌍 변환을 사용한 코드가 손상됩니다.However, this change breaks code that relied on aggressive pair conversions. 일반적으로 이러한 코드는 pair<C, X>가 필요한 함수에 make_pair(static_cast<B>(a), x) 전달 등의 방법으로 변환의 일부를 명시적으로 수행하여 수정할 수 있습니다.Such code can typically be fixed by performing one part of the conversion explicitly—for example, by passing make_pair(static_cast<B>(a), x) to a function that expects pair<C, X>.

  • Visual C++ 2010에서는 전처리기 기계로 오버로드와 특수화를 제거하여 variadic 템플릿(예: make_shared<T>(arg1, arg2, argN))을 10개 인수 제한까지 시뮬레이트했습니다.Visual C++ 2010 simulated variadic templates—for example, make_shared<T>(arg1, arg2, argN)—up to a limit of 10 arguments, by stamping out overloads and specializations with preprocessor machinery. Visual Studio 2012의 Visual C++에서는 대부분의 사용자에 대해 컴파일 시간과 컴파일러 메모리 소비를 개선하기 위해 이 제한이 5개 인수로 축소되었습니다.In Visual C++ in Visual Studio 2012, this limit is reduced to 5 arguments to improve compile times and compiler memory consumption for the majority of users. 그러나 프로젝트 수준에서 _VARIADIC_MAX를 10으로 명시적으로 정의하여 이전 제한을 설정할 수 있습니다.However, you can set the previous limit by explicitly defining _VARIADIC_MAX as 10, project-wide.

  • C++11 17.6.4.3.1 [macro.names]/2에서는 C++ 표준 라이브러리 헤더가 포함된 경우 macro-izing 키워드를 금지합니다.C++11 17.6.4.3.1 [macro.names]/2 forbids macro-izing keywords when C++ Standard Library headers are included. 이제 헤더가 macro-ized 키워드를 검색하면 컴파일러 오류를 내보냅니다.The headers now emit compiler errors if they detect macro-ized keywords. _ALLOW_KEYWORD_MACROS를 정의하면 이러한 코드를 컴파일할 수 있지만 사용하지 않는 것이 좋습니다. 예외로, macro-ized new는 헤더가 #pragma push_macro("new")/#undef new/#pragma pop_macro("new")를 사용하여 포괄적으로 자체 보호되므로 기본적으로 허용됩니다.(Defining _ALLOW_KEYWORD_MACROS allows such code to compile, but we strongly discourage that usage.) As an exception, macro-ized new is permitted by default, because the headers comprehensively defend themselves by using #pragma push_macro("new")/#undef new/#pragma pop_macro("new"). _ENFORCE_BAN_OF_MACRO_NEW 정의는 이름이 암시하는 작업을 정확히 수행합니다.Defining _ENFORCE_BAN_OF_MACRO_NEW does exactly what its name implies.

  • 다양한 최적화 및 디버깅 검사를 구현하기 위해 C++ 표준 라이브러리는 Visual Studio 버전(2005, 2008, 2010, 2012) 간에 이진 호환성을 의도적으로 중단합니다.To implement various optimizations and debugging checks, the C++ Standard Library implementation intentionally breaks binary compatibility among versions of Visual Studio (2005, 2008, 2010, 2012). C++ 표준 라이브러리가 사용되는 경우 서로 다른 버전을 사용하여 컴파일된 개체 파일 및 정적 라이브러리를 하나의 이진(EXE 또는 DLL)에 혼합할 수 없고, 서로 다른 버전을 사용하여 컴파일된 이진 간에 C++ 표준 라이브러리 개체를 전달할 수 없습니다.When the C++ Standard Library is used, this forbids the mixing of object files and static libraries that are compiled by using different versions into one binary (EXE or DLL), and forbids the passing of C++ Standard Library objects between binaries that are compiled by using different versions. 개체 파일과 정적 라이브러리를 혼합(Visual C++ 2010으로 컴파일된 C++ 표준 라이브러리와 Visual Studio 2012의 Visual C++로 컴파일된 C++ 표준 라이브러리를 함께 사용)하면 _MSC_VER 불일치에 대한 링커 오류가 내보내집니다. 여기서 _MSC_VER은 컴파일러의 주 버전(Visual Studio 2012의 Visual C++의 경우 1700)을 포함하는 매크로입니다.The mixing of object files and static libraries (using the C++ Standard Library that were compiled by using Visual C++ 2010 with those that were compiled by using Visual C++ in Visual Studio 2012 emits linker errors about _MSC_VER mismatch, where _MSC_VER is the macro that contains the compiler's major version (1700 for Visual C++ in Visual Studio 2012). 이 검사에서는 DLL 혼합을 비롯하여 Visual C++ 2008 또는 이전 버전과 관련된 혼합을 감지할 수 없습니다.This check cannot detect DLL mixing, and cannot detect mixing that involves Visual C++ 2008 or earlier.

  • Visual C++ 2010에서 구현된 _ITERATOR_DEBUG_LEVEL 검색 외에도 Visual Studio 2012의 Visual C++는 런타임 라이브러리 불일치를 검색합니다.In addition to detecting _ITERATOR_DEBUG_LEVEL mismatches, which was implemented in Visual C++ 2010, Visual C++ in Visual Studio 2012 detects Runtime Library mismatches. 컴파일러 옵션 /MT(정적 릴리스), /MTd(정적 디버그), /MD(동적 릴리스) 및 /MDd(동적 디버그)가 혼합되면 이러한 현상이 발생합니다.These occur when the compiler options /MT (static release), /MTd (static debug), /MD (dynamic release), and /MDd (dynamic debug) are mixed.

  • 구현이 실제로 유용하지는 않았지만 이전에는 operator<(), operator>(), operator<=() 및 operator>=()를 std::unordered_map andstdext::hash_map 컨테이너 패밀리에 사용할 수 있었습니다.operator<(), operator>(), operator<=(), and operator>=() were previously available for the std::unordered_map andstdext::hash_map families of containers, although their implementations were not actually useful. Visual Studio 2012의 Visual C++에서는 이러한 비표준 연산자가 제거되었습니다.These non-standard operators have been removed in Visual C++ in Visual Studio 2012. 또한 thestd::unordered_map 패밀리에 대한 operator==() 및 operator!=() 연산자의 구현이 stdext::hash_map 패밀리까지 확장되었습니다.Additionally, the implementation of operator==() and operator!=() for thestd::unordered_map family has been extended to cover the stdext::hash_map family. 새 코드에서는 thestdext::hash_map 패밀리 사용하지 않는 것이 좋습니다.(We recommend that you avoid the use of thestdext::hash_map family in new code.)

  • C++11 22.4.1.4 [locale.codecvt]에서는 codecvt::length() 및 codecvt::do_length()가 수정 가능한 stateT&parameters를 사용하도록 지정하지만 Visual C++ 2010에서는 const stateT&를 사용했습니다.C++11 22.4.1.4 [locale.codecvt] specifies that codecvt::length() and codecvt::do_length() should take modifiable stateT&parameters, but Visual C++ 2010 took const stateT&. Visual Studio 2012의 Visual C++에서는 표준에 따라 stateT&를 사용합니다.Visual C++ in Visual Studio 2012 takes stateT& as mandated by the standard. 이러한 차이는 가상 함수 do_length()를 재정의하려는 사용자에게 중요합니다.This difference is significant for anyone who is attempting to override the virtual function do_length().

CRTCRT

  • new 및 malloc()에 사용되는 C 런타임(CRT) 힙은 더 이상 private가 아닙니다.The C Runtime (CRT) heap, which is used for new and malloc(), is no longer private. 이제 CRT에서 프로세스 힙을 사용합니다.The CRT now uses the process heap. 즉, DLL을 언로드할 때 힙이 삭제되지 않으므로 CRT에 정적으로 연결하는 DLL은 DLL 코드에 의해 할당된 메모리가 언로드 전에 정리되도록 해야 합니다.This means that the heap is not destroyed when a DLL is unloaded, so DLLs that link statically to the CRT must ensure memory that's allocated by the DLL code is cleaned up before it’s unloaded.

  • Iscsymf() 함수는 음수 값으로 어설션됩니다.The iscsymf() function asserts with negative values.

  • threadlocaleinfostruct 구조체가 로캘 함수의 변경 내용에 맞게 변경되었습니다.The threadlocaleinfostruct struct has changed to accommodate the changes to locale functions.

  • 해당하는 내부 형식이 있는 memxxx(), strxxx() 등의 CRT 함수가 intrin.h에서 제거되었습니다.CRT functions that have corresponding intrinsics such as memxxx(), strxxx() are removed from intrin.h. 이러한 함수 전용으로 intrin.h를 포함한 경우 이제 해당 CRT 헤더를 포함해야 합니다.If you included intrin.h only for these functions, you must now include the corresponding CRT headers.

MFC 및 ATLMFC and ATL

  • Fusion 지원(afxcomctl32.h)이 제거되었으므로 afxcomctl32.h에 정의된 모든 메서드가 제거되었습니다.Removed Fusion support (afxcomctl32.h); therefore, all methods that are defined in afxcomctl32.h have been removed. 헤더 파일 afxcomctl32.h 및 afxcomctl32.inl이 삭제되었습니다.Header files afxcomctl32.h and afxcomctl32.inl have been deleted.

  • CDockablePane::RemoveFromDefaultPaneDividier의 이름이 CDockablePane::RemoveFromDefaultPaneDivider로 변경되었습니다.Changed the name of CDockablePane::RemoveFromDefaultPaneDividier to CDockablePane::RemoveFromDefaultPaneDivider.

  • CFileDialog::SetDefExt의 시그니처가 LPCTSTR을 사용하도록 변경되었으므로 유니코드 빌드가 영향을 받습니다.Changed the signature of CFileDialog::SetDefExt to use LPCTSTR; therefore, Unicode builds are affected.

  • 사용되지 않는 ATL 추적 범주가 제거되었습니다.Removed obsolete ATL tracing categories.

  • CBasePane::MoveWindow의 시그니처가 const CRect를 사용하도록 변경되었습니다.Changed the signature of CBasePane::MoveWindow to take a const CRect.

  • CMFCEditBrowseCtrl::EnableBrowseButton의 시그니처가 변경되었습니다.Changed the signature of CMFCEditBrowseCtrl::EnableBrowseButton.

  • m_fntTabs 및 m_fntTabsBold가 CMFCBaseTabCtrl에서 제거되었습니다.Removed m_fntTabs and m_fntTabsBold from CMFCBaseTabCtrl.

  • CMFCRibbonStatusBarPane 생성자에 매개 변수가 추가되었습니다.Added a parameter to the CMFCRibbonStatusBarPane constructors. 기본 매개 변수이므로 소스가 중단되지는 않습니다.(It is a default parameter, and so it is not source-breaking.)

  • CMFCRibbonCommandsListBox 생성자에 매개 변수가 추가되었습니다.Added a parameter to the CMFCRibbonCommandsListBox constructor. 기본 매개 변수이므로 소스가 중단되지는 않습니다.(It is a default parameter, and so it is not source-breaking.)

  • AFXTrackMouse API 및 관련 타이머 프로시저가 제거되었습니다.Removed the AFXTrackMouse API (and related timer proc). Win32 TrackMouseEvent API를 대신 사용합니다.Use the Win32 TrackMouseEvent API instead.

  • CFolderPickerDialog 생성자에 매개 변수가 추가되었습니다.Added a parameter to the CFolderPickerDialog constructor. 기본 매개 변수이므로 소스가 중단되지는 않습니다.(It is a default parameter, and so it is not source-breaking.)

  • CFileStatus 구조체 크기가 변경됨: m_attribute 멤버가 GetFileAttributes에서 반환된 값과 일치하도록 BYTE에서 DWORD로 변경되었습니다.CFileStatus structure size changed: The m_attribute member changed from BYTE to DWORD (to match the value that's returned fromGetFileAttributes).

  • CRichEditCtrl 및 CRichEditView가 유니코드 빌드에 RICHEDIT_CLASS(RichEdit 3.0 컨트롤) 대신 MSFTEDIT_CLASS(RichEdit 4.1 컨트롤)를 사용합니다.CRichEditCtrl and CRichEditView use MSFTEDIT_CLASS (RichEdit 4.1 control) instead of RICHEDIT_CLASS (RichEdit 3.0 control) in Unicode builds.

  • AFX_GLOBAL_DATA::IsWindowsThemingDrawParentBackground는 Windows Vista, Windows 7 및 Windows 8에서 항상 TRUE이므로 제거되었습니다.Removed AFX_GLOBAL_DATA::IsWindowsThemingDrawParentBackground because it is always TRUE on Windows Vista, Windows 7, and Windows 8.

  • AFX_GLOBAL_DATA::IsWindowsLayerSupportAvailable은 Windows Vista, Windows 7 및 Windows 8에서 항상 TRUE이므로 제거되었습니다.Removed AFX_GLOBAL_DATA::IsWindowsLayerSupportAvailable because it is always TRUE on Windows Vista, Windows 7, and Windows 8.

  • AFX_GLOBAL_DATA::DwmExtendFrameIntoClientArea가 제거되었습니다.Removed AFX_GLOBAL_DATA::DwmExtendFrameIntoClientArea. Windows Vista, Windows 7 및 Windows 8에서는 Windows API를 직접 호출합니다.Call Windows API directly on Windows Vista, Windows 7, and Windows 8.

  • AFX_GLOBAL_DATA::DwmDefWindowProc를 제거했습니다.Removed AFX_GLOBAL_DATA::DwmDefWindowProc. Windows Vista, Windows 7 및 Windows 8에서는 Windows API를 직접 호출합니다.Call Windows API directly on Windows Vista, Windows 7, and Windows 8.

  • 이름 충돌을 제거하기 위해 AFX_GLOBAL_DATA::DwmIsCompositionEnabled의 이름이 IsDwmCompositionEnabled로 바뀌었습니다.Renamed AFX_GLOBAL_DATA::DwmIsCompositionEnabled to IsDwmCompositionEnabled to eliminate name collision.

  • 많은 MFC 내부 타이머의 식별자가 변경되고 정의가 afxres.h(AFX_TIMER_ID_)로 이동되었습니다.Changed identifiers for a number of MFC internal timers and moved the definitions to afxres.h (AFX_TIMER_ID_).

  • OnExitSizeMove 메서드의 시그니처가 ON_WM_EXITSIZEMOVE 매크로와 일치하도록 변경되었습니다.Changed the signature of OnExitSizeMove method to agree with the ON_WM_EXITSIZEMOVE macro:

    • CFrameWndExCFrameWndEx

    • CMDIFrameWndExCMDIFrameWndEx

    • CPaneFrameWndCPaneFrameWnd

  • OnDWMCompositionChanged의 이름과 시그니처가 ON_WM_DWMCOMPOSITIONCHANGED 매크로와 일치하도록 변경되었습니다.Changed the name and signature of OnDWMCompositionChanged to agree with the ON_WM_DWMCOMPOSITIONCHANGED macro:

    • CFrameWndExCFrameWndEx

    • CMDIFrameWndExCMDIFrameWndEx

    • CPaneFrameWndCPaneFrameWnd

  • OnMouseLeave 메서드의 시그니처가 ON_WM_MOUSELEAVE 매크로와 일치하도록 변경되었습니다.Changed the signature of OnMouseLeave method to agree with the ON_WM_MOUSELEAVE macro:

    • CMFCCaptionBarCMFCCaptionBar

    • CMFCColorBarCMFCColorBar

    • CMFCHeaderCtrlCMFCHeaderCtrl

    • CMFCProperySheetListBoxCMFCProperySheetListBox

    • CMFCRibbonBarCMFCRibbonBar

    • CMFCRibbonPanelMenuBarCMFCRibbonPanelMenuBar

    • CMFCRibbonRichEditCtrlCMFCRibbonRichEditCtrl

    • CMFCSpinButtonCtrlCMFCSpinButtonCtrl

    • CMFCToolBar ReplaceThisTextCMFCToolBar ReplaceThisText

    • CMFCToolBarComboBoxEditCMFCToolBarComboBoxEdit

    • CMFCToolBarEditCtrlCMFCToolBarEditCtrl

    • CMFCAutoHideBarCMFCAutoHideBar

  • OnPowerBroadcast의 시그니처가 ON_WM_POWERBROADCAST 매크로와 일치하도록 변경되었습니다.Changed the signature of OnPowerBroadcast to agree with the ON_WM_POWERBROADCAST macro:

    • CFrameWndExCFrameWndEx

    • CMDIFrameWndExCMDIFrameWndEx

  • OnStyleChanged의 시그니처가 ON_WM_STYLECHANGED 매크로와 일치하도록 변경되었습니다.Changed the signature of OnStyleChanged to agree with the ON_WM_STYLECHANGED macro:

    • CMFCListCtrlCMFCListCtrl

    • CMFCStatusBarCMFCStatusBar

  • 내부 메서드 FontFamalyProcFonts의 이름이 FontFamilyProcFonts로 바뀌었습니다.Renamed the internal method FontFamalyProcFonts to FontFamilyProcFonts.

  • 일부 상황에서 메모리 누수를 방지하기 위해 수많은 전역 static CString 개체가 제거되었으며(#defines로 대체), 다음 클래스 멤버 변수가 제거되었습니다.Removed numerous global static CString objects to eliminate memory leaks in some situations (replaced with #defines), and the following class member variables:

    • CKeyBoardManager::m_strDelimiterCKeyBoardManager::m_strDelimiter

    • CMFCPropertyGridProperty::m_strFormatCharCMFCPropertyGridProperty::m_strFormatChar

    • CMFCPropertyGridProperty::m_strFormatShortCMFCPropertyGridProperty::m_strFormatShort

    • CMFCPropertyGridProperty::m_strFormatLongCMFCPropertyGridProperty::m_strFormatLong

    • CMFCPropertyGridProperty::m_strFormatUShortCMFCPropertyGridProperty::m_strFormatUShort

    • CMFCPropertyGridProperty::m_strFormatULongCMFCPropertyGridProperty::m_strFormatULong

    • CMFCPropertyGridProperty::m_strFormatFloatCMFCPropertyGridProperty::m_strFormatFloat

    • CMFCPropertyGridProperty::m_strFormatDoubleCMFCPropertyGridProperty::m_strFormatDouble

    • CMFCToolBarImages::m_strPngResTypeCMFCToolBarImages::m_strPngResType

    • CMFCPropertyGridProperty::m_strFormatCMFCPropertyGridProperty::m_strFormat

  • CKeyboardManager::ShowAllAccelerators의 시그니처가 변경되고 액셀러레이터 구분 기호 매개 변수가 제거되었습니다.Changed the signature of CKeyboardManager::ShowAllAccelerators and removed the accelerator delimiter parameter.

  • CPropertyPage::GetParentSheet가 추가되었으며, CPropertyPage 클래스에서 GetParent 대신 이 변수를 호출하여 올바른 부모 시트 창을 가져옵니다. 이 창은 CPropertyPage에 대한 부모 또는 최상위 항목일 수 있습니다.Added CPropertyPage::GetParentSheet, and in the CPropertyPage class, call it instead of GetParent to get the correct parent sheet window, which may be the parent or a grandparent window to CPropertyPage. ofGetParent 대신 GetParentSheet를 호출하도록 코드를 변경해야 할 수도 있습니다.You might have to change your code to call GetParentSheet instead ofGetParent.

  • ATLBASE.H에서 짝이 맞지 않는 #pragma warning(push)가 수정되었습니다. 이 코드 때문에 경고가 사용되지 않는 오류가 발생했었습니다.Fixed unbalanced #pragma warning(push) in ATLBASE.H, which caused warnings to be disabled incorrectly. 이제 ATLBASE.H가 구문 분석된 후 이러한 경고가 올바르게 사용됩니다.Those warnings are now enabled correctly after ATLBASE.H has been parsed.

  • D2D 관련 메서드가 AFX_GLOBAL_DATA에서 _AFX_D2D_STATE로 이동되었습니다.Moved D2D-related methods from AFX_GLOBAL_DATA to _AFX_D2D_STATE:

    • GetDirectD2dFactoryGetDirectD2dFactory

    • GetWriteFactoryGetWriteFactory

    • GetWICFactoryGetWICFactory

    • InitD2DInitD2D

    • ReleaseD2DRefsReleaseD2DRefs

    • IsD2DInitializedIsD2DInitialized

    • D2D1MakeRotateMatrixD2D1MakeRotateMatrix

    • 예를 들어 afxGlobalData.IsD2DInitialized를 호출하는 대신 AfxGetD2DState->IsD2DInitialized를 호출합니다.Instead of calling, for example, afxGlobalData.IsD2DInitialized, call AfxGetD2DState->IsD2DInitialized.

  • 사용되지 않는 ATL.CPP 파일이 \atlmfc\include\ 폴더에서 제거되었습니다.Removed obsolete ATL.CPP files from the \atlmfc\include\ folder.

  • DLLMain 요구 사항을 충족하기 위해 afxGlobalData 초기화가 CRT 초기화 시간 대신 요청 시로 이동되었습니다.Moved afxGlobalData initialization to on-demand instead of at CRT initialization time, to satisfy DLLMain requirements.

  • CMFCOutlookBarPane 클래스에 RemoveButtonByIndex 메서드가 추가되었습니다.Added the RemoveButtonByIndex method to the CMFCOutlookBarPane class.

  • CMFCCmdUsageCount::IsFreqeuntlyUsedCmd가 IsFrequentlyUsedCmd로 수정되었습니다.Corrected CMFCCmdUsageCount::IsFreqeuntlyUsedCmd to IsFrequentlyUsedCmd.

  • RestoreOriginalstate의 여러 인스턴스가 RestoreOriginalState (CMFCToolBar, CMFCMenuBar, CMFCOutlookBarPane)으로 수정되었습니다.Corrected several instances of RestoreOriginalstate to RestoreOriginalState (CMFCToolBar, CMFCMenuBar, CMFCOutlookBarPane).

  • CDockablePane: SetCaptionStyle, IsDrawCaption, IsHideDisabledButtons, GetRecentSiblingPaneInfo 및 CanAdjustLayout에서 사용되지 않는 메서드가 제거되었습니다.Removed unused methods from CDockablePane: SetCaptionStyle, IsDrawCaption, IsHideDisabledButtons, GetRecentSiblingPaneInfo, andCanAdjustLayout.

  • CDockablePane 정적 멤버 변수인 m_bCaptionText 및 m_bHideDisabledButtons가 제거되었습니다.Removed CDockablePane static member variables m_bCaptionText and m_bHideDisabledButtons.

  • CMFCFontComboBox에 재정의 DeleteString 메서드가 추가되었습니다.Added an override DeleteString method to CMFCFontComboBox.

  • CPane: GetMinLength 및 IsLastPaneOnLastRow에서 사용되지 않는 메서드가 제거되었습니다.Removed unused methods from CPane: GetMinLength and IsLastPaneOnLastRow.

  • CPane::GetDockSiteRow(CDockingPanesRow *)의 이름이 CPane::SetDockSiteRow로 바뀌었습니다.Renamed CPane::GetDockSiteRow(CDockingPanesRow *) to CPane::SetDockSiteRow.

Visual C++ 2010의 주요 변경 내용Visual C++ 2010 Breaking Changes

컴파일러Compiler

  • auto 키워드에 새로운 기본 의미가 있습니다.The auto keyword has a new default meaning. 이전 의미가 거의 사용되지 않았으므로 대부분의 응용 프로그램은 이 변경의 영향을 받지 않습니다.Because use of the old meaning is rare, most applications will not be affected by this change.

  • 새로운 static_assert 키워드가 도입되었으며, 코드에 해당 이름의 식별자가 이미 있는 경우 이름 충돌이 발생합니다.The new static_assert keyword is introduced, which will cause a name conflict if there is already an identifier by that name in your code.

  • 새 람다 표기법 지원에서 IDL uuid 특성에 따옴표가 없는 GUID를 코딩하기 위한 지원은 제외됩니다.Support for the new lambda notation excludes support for coding an unquoted GUID in an IDL uuid attribute.

  • .NET Framework 4에서는 프로세스를 복구할 수 없는 손상된 상태가 되게 하는 예외인 손상된 상태 예외 개념이 도입되었습니다.The .NET Framework 4 introduces the concept of corrupted state exceptions, which are exceptions that leave a process in an unrecoverable corrupted state. 기본적으로 다른 모든 예외를 catch하는 /EHa 컴파일러 옵션을 사용해도 손상된 상태 예외는 catch할 수 없습니다.By default, you cannot catch a corrupted state exception, even with the /EHa compiler option that catches all other exceptions. 손상된 상태 예외를 명시적으로 catch하려면 __try-__except 문을 사용합니다.To explicitly catch a corrupted state exception, use __try-__except statements. 또는 [HandledProcessCorruptedStateExceptions] 특성을 적용하여 함수가 손상된 상태 예외를 catch할 수 있게 합니다.Or, apply the [HandledProcessCorruptedStateExceptions]attribute to enable a function to catch corrupted state exceptions. 이 변경 내용은 주로 손상된 상태 예외를 catch해야 할 수 있는 시스템 프로그래머에게 영향을 줍니다.This change affects primarily system programmers who might have to catch a corrupted state exception. 8가지 예외는 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입니다.The eight exceptions are 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. 이러한 예외에 대한 자세한 내용은 GetExceptionCode 매크로를 참조하세요.For more information about these exceptions, see the GetExceptionCode macro.

  • 수정된 /GS 컴파일러 옵션은 이전 버전에 비해 더 포괄적으로 버퍼 오버런으로부터 보호합니다.The revised /GS compiler option guards against buffer overruns more comprehensively than in earlier versions. 이 버전에서는 스택에 추가 보안 검사가 삽입되어 성능이 느려질 수도 있습니다.This version might insert additional security checks in the stack that might decrease performance. 새로운 __declspec(safebuffers) 키워드를 사용하여 특정 함수에 대한 보안 검사를 삽입하지 않도록 컴파일러에 지시합니다.Use the new __declspec(safebuffers) keyword to instruct the compiler to not insert security checks for a particular function.

  • /GL(전체 프로그램 최적화) 및 /clr(공용 언어 런타임 컴파일) 컴파일러 옵션을 둘 다 사용하여 컴파일하는 경우 /GLoption은 무시됩니다.If you compile with both the /GL (Whole Program Optimization) and /clr (Common Language Runtime Compilation) compiler options, the /GLoption is ignored. 이 변경은 컴파일러 옵션 조합 시 혜택이 거의 없기 때문입니다.This change was made because the combination of compiler options provided little benefit. 이 변경의 결과로 빌드 성능이 향상됩니다.As a result of this change, the performance of the build is improved.

  • Visual C++ 2010에서는 기본적으로 삼중자 지원이 사용되지 않습니다.By default, support for trigraphs is disabled in Visual C++ 2010 . 삼중자 지원을 사용하려면 /Zc: trigraphs 컴파일러 옵션을 사용합니다.Use the /Zc:trigraphs compiler option to enable trigraphs support. 삼중자는 두 개의 연속 물음표("??")와 고유한 세 번째 문자로 구성됩니다.A trigraph consists of two consecutive question marks ("??") followed by a unique third character. 컴파일러는 삼중자를 해당 문장 부호 문자로 바꿉니다.The compiler replaces a trigraph with a corresponding punctuation character. 예를 들어 컴파일러는 "??=" 삼중자를 '#' 문자로 바꿉니다.For example, the compiler replaces the "??=" trigraph with the '#' character. 삼중자는 특정 문장 부호 문자에 대한 편리한 그래픽 표현을 포함하지 않는 문자 집합이 사용되는 C 소스 파일에서 사용합니다.Use trigraphs in C source files that use a character set that does not contain convenient graphic representations for some punctuation characters.

  • 링커가 Windows 98용 최적화를 더 이상 지원하지 않습니다.The linker no longer supports optimizing for Windows 98. /OPT:WIN98 또는 /OPT:NOWIN98을 지정하는 경우 /OPT(최적화) 옵션에서 컴파일 시간 오류가 생성됩니다.The /OPT (Optimizations) option produces a compile time error if you specify/OPT:WIN98 or /OPT:NOWIN98.

  • RuntimeLibrary 및 DebugInformationFormat 빌드 시스템 속성으로 지정되는 기본 컴파일러 옵션이 변경되었습니다.The default compiler options that are specified by the RuntimeLibrary and DebugInformationFormat build system properties have been changed. 기본적으로 이러한 빌드 속성은 Visual C++ 릴리스 7.0 ~ 10.0에서 생성된 프로젝트에 지정됩니다.By default, these build properties are specified in projects that are created by Visual C++ releases 7.0 through 10.0. Visual C++ 6.0에서 생성된 프로젝트를 마이그레이션하는 경우 이러한 속성 값을 지정할지 여부를 고려합니다.If you migrate a project that was created by Visual C++ 6.0, consider whether to specify a value for these properties.

  • Visual C++ 2010에서는 RuntimeLibrary = MultiThreaded(/MD) 및 DebugInformationFormat = ProgramDatabase(/Zi)입니다.In Visual C++ 2010, RuntimeLibrary = MultiThreaded (/MD) and DebugInformationFormat = ProgramDatabase (/Zi). Visual C++ 9.0에서는 RuntimeLibrary = MultiThreaded(/MT) 및 DebugInformationFormat = Disabled입니다.In Visual C++ 9.0,RuntimeLibrary = MultiThreaded (/MT) and DebugInformationFormat = Disabled.

CLRCLR

  • Microsoft C# 및 Visual Basic 컴파일러에서 이제 no-PIA(no 주 interop 어셈블리)를 생성할 수 있습니다.The Microsoft C# and Visual Basic compilers can now produce a no primary interop assembly (no-PIA). no-PIA 어셈블리는 관련 PIA(주 interop 어셈블리)를 배포하지 않고 COM 형식을 사용할 수 있습니다.A no-PIA assembly can use COM types without the deployment of the relevant primary interop assembly (PIA). Visual C# 또는 Visual Basic에서 생성된 no-PIA 어셈블리를 사용하는 경우 라이브러리를 사용하는 no-PIA 어셈블리를 참조하기 전에 컴파일 명령에서 PIA 어셈블리를 참조해야 합니다.When consuming no-PIA assemblies produced by Visual C# or Visual Basic, you must reference the PIA assembly on the compile command before you reference any no-PIA assembly that uses the library.

Visual C++ 프로젝트 및 MSBuildVisual C++ Projects and MSBuild

  • 이제 Visual C++ 프로젝트가 MSBuild 도구를 기반으로 합니다.Visual C++ projects are now based on the MSBuild tool. 따라서 프로젝트 파일이 새로운 XML 파일 형식과 .vcxproj 파일 접미사를 사용합니다.Consequently, project files use a new XML file format and a .vcxproj file suffix. Visual C++ 2010에서는 이전 Visual Studio 버전의 프로젝트 파일을 새 파일 형식으로 자동 변환합니다.Visual C++ 2010 automatically converts project files from earlier versions of Visual Studio to the new file format. 이전 빌드 도구인 VCBUILD.exe 또는 프로젝트 파일 접미사 .vcproj를 사용하는 기존 프로젝트에 영향을 줍니다.An existing project is affected if it depends on the previous build tool, VCBUILD.exe, or project file suffix, .vcproj.

  • 이전 릴리스에서는 Visual C++가 속성 시트의 런타임 평가를 지원했습니다.In earlier releases, Visual C++ supported the late evaluation of property sheets. 예를 들어 부모 속성 시트가 자식 속성 시트를 가져올 수 있고, 부모가 자식에 정의된 변수를 사용하여 다른 변수를 정의할 수 있었습니다.For example, a parent property sheet could import a child property sheet, and the parent could use a variable defined in the child to define other variables. 런타임 평가를 통해 부모가 자식 속성 시트를 가져오기 전에도 자식 변수를 사용할 수 있었습니다.Late evaluation enabled the parent to use the child variable even before the child property sheet was imported. Visual C++ 2010에서는 MSBuild가 초기 평가만 지원하기 때문에 프로젝트 시트 변수가 정의되기 전에는 사용할 수 없습니다.In Visual C++ 2010, a project sheet variable cannot be used before it is defined because MSBuild supports only early evaluation.

IDEIDE

  • 응용 프로그램 종료 대화 상자에서 더 이상 응용 프로그램을 종료하지 않습니다.The application termination dialog box no longer ends an application. 이전 릴리스에서는 abort() 또는 terminate() 함수가 응용 프로그램의 일반 정품 빌드를 닫을 때 C 런타임 라이브러리가 콘솔 창이나 대화 상자에 응용 프로그램 종료 메시지를 표시했습니다.In previous releases, when the abort() or terminate() function closed the retail build of an application, the C Run-Time Library displayed an application termination message in a console window or dialog box. “이 응용 프로그램에서 비정상적인 종료를 런타임에 요청했습니다.The message said in part, "This application has requested the Runtime to terminate it in an unusual way. 자세한 내용은 해당 응용 프로그램의 지원 팀에 문의하세요.”라는 메시지가 표시되었습니다.Please contact the application's support team for more information." 이후에 Windows에서 대체로 Windows 오류 보고(Dr. Watson) 대화 상자 또는 Visual Studio 디버거인 현재 종료 처리기를 표시했기 때문에 응용 프로그램 종료 메시지가 중복되었습니다.The application termination message was redundant because Windows subsequently displayed the current termination handler, which was usually the Windows Error Reporting (Dr. Watson) dialog box or the Visual Studio debugger. Visual Studio 2010부터 C 런타임 라이브러리가 메시지를 표시하지 않습니다.Starting in Visual Studio 2010, the C Run-Time Library does not display the message. 또한 런타임에서 디버거가 시작되기 전에 응용 프로그램이 종료되지 않도록 방지합니다.Furthermore, the runtime prevents the application from ending before a debugger starts. 이는 응용 프로그램 종료 메시지의 이전 동작을 사용하는 경우에만 주요 변경 내용입니다.This is a breaking change only if you depend on the previous behavior of the application termination message.

  • 특히 Visual Studio 2010에서는 IntelliSense가 C++/CLI 코드 또는 특성에 대해 작동하지 않고, 모든 참조 찾기가 지역 변수에 대해 작동하지 않으며, 코드 모델이 가져온 어셈블리에서 형식 이름을 검색하거나 형식을 정규화된 이름으로 확인하지 않습니다.Specifically for Visual Studio 2010, IntelliSense does not work for C++/CLI code or attributes, Find All References does not work for local variables, and Code Model does not retrieve type names from imported assemblies or resolve types to their fully qualified names.

라이브러리Libraries

  • SafeInt 클래스가 Visual C++에 포함되었으며 더 이상 별도 다운로드로 제공되지 않습니다.The SafeInt class is included in Visual C++ and is no longer in a separate download. 이는 "SafeInt"라고도 하는 클래스를 개발한 경우에만 주요 변경 내용입니다.This is a breaking change only if you have developed a class that is also named "SafeInt".

  • 라이브러리 배포 모델은 더 이상 매니페스트를 사용하여 특정 버전의 동적 연결 라이브러리를 찾지 않습니다.The libraries deployment model no longer uses manifests to find a particular version of a dynamic link library. 대신, 각 동적 연결 라이브러리의 이름에 해당 버전 번호가 포함되므로 이름을 사용하여 라이브러리를 찾습니다.Instead, the name of each dynamic link library contains its version number, and you use that name to locate the library.

  • 이전 버전의 Visual Studio에서는 런타임 라이브러리를 다시 빌드할 수 있었습니다.In previous versions of Visual Studio, you could rebuild the run time libraries. Visual C++ 2010에서는 더 이상 C 런타임 라이브러리 파일의 고유 복사본을 작성할 수 없습니다.Visual C++ 2010 no longer supports building your own copies of the C run time library files.

표준 라이브러리Standard Library

  • <iterator> 헤더가 더 이상 다른 많은 헤더 파일에 의해 자동으로 포함되지 않습니다.The <iterator> header is no longer included automatically by many other header files. 대신, 헤더에 정의된 독립 실행형 반복기에 대한 지원이 필요한 경우 해당 헤더를 명시적으로 포함합니다. 이전 빌드 도구인 VCBUILD.exe 또는 프로젝트 파일 접미사 .vcproj를 사용하는 기존 프로젝트에 영향을 줍니다.Instead, include that header explicitly if you require support for the standalone iterators defined in the An existing project is affected if it depends on the previous build tool, VCBUILD.exe, or project file suffix, .vcproj.interator> header.

  • <algorithm> 헤더에서 checked_* and unchecked_* 함수가 제거되었습니다.In the <algorithm> header, the checked_* and unchecked_* functions are removed. 또한 <iterator>> 헤더에서 checked_iteratorclass가 제거되고 unchecked_array_iterator 클래스가 추가되었습니다.And in the <iterator>> header, the checked_iteratorclass is removed, and the unchecked_array_iterator class has been added.

  • CComPtr::CComPtr(int) 생성자가 제거되었습니다.The CComPtr::CComPtr(int) constructor is removed. 해당 생성자는 NULL 매크로에서 CComPtr 개체를 생성할 수 있게 해주지만 불필요하고 0이 아닌 정수에서 무의미한 생성을 허용했습니다.That constructor allowed a CComPtr object to be constructed from the NULL macro, but was unnecessary and allowed nonsensical constructions from non-zero integers.

    0으로 정의된 NULL에서는 CComPtr을 계속 생성할 수 있지만 리터럴 0이 아닌 정수에서 생성할 경우 실패합니다.A CComPtr can still be constructed from NULL, which is defined as 0, but will fail if constructed from an integer other than literal 0. nullptr을 대신 사용합니다.use nullptr instead.

  • ctype 멤버 함수인 ctype::_Do_narrow_s, ctype::_Do_widen_s, ctype::_narrow_s, ctype::_widen_s가 제거되었습니다.The following ctype member functions were removed: ctype::_Do_narrow_s, ctype::_Do_widen_s, ctype::_narrow_s, ctype::_widen_s. 응용 프로그램이 이러한 멤버 함수 중 하나를 사용하는 경우 해당하는 비보안 버전인 ctype::do_narrow,ctype::do_widen, ctype::narrow, ctype::widen으로 대체해야 합니다.If an application uses one of these member functions, you must replace it with the corresponding non-secure version: ctype::do_narrow,ctype::do_widen, ctype::narrow, ctype::widen.

CRT, MFC 및 ATL 라이브러리CRT, MFC, and ATL Libraries

  • 사용자가 CRT, MFC 및 ATL 라이브러리를 빌드할 수 있게 해주는 지원이 제거되었습니다.Support has been removed for users to build the CRT, MFC, and ATL libraries. 예를 들어 해당 nmake 파일이 제공되지 않습니다.For example, an appropriate nmake file is not provided. 그러나 사용자는 이러한 라이브러리에 대한 소스 코드에 계속 액세스할 수 있습니다.However, users still have access to the source code for these libraries. 또한 Microsoft에서 이러한 라이브러리를 빌드하는 데 사용하는 MSBuild 옵션을 설명하는 문서가 Visual C++ 팀 블로그에 게시될 예정입니다.And a document that describes the MSBuild options that Microsoft uses to build these libraries will probably be posted in a Visual C++ Team Blog.

  • IA64의 MFC 지원이 제거되었습니다.MFC support for IA64 has been removed. 그러나 IA64의 CRT 및 ATL 지원은 계속 제공됩니다.However, support for the CRT and ATL on IA64 is still provided.

  • 서수가 MFC 모듈 정의(.def) 파일에서 더 이상 재사용되지 않습니다.Ordinals are no longer reused in MFC module-definition (.def) files. 이 변경으로 인해 부 버전 간에는 서수가 동일하며, 서비스 팩 및 빠른 수정 엔지니어링 릴리스에 대한 이진 호환성이 개선됩니다.This change means ordinals will not be different between minor versions, and binary compatibility for service packs and quick fix engineering releases will be improved.

  • CDocTemplate 클래스에 새 가상 함수가 추가되었습니다.A new virtual function was added to the CDocTemplate class. 새 가상 함수는 CDocTemplate 클래스입니다.This new virtual function is CDocTemplate Class. 이전 버전의 OpenDocumentFile에는 두 개의 매개 변수가 있었습니다.The previous version of OpenDocumentFile had two parameters. 새 버전에는 세 개의 매개 변수가 있습니다.The new version has three parameters. 다시 시작 관리자를 지원하려면 CDocTemplate에서 파생된 모든 클래스가 세 개의 매개 변수가 있는 버전을 구현해야 합니다.To support the restart manager, any class derived from CDocTemplate must implement the version that has three parameters. 새 매개 변수는 bAddToMRU입니다.The new parameter is bAddToMRU.

매크로 및 환경 변수Macros and Environment Variables

  • 환경 변수 __MSVCRT_HEAP_SELECT는 더 이상 지원되지 않습니다.The environment variable __MSVCRT_HEAP_SELECT is no longer supported. 이 환경 변수가 제거되었으며 대체 항목은 없습니다.This environment variable is removed and there is no replacement.

Microsoft 매크로 어셈블러 참조Microsoft Macro Assembler Reference

  • Microsoft 매크로 어셈블러 참조 컴파일러에서 여러 지시문이 제거되었습니다.Several directives were removed from the Microsoft Macro Assembler Reference compiler. 제거된 지시문은 .186, .286, .286P, .287,.8086, .8087 및 .NO87입니다.The removed directives are .186, .286, .286P, .287,.8086, .8087, and .NO87.

Visual C++ 2008의 주요 변경 내용Visual C++ 2008 Breaking Changes

컴파일러Compiler

  • Windows 95, Windows 98, Windows ME 및 Windows NT 플랫폼은 더 이상 지원되지 않습니다.The Windows 95, Windows 98, Windows ME, and Windows NT platforms are no longer supported. 이러한 운영 체제는 대상 플랫폼 목록에서 제거되었습니다.These operating systems have been removed from the list of targeted platforms.

  • 컴파일러가 ATL 서버와 직접 연결된 여러 특성을 더 이상 지원하지 않습니다.The compiler no longer supports multiple attributes that were directly associated with ATL Server. 다음 특성은 더 이상 지원되지 않습니다.The following attributes are no longer supported:

    • perf_counterperf_counter

    • perf_objectperf_object

    • perfmonperfmon

    • request_handlerrequest_handler

    • soap_handlersoap_handler

    • soap_headersoap_header

    • soap_methodsoap_method

    • tag_nametag_name

Visual C++ 프로젝트Visual C++ Projects

  • 이전 버전의 Visual Studio에서 프로젝트를 업그레이드하는 경우 WINVER 및 _WIN32_WINNT 매크로를 0x0500보다 크거나 같도록 수정해야 할 수도 있습니다.When upgrading projects from previous versions of Visual Studio, you might have to modify the WINVER and _WIN32_WINNT macros so that they are greater than or equal to 0x0500.

  • Visual Studio 2008부터 새 프로젝트 마법사에 C++ SQL Server 프로젝트를 만드는 옵션이 없습니다.Beginning with Visual Studio 2008, the new project wizard does not have an option to create a C++ SQL Server project. 이전 버전의 Visual Studio를 사용하여 만든 SQL Server 프로젝트는 제대로 컴파일되고 작동합니다.SQL Server projects created by using an earlier version of Visual Studio will still compile and work correctly.

  • Windows API 헤더 파일인 Winable.h가 제거되었습니다.The Windows API header file Winable.h has been removed. Winuser.h를 대신 포함합니다.Include Winuser.h instead.

  • Windows API 라이브러리인 Rpcndr.lib가 제거되었습니다.The Windows API library Rpcndr.lib has been removed. 대신 rpcrt4.lib에 연결합니다.Link with rpcrt4.lib instead.

CRTCRT

  • Windows 95, Windows 98, Windows Millennium Edition 및 Windows NT 4.0에 대한 지원이 제거되었습니다.Support for Windows 95, Windows 98, Windows Millennium Edition, and Windows NT 4.0 has been removed.

  • 다음 전역 변수가 제거되었습니다.The following global variables have been removed:

    • _osplatform_osplatform

    • _osver_osver

    • _winmajor_winmajor

    • _winminor_winminor

    • _winver_winver

  • 다음 함수가 제거되었습니다.The following functions have been removed. Windows API 함수인 GetVersion 또는 GetVersionEx를 대신 사용합니다.Use the Windows API functions GetVersion or GetVersionEx instead:

    • _get_osplatform_get_osplatform

    • _get_osver_get_osver

    • _get_winmajor_get_winmajor

    • _get_winminor_get_winminor

    • _get_winver_get_winver

  • SAL 주석 구문이 변경되었습니다.The syntax for SAL Annotations has changed. 자세한 내용은 SAL 주석을 참조하세요.For more information, see SAL Annotations.

  • 이제 IEEE 필터가 SSE 4.1 명령 집합을 지원합니다.The IEEE filter now supports the SSE 4.1 instruction set. 자세한 내용은 _fpieee_flt_fpieee_flt를 참조하세요.For more information, see _fpieee_flt_fpieee_flt.

  • Visual Studio와 함께 제공되는 C 런타임 라이브러리가 더 이상 시스템 DLL msvcrt.dll을 사용하지 않습니다.The C Run-Time Libraries that ship with Visual Studio are no longer dependent on the system DLL msvcrt.dll.

표준 라이브러리Standard Library

  • Windows 95, Windows 98, Windows Millennium Edition 및 Windows NT 4.0에 대한 지원이 제거되었습니다.Support for Windows 95, Windows 98, Windows Millennium Edition, and Windows NT 4.0 has been removed.

  • _HAS_ITERATOR_DEBUGGING(Visual Studio 2010 후에는 _ITERATOR_DEBUG_LEVEL로 대체됨)을 정의하여 디버그 모드에서 컴파일하는 경우 반복기가 기본 컨테이너의 경계를 지나서 증가 또는 감소를 시도하면 이제 응용 프로그램이 어설션됩니다.When compiling in debug mode with _HAS_ITERATOR_DEBUGGING defined (superseded by _ITERATOR_DEBUG_LEVEL after Visual Studio 2010), an application will now assert when an iterator attempts to increment or decrement past the bounds of the underlying container.

  • 스택 클래스의 멤버 변수 c가 이제 protected로 선언됩니다.The member variable c of the stack Class is now declared protected. 이전에는 이 멤버 변수가 public으로 선언되었습니다.Previously, this member variable was declared public.

  • money_get::do_get의 동작이 변경되었습니다.The behavior of money_get::do_get has changed. 이전에는 frac_digits에 대해 호출되는 것보다 소수 자릿수가 많은 금액을 구문 분석할 때 do_get이 모든 자릿수를 처리했습니다.Previously, when parsing a monetary amount with more fraction digits than are called for by frac_digits, do_get used to consume them all. 이제 do_get이 frac_digits 자릿수를 처리한 후 구문 분석을 중지합니다.Now, do_get stops parsing after consuming at most frac_digits characters.

ATLATL

  • CRT에 대한 종속성 없이 ATL을 빌드할 수 없습니다.ATL cannot be built without a dependency on CRT. 이전 버전의 Visual Studio에서는 #define ATL_MIN_CRT를 사용하여 ATL 프로젝트의 CRT 종속성을 최소화할 수 있었습니다.In earlier versions of Visual Studio, you could use #define ATL_MIN_CRT to make an ATL project minimally dependent on CRT. Visual C++ 2008에서는 ATL_MIN_CRT 정의 여부에 관계없이 모든 ATL 프로젝트의 CRT 종속성이 최소화됩니다.In Visual C++ 2008, all ATL projects are minimally dependent on CRT regardless of whether ATL_MIN_CRT is defined.

  • ATL 서버 코드베이스가 CodePlex에 공유 소스 프로젝트로 릴리스되었으며 Visual Studio의 일부로 설치되지 않습니다.The ATL Server codebase has been released as a shared source project on CodePlex and is not installed as part of Visual Studio. atlenc.h의 데이터 인코딩 및 디코딩 클래스와 atlutil.h 및 atlpath.h의 유틸리티 함수 및 클래스는 유지되고 ATL 라이브러리에 포함되었습니다.Data encoding and decoding classes from atlenc.h and utility functions and classes from atlutil.h and atlpath.h have been kept and are now part of the ATL library. ATL 서버와 관련된 여러 파일이 더 이상 Visual Studio의 일부로 제공되지 않습니다.Several files associated with ATL Server are no longer part of Visual Studio.

  • 일부 함수가 더 이상 DLL에 포함되지 않습니다.Some functions are no longer included in the DLL. 가져오기 라이브러리에는 계속 유지됩니다.They are still located in the import library. 정적으로 함수를 사용하는 코드에는 영향을 주지 않습니다.This will not affect code that uses the functions statically. 이러한 함수를 동적으로 사용하는 코드에만 영향을 줍니다.It will affect only the code that uses these functions dynamically.

  • PROP_ENTRY 및 PROP_ENTRY_EX 매크로는 사용되지 않으며 보안상의 이유로 PROP_ENTRY_TYPE 및 PROP_ENTRY_TYPE_EX 매크로로 대체되었습니다.The macros PROP_ENTRY and PROP_ENTRY_EX have been deprecated and replaced with the macros PROP_ENTRY_TYPE andPROP_ENTRY_TYPE_EX for security reasons.

ATL/MFC 공유 클래스ATL/MFC Shared Classes

  • CRT에 대한 종속성 없이 ATL을 빌드할 수 없습니다.ATL cannot be built without a dependency on CRT. 이전 버전의 Visual Studio에서는 #define ATL_MIN_CRT를 사용하여 ATL 프로젝트의 CRT 종속성을 최소화할 수 있었습니다.In earlier versions of Visual Studio, you could use #define ATL_MIN_CRT to make an ATL project minimally dependent on CRT. Visual C++ 2008에서는 ATL_MIN_CRT 정의 여부에 관계없이 모든 ATL 프로젝트의 CRT 종속성이 최소화됩니다.In Visual C++ 2008, all ATL projects are minimally dependent on CRT regardless of whether ATL_MIN_CRT is defined.

  • ATL 서버 코드베이스가 CodePlex에 공유 소스 프로젝트로 릴리스되었으며 Visual Studio의 일부로 설치되지 않습니다.The ATL Server codebase has been released as a shared source project on CodePlex and is not installed as part of Visual Studio. atlenc.h의 데이터 인코딩 및 디코딩 클래스와 atlutil.h 및 atlpath.h의 유틸리티 함수 및 클래스는 유지되고 ATL 라이브러리에 포함되었습니다.Data encoding and decoding classes from atlenc.h and utility functions and classes from atlutil.h and atlpath.h have been kept and are now part of the ATL library. ATL 서버와 관련된 여러 파일이 더 이상 Visual Studio의 일부로 제공되지 않습니다.Several files associated with ATL Server are no longer part of Visual Studio.

  • 일부 함수가 더 이상 DLL에 포함되지 않습니다.Some functions are no longer included in the DLL. 가져오기 라이브러리에는 계속 유지됩니다.They are still located in the import library. 정적으로 함수를 사용하는 코드에는 영향을 주지 않습니다.This will not affect code that uses the functions statically. 이러한 함수를 동적으로 사용하는 코드에만 영향을 줍니다.It will affect only the code that uses these functions dynamically.

MFCMFC

  • CTime 클래스: 이제 CTime 클래스가 1970/1/1 C.E 대신 1900/1/1 C.E부터 날짜를CTime Class: The CTime class now accepts dates starting from 1/1/1900 C.E. 허용합니다.instead of 1/1/1970 C.E.
  • MFC 대화 상자의 컨트롤 탭 순서: MFC ActiveX 컨트롤이 탭 순서에 삽입된 경우 MFC 대화 상자에 있는 여러 컨트롤의 올바른 탭 순서를 방해합니다.Tab order of controls in MFC dialogs: The correct tab order of multiple controls in an MFC dialog is disturbed if an MFC ActiveX control is inserted in the tab order. 이 변경은 해당 문제를 해결합니다.This change corrects that problem.

    예를 들어 ActiveX 컨트롤 및 여러 개의 편집 컨트롤이 들어 있는 MFC 대화 상자 응용 프로그램을 만듭니다.For example, create an MFC dialog application that has an ActiveX control and several edit controls. 편집 컨트롤의 탭 순서 중간에 ActiveX 컨트롤을 배치합니다.Position the ActiveX control in the middle of the tab order of the edit controls. 응용 프로그램을 시작하고 탭 순서가 ActiveX 컨트롤 뒤에 오는 편집 컨트롤을 클릭한 후 Tab 키를 누릅니다. 이 변경 전에는 포커스가 탭 순서의 다음 편집 컨트롤 대신 ActiveX 컨트롤 뒤에 있는 편집 컨트롤로 이동했습니다.Start the application, click an edit control whose tab order is after the ActiveX control, then tab. Prior to this change, the focus went to the edit control following the ActiveX control instead of the next edit control in the tab order.

  • CFileDialog 클래스: CFileDialog 클래스에 대한 사용자 지정 템플릿을 Windows Vista로 자동 포팅할 수 없습니다.CFileDialog Class: Custom templates for the CFileDialog class cannot be automatically ported to Windows Vista. 여전히 사용할 수는 있지만 Windows Vista 스타일 대화 상자의 추가 기능이나 모양은 제공되지 않습니다.They are still usable, but will not have the additional functionality or looks of Windows Vista style dialogs.

  • CWnd 클래스 및 CFrameWnd 클래스: CWnd::GetMenuBarInfo 메서드가 제거되었습니다.CWnd Class and CFrameWnd Class: The CWnd::GetMenuBarInfo method was removed.

    CFrameWnd::GetMenuBarInfo 메서드가 이제 비가상 메서드입니다.The CFrameWnd::GetMenuBarInfo method is now a non-virtual method. 자세한 내용은 Windows SDK의 GetMenuBarInfo 함수를 참조하세요.For more information, see GetMenuBarInfo Functionin the Windows SDK.

  • MFC ISAPI 지원: MFC에서 ISAPI(Internet Server Application Programming Interface)를 사용한 응용 프로그램 빌드를 더 이상 지원하지 않습니다.MFC ISAPI support: MFC no longer supports building applications with the Internet Server Application Programming Interface (ISAPI). ISAPI 응용 프로그램을 빌드하려는 경우 ISAPI 확장을 직접 호출합니다.If you want to build an ISAPI application, call the ISAPI extensions directly.

  • 사용되지 않는 ANSI API: 여러 MFC 메서드의 ANSI 버전이 사용되지 않습니다.Deprecated ANSI APIs: The ANSI versions of several MFC methods are deprecated. 이후 응용 프로그램에서는 해당 메서드의 유니코드 버전을 사용합니다.Use the Unicode versions of those methods in your future applications. 자세한 내용은 Windows Vista 공용 컨트롤의 빌드 요구 사항을 참조하세요.For more information, see Build Requirements for Windows Vista Common Controls.

Visual C++ 2005의 주요 변경 내용Visual C++ 2005 Breaking Changes

CRTCRT

  • 많은 함수가 사용되지 않습니다.Many functions have been deprecated. 사용되지 않는 CRT 함수를 참조하세요.See Deprecated CRT Functions.

  • 이제 많은 함수가 매개 변수의 유효성을 검사하며, 잘못된 매개 변수가 제공될 경우 실행을 중지합니다.Many functions now validate their parameters, halting execution if given invalid parameters. 이로 인해 잘못된 매개 변수를 전달하며, 함수가 해당 매개 변수를 무시하거나 단순히 오류 코드를 반환해야 하는 코드가 중단될 수 있습니다.This may break code that passes invalid parameters and relies on the function ignoring them or just returning an error code. 매개 변수 유효성 검사를 참조하세요.See Parameter Validation.

  • 이제 파일 설명자 값 -2를 사용하여 stdout 및 stderr을 출력에 사용할 수 없음을 나타냅니다. 예를 들어 콘솔 창이 없는 Windows 응용 프로그램의 경우입니다.The file descriptor value -2 is now used to indicate that stdout and stderr are not available for output, as for example in a Windows application that has no console window. 이전에는 값 -1을 사용했습니다.The previous value used was -1. 자세한 내용은 _fileno를 참조하세요.For more information, see _fileno.

  • 단일 스레드 CRT 라이브러리인 libc.lib 및 libcd.lib가 제거되었습니다.The single-threaded CRT libraries, libc.lib and libcd.lib, have been removed. 다중 스레드 CRT 라이브러리를 사용합니다.Use the multi-threaded CRT libraries. /ML 컴파일러 플래그가 더 이상 지원되지 않습니다.The /ML compiler flag is no longer supported. 다중 스레드 코드와 단일 스레드 코드 간의 성능 차이가 잠재적으로 중요한 경우를 위해 일부 함수의 비잠금 버전이 추가되었습니다.Non-locking versions of some functions have been added in cases where the performance difference between the multithreaded code and the single-threaded code is potentially significant.

  • pow 오버로드인 double pow(int, int)가 표준 준수를 개선하기 위해 제거되었습니다.The overload of pow, double pow(int, int), was removed to better conform with the standard.

  • 본질적으로 안전하지 않은 %n 형식 지정자는 함수의 printf 패밀리에서 더 이상 기본적으로 지원되지 않습니다.The %n format specifier is no longer supported by default in any of the printf family of functions because it is inherently insecure. %n이 발견된 경우의 기본 동작은 잘못된 매개 변수 처리기를 호출하는 것입니다.The default behavior if %n is encountered is to invoke the invalid parameter handler. %n 지원을 사용하려면 _set_printf_count_output(또는 see_get_printf_count_output)을 사용합니다.To enable %n support, use _set_printf_count_output (also see_get_printf_count_output).

  • 이제 sprintf가 부호 있는 0의 음수 기호를 인쇄합니다.sprintf now prints the negative sign of a signed zero.

  • swprintf가 표준을 준수하도록 변경되었습니다. 이제 크기 매개 변수가 필요합니다.swprintf has been changed to conform with the Standard; it now requires a size parameter. 크기 매개 변수가 없는 swprintf 형태는 사용되지 않습니다.The form of swprintf without a size parameter has been deprecated.

  • _set_security_error_handler가 제거되었습니다._set_security_error_handler has been removed. 해당 함수에 대한 호출을 모두 제거합니다. 기본 처리기가 보안 오류를 처리하는 훨씬 안전한 방법입니다.Remove any calls to that function; the default handler is a much safer way of dealing with security errors.

  • 이제 time_t가 64비트 값입니다(_USE_32BIT_TIME_T가 정의되지 않은 경우).time_t is now a 64-bit value (unless _USE_32BIT_TIME_T is defined).

  • 이제 _spawn, _wspawn 함수가 C 표준에 지정된 대로 성공 시 errno를 그대로 유지합니다.The _spawn, _wspawn Functions now leave errno untouched on success, as specified by the C Standard.

  • 이제 RTC가 기본적으로 와이드 문자를 사용합니다.RTC now uses wide characters by default.

  • 부동 소수점 제어 단어 지원 함수가 /CLR 또는 /CLR:PURE로 컴파일된 응용 프로그램에 대해 사용되지 않습니다.Floating-point control word support functions have been deprecated for applications compiled with /CLR or /CLR:PURE. 영향을 받는 함수는 _clear87, _clearfp, _control87, _controlfp, _fpreset, _status87, _statusfp입니다.The affected functions are _clear87, _clearfp, _control87, _controlfp, _fpreset, _status87, _statusfp. _CRT_MANAGED_FP_NO_DEPRECATE를 정의하여 사용 중단 경고를 해제할 수 있지만 관리 코드에서 이러한 함수의 사용은 예측하기 어렵고 지원되지 않습니다.You can disable the deprecation warning by defining _CRT_MANAGED_FP_NO_DEPRECATE, but the use of these functions in managed code is unpredictable and unsupported.

  • 이제 일부 함수가 const 포인터를 반환합니다.Some functions now return const pointers. _CONST_RETURN을 정의하면 이전의 비 const 동작을 복구할 수 있습니다.The old, non-const behavior can be reinstated by defining _CONST_RETURN. 영향을 받는 함수는 다음과 같습니다.The affected functions are

    1. memchr, wmemchrmemchr, wmemchr

    2. strchr, wcschr, _mbschr, _mbschr_lstrchr, wcschr, _mbschr, _mbschr_l

    3. strpbrk, wcspbrk, _mbspbrk, _mbspbrk_lstrpbrk, wcspbrk, _mbspbrk, _mbspbrk_l

    4. strrchr, wcsrchr, _mbsrchr, _mbsrchr_lstrrchr, wcsrchr, _mbsrchr, _mbsrchr_l

    5. strstr, wcsstr, _mbsstr, _mbsstr_lstrstr, wcsstr, _mbsstr, _mbsstr_l

  • Setargv.obj 또는 Wsetargv.obj에 연결하는 경우 더 이상 명령줄에서 와일드카드 문자를 큰따옴표로 묶어 확장을 억제할 수 없습니다.When linking with Setargv.obj or Wsetargv.obj, it is no longer possible to suppress the expansion of a wildcard character on the command line by enclosing it in double quotes. 자세한 내용은 와일드카드 인수 확장을 참조하세요.For more information, see Expanding Wildcard Arguments.

표준 라이브러리(2005)Standard Library (2005)

  • exception 클래스(<exception> 헤더에 있음)가 std 네임스페이스로 이동되었습니다.The exception class (located in the <exception> header) has been moved to the std namespace. 이전 버전에서는 이 클래스가 전역 네임스페이스에 있었습니다.In previous versions, this class was in the global namespace. exception 클래스를 찾을 수 없다는 오류를 해결하려면 다음 using 문을 코드에 추가합니다. using namespace std;To resolve any errors indicating that the exception class cannot be found, add the following using statement to your code: using namespace std;

  • valarray::resize()를 호출하는 경우 valarray의 내용이 손실되고 기본값으로 대체됩니다.When calling valarray::resize(), the contents of the valarray will be lost and will be replaced by default values. resize() 메서드는 벡터처럼 동적으로 확장하는 대신 valarray를 다시 초기화합니다.The resize() method is intended to reinitialize the valarray rather than grow it dynamically like a vector.

  • 디버그 반복기: C 런타임 라이브러리의 디버그 버전으로 빌드된 응용 프로그램이 반복기를 잘못 사용하는 경우 런타임에 어설션이 표시될 수 있습니다.Debug Iterators: Applications built with a debug version of the C-Runtime Library and which use iterators incorrectly might begin to see asserts at runtime. 이러한 어설션을 사용하지 않으려면 _HAS_ITERATOR_DEBUGGING(Visual Studio 2010 후에는 _ITERATOR_DEBUG_LEVEL로 대체됨)을 0으로 정의해야 합니다.To disable these asserts, you must define _HAS_ITERATOR_DEBUGGING (superseded by _ITERATOR_DEBUG_LEVEL after Visual Studio 2010) to 0. 자세한 내용은 디버그 반복기 지원을 참조하세요.For more information, see Debug Iterator Support

Visual C++ .NET 2003의 주요 변경 내용Visual C++ .NET 2003 Breaking Changes

컴파일러Compiler

  • 이제 정의된 전처리기 지시문(C2004)에 닫는 괄호가 필요합니다.Closing parentheses now required for the defined preprocessor directive (C2004).

  • 명시적 특수화가 더 이상 기본 템플릿에서 템플릿 매개 변수를 찾지 않습니다(컴파일러 오류 C2146).Explicit specializations no longer find template parameters from primary template (Compiler Error C2146).

  • 보호된 멤버(n)는 (n)이 속하는 클래스(A)에서 상속하는 클래스(B)의 멤버 함수를 통해서만 액세스할 수 있습니다(컴파일러 오류 C2247).A protected member (n) can only be accessed through a member function of a class (B) that inherits from the class (A) of which it (n) is a member (Compiler Error C2247).

  • 이제 컴파일러의 향상된 접근성 검사에서 액세스할 수 없는 기본 클래스가 검색됩니다(컴파일러 오류 C2248).Improved accessibility checks in compiler now detect inaccessible base classes (Compiler Error C2248).

  • 소멸자로 및/또는 복사 생성자에 액세스할 수 없는 경우 예외를 catch할 수 없습니다(C2316).An exception cannot be caught if the destructor and/or copy constructor is inaccessible (C2316).

  • 함수에 대한 포인터의 기본 인수가 더 이상 허용되지 않습니다(컴파일러 오류 C2383).Default arguments on pointers to functions no longer allowed (Compiler Error C2383).

  • 파생 클래스를 통해 정적 데이터 멤버를 초기화할 수 없습니다(컴파일러 오류 C2477).A static data member cannot be initialized via derived class (Compiler Error C2477).

  • typedef의 초기화가 표준에서 허용되지 않으며 이제 컴파일러 오류를 생성합니다(컴파일러 오류 C2513).The initialization of a typedef is not allowed by the standard and now generates a compiler error (Compiler Error C2513).

  • 이제 bool이 올바른 형식입니다(컴파일러 오류 C2632).bool is now a proper type (Compiler Error C2632).

  • 이제 UDC가 오버로드된 연산자로 모호성을 만들 수 있습니다(C2666).A UDC can now create ambiguity with overloaded operators (C2666).

  • 이제 더 많은 식이 유효한 null 포인터 상수로 간주됩니다(컴파일러 오류 C2668).More expressions are now considered valid null pointer constants (Compiler Error C2668).

  • 이전에는 컴파일러에서 암시되었을 위치에 이제 template<>이 필요합니다(컴파일러 오류 C2768).template<> is now required in places where the compiler would previously imply it (Compiler Error C2768).

  • 함수가 이미 템플릿 클래스 특수화를 통해 명시적으로 특수화된 경우 클래스 외부에서 멤버 함수의 명시적 특수화는 유효하지 않습니다(컴파일러 오류 C2910).The expilicit specialization of a member function ourside the class is not valid if the function has already been explicitly specialized via a template class specialization (Compiler Error C2910).

  • 부동 소수점 비형식 템플릿 매개 변수가 더 이상 허용되지 않습니다(컴파일러 오류 C2993).Floating point non-type template parameters are no longer allowed (Compiler Error C2993).

  • 클래스 템플릿이 템플릿 형식 인수로로 허용되지 않습니다(C3206).Class templates are not allowed as template type arguments (C3206).

  • 친숙한 함수 이름이 포함하는 네임스페이스에 더 이상 도입되지 않습니다(컴파일러 오류 C3767).Friend function names are no longer introduced into containing namespace (Compiler Error C3767).

  • 컴파일러에서 매크로의 추가 쉼표를 더 이상 허용하지 않습니다(C4002).The compiler will no longer accept extra commas in a macro (C4002).

  • form()의 이니셜라이저로 생성된 POD 형식의 개체가 기본값으로 초기화됩니다(C4345).An object of POD type constructed with an initializer of the form () will be default-initialized (C4345).

  • 이제 종속 이름이 형식으로 처리되어야 하는 경우 typename이 필요합니다(컴파일러 경고(수준 1) C4346).typename is now required if a dependent name is to be treated as a type (Compiler Warning (level 1) C4346).

  • 템플릿 특수화로 잘못 간주된 함수가 더 이상 그렇게 간주되지 않습니다(C4347).Functions that were incorrectly considered template specializations are no longer considered so (C4347).

  • 파생 클래스를 통해 정적 데이터 멤버를 초기화할 수 없습니다(C4356).Static data members cannot be initialized via derived class (C4356).

  • 클래스 템플릿 특수화가 반환 형식에 사용되기 전에 정의해야 합니다(컴파일러 경고(수준 3) C4686).A class template specialization needs to be defined before it was used in a return type (Compiler Warning (level 3) C4686).

  • 이제 컴파일러에서 연결할 수 없는 코드를 보고합니다(C4702).The compiler now reports unreachable code (C4702).

참고 항목See Also

Visual Studio의 Visual C++에 대한 새로운 기능What's New for Visual C++ in Visual Studio