Visual C++ 2005 컴파일러의 주요 변경 사항

업데이트: 2007년 11월

이 항목에서는 이전 릴리스에서 작동하던 코드가 컴파일되지 않거나 런타임에 다르게 동작하는 결과를 가져올 수 있는 Visual C++ 2005의 변경된 동작에 대해 설명합니다.

새로운 기능에 대한 자세한 내용은 Visual C++ 2005 및 이전 버전의 변경 내용, Visual C++ 2005 라이브러리의 변경 사항Visual C++ 2005 컴파일러, 언어 및 도구의 변경 내용을 참조하십시오.

  • 이제 멤버 포인터에 정규화된 이름과 &가 필요합니다.
    메서드 이름만 사용하던 이전 버전의 컴파일러용으로 작성된 코드의 경우 컴파일러 오류 C3867 또는 컴파일러 경고 C4867이 발생합니다. 이러한 진단은 표준 C++에서 요구하는 사항입니다. 이제 멤버 함수에 대한 포인터를 만들려면 연산자(&)의 주소를 정규화된 메서드 이름과 함께 사용해야 합니다. & 연산자와 메서드의 정규화된 이름을 사용할 필요가 없으면 함수 호출에서 누락된 괄호로 인해 코드에서 논리 버그가 발생할 수 있습니다. 인수 목록 없이 함수 이름을 사용하면 여러 형식으로 변환될 수 있는 함수 포인터가 생성됩니다. 이 코드를 컴파일하면 런타임에 예상치 않은 동작이 발생합니다.

  • Friend 선언에서 클래스에 액세스할 수 있어야 합니다.
    Visual C++ 2005 이전의 Visual C++ 컴파일러에서는 선언이 포함된 클래스 범위에서 액세스할 수 없는 클래스에 friend 선언을 사용할 수 있었습니다. 이제 컴파일러에서는 컴파일러 오류 C2248이 발생합니다. 이 오류를 해결하려면 friend 선언에 지정된 클래스의 액세스 가능성을 변경합니다. C++ 표준을 따르도록 이와 같이 변경되었습니다.

  • 이제 __int asm 3이 네이티브로 컴파일됩니다.
    /clr을 사용하여 컴파일할 때 __asm int 3에서 네이티브 코드를 생성하지 않은 경우 컴파일러에서는 명령을 CLR 중단 명령으로 변환했습니다. 이제 Visual C++ 2005에서는 __asm int 3에서 함수에 대해 네이티브 코드가 생성됩니다. 함수가 코드에서 중단점을 발생시키게 하고 함수가 MSIL로 컴파일되게 하려면 __debugbreak를 참조하십시오. 자세한 내용은 __asm/clr(공용 언어 런타임 컴파일)을 참조하십시오. 관리 코드보다는 네이티브 코드를 생성할 경우를 더욱 명확히 하기 이렇게 변경되었습니다. 즉, 인라인 어셈블리에서는 네이티브 코드를 생성해야 합니다.

  • 명시적 특수화를 복사 생성자나 복사 할당 연산자로 사용할 수 없습니다.
    이제 복사 생성자나 복사 할당 연산자에 대한 명시적 템플릿 특수화에 따라 달라지는 코드를 사용하면 컴파일러 오류 C2299가 발생합니다. 표준 C++에서는 이 코드를 사용할 수 없습니다. 코드 이식성을 향상하기 위해 표준을 따르도록 이와 같이 변경되었습니다.

  • 특수화되지 않은 클래스 템플릿은 기본 클래스 목록에서 템플릿 인수로 사용할 수 없습니다.
    기본 클래스 목록에서 특수화되지 않은 템플릿 클래스 이름을 클래스 정의에 사용하면 컴파일러 오류 C3203이 발생합니다. 특수화되지 않은 템플릿 클래스 이름은 기본 클래스 목록에서 템플릿 매개 변수로 사용할 수 없습니다. 특수화되지 않은 템플릿 클래스 이름을 기본 클래스 목록에서 템플랫 매개 변수로 사용할 때는 템플릿 클래스 이름에 템플릿 형식 매개 변수를 명시적으로 추가합니다. 코드 이식성을 향상하기 위해 표준을 따르도록 이와 같이 변경되었습니다.

  • 중첩 형식의 선언을 더 이상 사용할 수 없습니다.
    이제 중첩 형식의 선언이 있는 코드를 사용하면컴파일러 오류 C2885가 생성됩니다. 이 오류를 해결하려면 중첩 형식에 대한 참조를 정규화하거나 네임스페이스에 이 형식을 배치하거나 typedef를 만들어야 합니다. 코드 이식성을 향상하기 위해 표준을 따르도록 이와 같이 변경되었습니다.

  • 컴파일러에서 const_cast가 /clr:oldSyntax 아래로 다운캐스팅할 수 없습니다.
    Visual C++ 2005 이전의 Visual C++ 컴파일러에서는 Managed Extensions for C++ 구문을 사용하는 소스 코드를 컴파일할 때 const_cast Operator를 다운캐스팅할 수 있었습니다. 이제 const_cast를 사용하여 다운캐스트를 수행하면 컴파일러 오류 C2440이 발생합니다. 이 오류를 해결하려면 올바른 캐스트 연산자를 사용해야 합니다. 자세한 내용은 Casting Operators를 참조하십시오. 표준을 따르도록 이와 같이 변경되었습니다.

  • 컴파일러에서 관리되는 열거형의 정방향 선언을 허용하지 않습니다.
    Visual C++ 2005 이전의 Visual C++ 컴파일러에서는 관리되는 열거형의 정방향 선언을 허용했습니다. 이제 /clr 형식을 사용하여 컴파일할 때 관리되는 열거형을 선언만 하고 정의하지 않으면 컴파일러 오류 C2599가 발생합니다. 이 오류를 해결하려면 선언 시 관리되는 열거형을 항상 정의합니다. 관리되는 열거형의 정방향 선언이 항상 올바로 작동한다고 보장하지 못했기 때문에 이와 같이 변경되었습니다. 컴파일러에서는 열거형의 내부 형식을 올바로 식별할 수 없습니다. 또는 C++ 표준에서는 열거형 선언을 허용하지 않습니다.

  • /YX 컴파일러 옵션이 제거되었습니다.
    /YX 옵션은 미리 컴파일된 헤더 자동 지원을 생성했으며 개발 환경에서 기본적으로 사용되었습니다. 빌드 구성에서 /YX를 제거하고 다른 옵션을 대신 사용하지 않으면 빌드 속도를 향상시킬 수 있습니다. /YX를 사용할 경우 예기치 않은 동작이 발생할 수 있다는 점 외에도 /Yc(미리 컴파일된 헤더 파일 만들기)/Yu(미리 컴파일된 헤더 파일 사용) 옵션을 사용할 경우 미리 컴파일된 헤더를 사용하는 방법을 더욱 잘 제어할 수 있으므로 이들 옵션을 사용하는 것이 좋습니다.

  • /Oa/Ow 컴파일러 옵션이 제거되었습니다.
    /Ow/Oa 컴파일러 옵션이 제거되었으며 이들 옵션을 사용해도 자동으로 무시됩니다. 컴파일러가 별칭을 설정하는 방식을 지정하는 데는 noalias 또는 restrict__declspec 한정자를 사용합니다.

  • /Op 컴파일러 옵션이 제거되었습니다.
    /Op 컴파일러 옵션이 제거되었습니다. /fp(부동 소수점 동작 지정)를 대신 사용해야 합니다.

  • /ML/MLd 컴파일러 옵션이 제거되었습니다.
    Visual C++에서는 정적으로 링크된 단일 스레드 CRT 라이브러리 지원을 더 이상 지원하지 않음 대신 /MT/MTd를 사용합니다. 자세한 내용은 C Run-Time Libraries를 참조하십시오.

  • /G3, /G4, /G5, /G6, /G7/GB 컴파일러 옵션이 제거되었습니다.
    이제 컴파일러에서는 모든 아키텍터에 가장 적합한 출력 파일을 만드는 복합 모델을 사용합니다.

  • /Gf가 제거되었습니다.
    /GF(중복 문자열 제거)를 대신 사용합니다. /GF는 풀링된 문자열을 읽기 전용 섹션에 넣습니다. 읽기 전용 섹션은 /Gf가 해당 문자열을 추가한 쓰기 가능 섹션보다 안전합니다.

  • /clr/MT와 함께 사용할 수 없습니다.
    C 런타임 라이브러리에서는 관리되는 응용 프로그램과의 정적 링크를 지원하지 않습니다. 모든 관리되는 응용 프로그램은 동적으로 링크해야 합니다(/MD). /clr 사용 시 제한 사항에 대한 자세한 내용은 /clr 제한을 참조하십시오.

  • /GS가 기본적으로 사용됩니다.
    이제 버퍼 오버플로 검사가 기본적으로 설정됩니다. /GS-를 사용하여 버퍼 오버런 검사를 해제할 수 있습니다. 자세한 내용은 /GS(버퍼 보안 검사)를 참조하십시오.

  • /Zc:wchar_t가 기본적으로 사용됨
    이것은 표준 C++ 동작입니다. wchar_t 변수는 short unsigned 정수 대신 기본 제공 형식을 기본값으로 사용합니다. 이러한 변경 때문에 /Zc:wchar_t 없이 컴파일된 라이브러리에 클라이언트 코드를 링크하면 이진 호환성이 유지되지 않습니다(LNK2019). 이 경우 /Zc:wchar_t-를 사용하여 이전의 비표준 동작으로 되돌릴 수 있습니다. 기본적으로 호환되는 코드가 만들어지도록 이렇게 변경된 것입니다.

    자세한 내용은 /Zc:wchar_t(wchar_t를 네이티브 형식으로 인식)를 참조하십시오.

  • /Zc:forScope가 기본적으로 사용됩니다.
    이것은 표준 C++ 동작입니다. 이제 for 루프 범위가 끝난 후 for 루프에 선언된 변수의 사용에 따라 달라지는 코드는 컴파일할 수 없습니다. /Zc:forScope-를 사용하여 이전의 비표준 동작으로 되돌릴 수 있습니다. 기본적으로 호환되는 코드가 만들어지도록 이렇게 변경된 것입니다.

    자세한 내용은 /Zc:forScope(for 루프 범위의 강제 규칙)를 참조하십시오.

  • Visual C++ 특성에 매개 변수 검사를 적용합니다.
    명명된 특성을 특성 생성자에 전달할 때 형식이 문자열이 아닐 경우 따옴표로 묶어 전달하고 형식이 문자열일 경우에는 따옴표 없이 전달하는 코드를 사용하면 이제 컴파일러 오류 C2065 또는 컴파일러 경고(수준 1) C4581이 발생합니다. 이전에는 모든 컴파일러 특성이 문자열로 구문 분석되었으며, 필요한 경우 누락된 따옴표를 컴파일러에서 자동으로 삽입했습니다. 이제 매개 변수 유효성 검사 기능이 추가되어 특성 지원이 향상되었습니다. 따라서 특성 생성자에 잘못된 인수가 전달되는 경우에 발생하는 예기치 않은 동작을 방지할 수 있습니다.

    이 릴리스에서는 암시적 문자열을 인수로 사용하는 특성의 인수에 MBCS(멀티바이트 문자열)를 따옴표로 묶더라도 사용할 수 없습니다. 이렇게 하면 손상된 .idl 파일이 생성될 수 있습니다. 이 문제에 대한 해결 방법은 다음과 같습니다.

    #define ARG string_with_MBCS_chars
    [helpstring(ARG)]
    
  • 컴파일러에서는 이제 같은 형식의 여러 선언에 대해 템플릿을 동일하게 지정해야 합니다.
    예를 들어 해당 형식의 friend를 만들 수 있도록 형식에 전방향 선언을 사용하는 경우 해당 형식의 모든 선언에서 형식에 대한 템플릿 지정이 동일해야 합니다. 그렇지 않으면 컴파일러에서 컴파일러 오류 C2990이 발생합니다.

  • uuid 특성에서는 더 이상 관리되는 형식을 대상으로 지정할 수 없습니다.
    uuid (C++ Attributes) 특성은 이전에는 Managed Extensions for C++를 사용하는 사용자 정의 특성에서 사용할 수 있었지만 이제 컴파일러 오류 C3451을 생성합니다. 대신 GuidAttribute를 사용합니다.

  • 관리되는 배열을 사용자 지정 속성에 전달하는 구문의 변경 사항
    배열 형식이 더 이상 집합체 초기화 목록에서 추론되지 않습니다. 컴파일러를 실행할 때 이니셜라이저 목록과 배열의 형식을 함께 지정해야 합니다. 이전 구문을 사용하면 컴파일러 오류 C3104가 발생합니다. 컴파일러에서 배열 형식을 집합체 초기화 목록을 통해 추론할 수 없는 경우가 있었기 때문에 이와 같이 변경되었습니다.

  • 컴파일러에서 선언에 int를 기본 형식으로 삽입하지 않습니다.
    선언에 형식이 없는 코드가 더 이상 int 형식으로 기본 설정되지 않습니다. 컴파일러에서는 컴파일러 경고 C4430 또는 컴파일러 경고(수준 4) C4431을 생성합니다. 표준 C++에서는 기본 int를 지원하지 않으며 이러한 변경 때문에 원하는 형식을 가져올 수 있습니다.

  • dynamic_cast가 C++ 표준을 따르도록 개선되었습니다.
    C 런타임 라이브러리는 이제 dynamic_cast 런타임 검사를 수행하여 캐스팅되는 식의 컴파일 타임 형식이 캐스트 대상 형식(다운캐스팅의 경우) 또는 대부분의 파생된 개체 형식(크로스캐스팅의 경우) 중 하나의 공용 기본 클래스 하위 개체를 참조하도록 합니다. 자세한 내용은 dynamic_cast의 주요 변경 사항을 참조하십시오.

  • 비상수 참조에 rvalue를 바인딩할 수 없습니다.
    비상수 참조에 rvalue를 바인딩할 수 없습니다. 이전 버전의 Visual C++에서는 직접 초기화를 통해 비상수 참조에 rvalue를 바인딩할 수 있었습니다. 이제 이 코드에서는 컴파일러 경고(수준 1) C4350을 생성합니다.

  • 값 형식에서 더 이상 기본 생성자를 내보내지 않으므로 형식 이니셜라이저가 다른 지점에서 실행될 수 있습니다.
    Visual C++ 2005 이전에는 값 형식의 인스턴스를 만들 때 값 형식의 정적 생성자(형식 이니셜라이저)가 실행되었습니다. 정적 생성자가 실행되게 하려면 정적 데이터 멤버에 액세스하거나 인스턴스 생성자를 정의합니다(/clr:oldSyntax에만 해당). 공용 언어 런타임에서 항상 기본 생성자를 호출하는 것은 아니므로 값 형식의 기본 생성자를 지정하지 않았습니다. 또한 값 형식의 기본 생성자를 지정하지 않으면 성능이 개선됩니다.

  • Boxed 값 형식은 이제 확인할 수 없는 (/clr:safe) 컨텍스트에서만 읽을 수 있습니다.
    공용 언어 런타임에서는 확인할 수 없는 어셈블리를 컴파일할 때 더 이상 boxed 값 형식을 수정할 수 없습니다. 이제 컴파일러에서는 이 형식을 발견하는 경우 컴파일러 경고 C4972가 발생합니다.

    C4792는 boxed 값 개체를 통해 내부 값 개체의 값을 변경하는 경우에만 발생합니다. 예를 들어 boxed 개체를 변경하는 것과 같이 값 개체의 복사본을 변경하는 경우에는 이 오류가 발생하지 않습니다.

  • 네이티브 형식은 어셈블리 외부에서 기본적으로 private입니다.
    이제 네이티브 형식은 어셈블리 외부에서 기본적으로 표시되지 않습니다. 어셈블리 외부에서 형식 표시에 대한 자세한 내용은 Type Visibility을 참조하십시오. 기본적으로 Visual C++에서 작성된 메타데이터를 참조할 때 다른 대/소문자 구분 언어를 사용하는 개발자의 요구 때문에 이렇게 변경되었습니다.

  • /clr에서는 이제 Visual C++의 새로운 CLR 구문을 사용할 수 있습니다.
    Visual C++ 2005 이전에는 /clr에서 Managed Extensions for C++ 구문을 컴파일했습니다. 이제 /clr에서는 새로운 CLR 구문을 컴파일하고 /clr:oldSyntax에서 Managed Extensions for C++ 구문을 컴파일합니다. /clr에 대한 자세한 내용은 /clr(공용 언어 런타임 컴파일)을 참조하십시오. 새로운 구문에 대한 자세한 내용은 New C++ Language Features를 참조하십시오.

  • /clr에서는 더 이상 C 소스 코드 파일을 컴파일하지 않습니다.
    Visual C++ 2005 이전에는 /clr을 사용하여 C 소스 코드 파일을 컴파일할 수 있었지만 이제는 이렇게 하면 명령줄 오류 D8045를 발생합니다. 이 문제를 해결하려면 파일 확장명을 .cpp 또는 .cxx로 변경하거나 /TP 또는 /Tp 옵션을 사용하여 컴파일합니다. 자세한 내용은 /Tc, /Tp, /TC, /TP(소스 파일 형식 지정)를 참조하십시오.

  • 같음 여부를 테스트할 때 MSIL가 변경됩니다.
    자세한 내용은 방법: 같음 여부 테스트를 참조하십시오.

참고 항목

참조

Visual C++ 컴파일러의 주요 변경 사항