본문 바로가기
프로그래밍 기록/Tip

Visual Studio 2015의 새로운 C++ 기능

by hominic 2023. 12. 8.
728x90
반응형
반응형

Visual Studio 2015 이상 버전에서 컴파일러 규칙이 지속적으로 향상됨으로써 컴파일러에서 기존의 소스 코드를 인식하는 방식이 변경되는 경우가 있습니다. 이로 인해 빌드 새로운 오류 또는 다른 오류가 발생하거나, 이전에 빌드되어 올바르게 실행되는 것처럼 보이는 코드가 다르게 동작할 수도 있습니다.

다행히 이러한 차이는 대부분의 소스 코드에 거의 또는 전혀 영향을 주지 않으며, 차이를 해결하기 위해 소스 코드 변경이나 기타 변경이 필요한 경우에도 대체로 간단히 처리할 있는 사소한 수정입니다. 이전에는 허용되는 소스 코드였지만 변경해야 있는 코드 (이전)  수정 코드 (이후)  많은 예가 포함되어 있습니다.

이러한 차이가 소스 코드나 다른 빌드 아티팩트에 영향을 수도 있지만 Visual C++ 버전 업데이트 간의 이진 호환성에는 영향을 주지 않습니다. 보다 심각한 종류의 변경인 주요 변경 내용  이진 호환성에 영향을 있지만 이러한 종류의 이진 호환성 중단은 Visual C++ 버전 간에만 발생합니다. 예를 들어 Visual C++ 2013 Visual C++ 2015 간에 발생합니다. Visual C++ 2013 Visual C++ 2015 사이에 발생한 주요 변경 내용에 대한 자세한 내용은 Visual C++ 변경 기록 2003 - 2015 참조하세요.

·        Visual Studio 2015 규칙 향상

·        Visual Studio 2015 업데이트 1 규칙 향상

·        Visual Studio 2015 업데이트 2 규칙 향상

·        Visual Studio 2015 업데이트 3 규칙 향상

Visual Studio 2015 규칙 향상

·        /Zc:forScope- 옵션

/Zc:forScope- 컴파일러 옵션은 이상 사용되지 않으므로 이후 릴리스에서 제거될 예정입니다.

출력복사

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

옵션은 대개 표준에 따라 범위를 벗어나야 하는 지점 뒤에서 루프 변수를 사용하는 비표준 코드를 허용하려고 사용됩니다/Za 사용하지 않으면 루프 끝에 for 루프 변수를 항상 사용할 있으므로 /Za 옵션으로 컴파일할 경우에만 필요합니다. 표준 준수가 중요하지 않으면(: 코드가 다른 컴파일러에 이식 가능하지 않은 경우/Za 옵션을 해제하거나 언어 확장 사용  속성을 아니요  설정할 있습니다. 이식 가능한 표준 규격 코드를 작성해야 하면 변수의 선언을 루프 외부 지점으로 이동하여 표준을 따르도록 코드를 다시 작성해야 합니다.

C++복사

  // zc_forScope.cpp

  // compile with: /Zc:forScope- /Za

  // 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 컴파일러 옵션(함수 프로토타입 생성) 이상 사용할 없습니다. 컴파일러 옵션은 이미 사용되지 않습니다.

·        mstest.exe 사용하여 명령줄에서 C++/CLI 대한 단위 테스트를 이상 실행할 없습니다. 대신 vstest.console.exe 사용합니다.

·        mutable 키워드

mutable 이전에 오류 없이 컴파일된 위치에서는 저장소 클래스 지정 자가 이상 허용 되지 않습니다. 현재 컴파일러에서는 오류 C2071(스토리지 클래스가 잘못되었습니다.) 표시합니다. 표준에 따라 mutable 지정자는 클래스 데이터 멤버의 이름에만 적용되고 const 또는 static으로 선언된 이름과 참조 멤버에는 적용할 없습니다.

예를 들어, 다음 코드를 고려하세요.

C++복사

  struct S {

      mutable int &r;

  };

이전 Microsoft C++ 컴파일러 버전에서는 이를 허용했으나 현재 컴파일러에서는 다음 오류를 표시합니다.

Output복사

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

오류를 해결 하려면 중복 키워드를 제거 하면 됩니다 mutable .

·        char_16_t char32_t

char16_t char32_t 이러한 형식은 이제 기본 제공으로 처리 되므로 typedef에서 또는 별칭으로 이상 사용할 없습니다. 일반적으로 사용자와 라이브러리 작성자는 char16_t  char32_t uint16_t  각각 및의 별칭으로 정의 하는 것이 일반적 이었습니다 uint32_t .

C++복사

  #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  이러한 이름과 충돌 하는 다른 식별자의 이름을 바꿉니다.

·        비형식 템플릿 매개 변수

이제는 비형식 템플릿 매개 변수가 포함된 특정 코드에 명시적 템플릿 인수를 제공하면 형식 호환성 검사가 정확하게 수행됩니다. 예를 들어 다음 코드는 이전 Visual C++ 버전에서는 오류 없이 컴파일되었습니다.

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입니다.

Output복사

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

코드에서 오류를 해결하려면 사용하는 템플릿 인수 형식이 템플릿 매개 변수의 선언된 형식과 일치해야 합니다.

·        __declspec(align)

컴파일러가 함수에서 __declspec(align)  이상 허용하지 않습니다. 이는 항상 무시되었지만 현재는 컴파일러 오류가 생성됩니다.

C++복사

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

문제를 수정하려면 함수 선언에서 __declspec(align)  제거합니다. 아무런 영향이 없으므로 제거해도 아무것도 변경되지 않습니다.

·        예외 처리

예외 처리에 대한 가지 변경 내용이 있습니다. 먼저 예외 개체는 복사 가능하거나 이동 가능해야 합니다. 다음 코드는 Visual Studio 2013에서 컴파일되지만 Visual Studio 2015에서는 컴파일되지 않습니다.

C++복사

  struct S {

  public:

      S();

  private:

      S(const S &);

  };

 

  int main()

  {

      throw S(); // error

  }

문제는 복사 생성자가 private이라는 점이므로 일반적인 예외 처리 과정으로는 개체를 복사할 없습니다. 복사 생성자가 선언 경우에도 마찬가지 explicit 입니다.

C++복사

  struct S {

      S();

      explicit S(const S &);

  };

 

  int main()

  {

      throw S(); // error

  }

코드를 업데이트 하려면 예외 개체에 복사 생성자가 public 표시 되지 않았는지 확인 explicit 합니다.

값으로 예외를 catch하려면 예외 개체가 복사 가능해야 합니다. 다음 코드는 Visual Studio 2013에서 컴파일되지만 Visual Studio 2015에서는 컴파일되지 않습니다.

C++복사

  struct B {

  public:

      B();

  private:

      B(const B &);

  };

 

  struct D : public B {

  };

 

  int main()

  {

      try

      {

      }

      catch (D d) // error

      {

      }

  }

매개 변수 형식을 참조로 변경 하면이 문제를 해결할 있습니다 catch .

C++복사

  catch(D& d)

  {

  }

·        매크로 뒤의 문자열 리터럴

현재 컴파일러는 사용자 정의 리터럴을 지원합니다. 따라서 중간 공백 없이 매크로 뒤의 문자열 리터럴은 오류나 예기치 않은 결과를 생성할 있는 사용자 정의 리터럴로 해석됩니다. 예를 들어 이전 컴파일러에서는 다음 코드가 성공적으로 컴파일되었습니다.

C++복사

  #define _x "there"

  char* func() {

      return "hello"_x;

  }

  int main()

  {

      char * p = func();

      return 0;

  }

컴파일러에서 코드는 매크로 뒤의 문자열 리터럴 "hello" 해석되고 “there” 확장되었고 문자열 리터럴은 하나로 연결되었습니다. Visual Studio 2015에서 컴파일러는 코드를 사용자 정의 리터럴로 해석하지만 일치하는 사용자 정의 리터럴 _x 정의되지 않았으므로 오류가 발생합니다.

C++복사

  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?

 

문제를 수정하려면 문자열 리터럴과 매크로 사이에 공백을 추가합니다.

·        인접 문자열 리터럴

이전과 비슷하게 문자열 구문 분석의 관련 변경 내용 때문에 공백이 없는 인접 문자열 리터럴(전각 또는 반각 문자 문자열 리터럴) 이전 Visual C++ 릴리스에서 하나의 연결된 문자열로 해석되었습니다. Visual Studio 2015에서는 현재 문자열 사이에 공백을 추가해야 합니다. 예를 들어 다음 코드를 변경해야 합니다.

C++복사

  char * str = "abc""def";

문자열 사이에 공백을 추가하면 됩니다.

C++복사

  char * str = "abc" "def";

·        Placement new delete

delete 연산자가 c + + 14 표준을 준수 하도록 변경 되었습니다. 표준 변경에 대한 자세한 내용은 C++ 크기 지정된 할당 해제(영문) 참조하세요. 변경 내용에는 delete 크기 매개 변수를 사용 하는 전역 연산자의 폼이 추가 됩니다. 주요 변경 내용은 이전에 배치 new 연산자와 일치 하는 것과 같은 서명을 사용 이전에 배치 new 연산자를 사용 하는 경우 컴파일러 delete 오류 (C2956) 받게 됩니다 .이는 컴파일러가 적절 일치 연산자를 식별 하는 코드의 위치 이기 때문입니다 delete .

void operator delete(void *, size_t) 함수는 C++11 placement new 함수 void * operator new(size_t, size_t) 해당하는 placement delete 연산자였습니다. C + + 14 크기 할당 취소를 사용 하는 경우이 delete 함수는 이제 일반적인 할당 취소 함수 (global delete 연산자)입니다. 표준에서는 배치 new  사용 해당 함수를 조회  delete  일반적인 할당 취소 함수를 찾으면 프로그램의 형식이 잘못 됩니다.

예를 들어 코드에서 placement new  placement delete  정의한다고 가정합니다.

C++복사

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

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

사용자가 정의한 배치 delete 연산자와 전역 크기 연산자 사이에 함수 서명이 일치 하기 때문에 문제가 발생 합니다 delete . size_t 배치 new  연산자에 대해 이외의 다른 형식을 사용할 있는지 여부를 고려 delete 합니다. 형식은 size_t typedef 컴파일러에 따라 다르며 typedef Visual C++의에 한입니다 unsigned int . 문제를 해결하려면 다음과 같은 열거된 형식을 사용하는 것이 좋습니다.

C++복사

  enum class my_type : size_t {};

그런 다음 배치의 정의를 변경  new  delete  유형을 대신 번째 인수로 사용 size_t 합니다. 형식 (: 사용  static_cast<my_type> 정수 값에서 변환) 전달 , 및의 정의를 업데이트  new delete 다시 정수 형식으로 캐스팅 하는 경우에는 placement new 호출도 업데이트 해야 합니다. 이를 위해를 사용할 필요는 없습니다enum 멤버를 포함 하는 클래스 형식 size_t  작동 합니다.

다른 솔루션은 placement new  함께 제거하는 것입니다. 코드에서 placement new  사용 배치 인수가 할당 되거나 삭제 되는 개체의 크기인 메모리 풀을 구현 하는 경우 크기가 지정 할당 해제 기능이 사용자 지정 메모리 코드를 대체 하는 적합할 있으며 배치 함수를 제거 배치 함수 대신 고유한 인수 연산자를 사용할 있습니다 delete .

코드를 바로 업데이트하지 않으려면 컴파일러 옵션 /Zc:sizedDealloc- 사용하여 이전 동작으로 되돌릴 있습니다. 옵션을 사용 하는 경우 인수 delete 함수가 존재 하지 않으며 placement delete 연산자와 충돌 하지 않습니다.

·        공용 구조체 데이터 멤버

공용 구조체의 데이터 멤버는 이상 참조 형식을 포함할 없습니다. 다음 코드는 Visual Studio 2013에서 성공적으로 컴파일되지만 Visual Studio 2015에서는 오류를 생성합니다.

C++복사

  union U1 {

      const int i;

  };

  union U2 {

     int &i;

  };

  union U3 {

      struct {int &i;};

  };

앞의 코드에서 발생하는 오류는 다음과 같습니다.

Output복사

  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

문제를 해결하려면 참조 형식을 포인터 또는 값으로 변경합니다. 형식을 포인터로 변경하려면 공용 구조체 필드를 사용하는 코드를 변경해야 합니다. 코드를 값으로 변경하면 공용 구조체에 저장된 데이터가 변경되며, union 형식의 필드는 같은 메모리를 공유하므로 변경이 다른 필드에 영향을 미칩니다. 크기에 따라 공용 구조체 크기도 변경할 있습니다.

·        익명 공용 구조체

이제 표준을 준수합니다. 이전 컴파일러 버전에서는 익명 공용 구조체에 대한 명시적 생성자 소멸자를 생성했습니다. 이러한 항목은 Visual Studio 2015에서 삭제됩니다.

C++복사

struct S {

    S();

};

 

union {

    struct {

       S s;

    };

} u; // C2280

앞의 코드는 Visual Studio 2015에서 다음 오류를 생성합니다.

C++복사

  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

문제를 해결하려면 생성자 /또는 소멸자의 정의를 제공하세요.

C++복사

  struct S {

     // Provide a default constructor by adding an empty function body.

     S() {}

  };

 

  union {

     struct {

        S s;

     };

  } u;

·        익명 구조체가 있는 공용 구조체

공용 구조체에서 익명 구조체 멤버의 런타임 동작이 표준을 준수하도록 변경되었습니다. 해당 공용 구조체가 생성될 공용 구조체의 익명 구조체 멤버에 대한 생성자가 이상 암시적으로 호출되지 않습니다. 또한 공용 구조체가 범위를 벗어날 공용 구조체의 익명 구조체 멤버에 대한 소멸자가 이상 암시적으로 호출되지 않습니다. 소멸자가 있는 명명된 구조체 S 멤버가 포함된 익명 구조체가 공용 구조체 U 들어 있는 다음 코드를 고려하세요.

C++복사

  #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에서 S 대한 생성자는 공용 구조체가 생성될 호출되고 S 대한 소멸자는 f 함수의 스택이 정리될 호출됩니다. 그러나 Visual Studio 2015에서는 생성자와 소멸자가 호출되지 않습니다. 컴파일러에서 동작 변경에 대해 경고를 표시합니다.

Output복사

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

원래 동작을 복원하려면 익명 구조체에 이름을 지정합니다. 익명이 아닌 구조체의 런타임 동작은 컴파일러 버전과 관계없이 동일합니다.

C++복사

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

  }

또는 생성자 소멸자 코드를 함수로 이동하고 공용 구조체에 대한 생성자 소멸자에서 이들 함수에 호출을 추가하세요.

C++복사

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

  }

·        템플릿 확인

템플릿의 이름 확인에 대한 변경 내용이 있습니다. C++에서 이름을 확인할 후보를 고려할 잠재적인 일치 항목으로 고려 중인 하나 이상의 이름에서 잘못된 템플릿 인스턴스화가 생성될 있습니다. 보통 이들 잘못된 인스턴스화 때문에 컴파일러 오류가 발생하지는 않습니다. 원칙을 SFINAE(Substitution Failure Is Not An Error)라고 합니다.

현재 SFINAE 따라 컴파일러가 클래스 템플릿의 특수화를 인스턴스화해야 하면 프로세스 중에 발생하는 오류는 컴파일러 오류입니다. 이전 버전에서는 컴파일러가 해당 오류를 무시합니다. 예를 들어, 다음 코드를 고려하세요.

C++복사

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

  }

현재 컴파일러로 컴파일할 경우 다음 오류가 발생합니다.

Output복사

  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' 클래스가 아직 정의되지 않았기 때문입니다.

경우 문제를 해결하려면 클래스가 정의될 때까지 이러한 형식 특성을 사용하지 마세요. B D 정의를 코드 파일의 시작 부분으로 이동하면 오류가 해결됩니다. 정의가 헤더 파일에 있으면 헤더 파일의 include 순서를 확인하여 문제가 있는 템플릿이 사용되기 전에 클래스 정의가 컴파일되는지 확인합니다.

·        복사 생성자

Visual Studio 2013 Visual Studio 2015에서 클래스에 사용자 정의 이동 생성자가 있지만 사용자 정의 복사 생성자가 없는 경우 컴파일러는 해당 클래스에 대한 복사 생성자를 생성합니다. Dev14에서는 생성된 복사 생성자가 "= delete" 표시됩니다.

Visual Studio 2015 업데이트 1 규칙 향상

·        개인 가상 기본 클래스 간접 상속

이전 버전의 컴파일러에서는 파생 클래스에서 간접적으로 파생된 private virtual 기본 클래스의 멤버 함수를 호출할 있었습니다. 이전 동작은 올바르지 않으며 C++ 표준을 따르지 않습니다. 컴파일러는 이러한 방식으로 작성된 코드를 이상 허용하지 않으며, 결과적으로 컴파일러 오류 C2280 발생합니다.

Output복사

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

예제(이전)

C++복사

  class base

  {

  protected:

      base();

      ~base();

  };

 

  class middle: private virtual base {};class top: public virtual middle {};

 

  void destroy(top *p)

  {

      delete p;  //

  }

예제(이후)

C++복사

  class base;  // as above

 

  class middle: protected virtual base {};

  class top: public virtual middle {};

 

  void destroy(top *p)

  {

      delete p;

  }

-또는-

C++복사

  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 delete

이전 버전의 컴파일러는 비멤버 operator new  비멤버 operator delete  정적으로 선언하고 글로벌 네임스페이스 이외의 네임스페이스에서 선언할 있었습니다. 이전 동작은 프로그램에서 new 프로그래머가 의도 또는 연산자 구현을 호출 하지 않아서 잘못 자동 런타임 동작이 발생 하는 위험을 생성 delete 했습니다. 컴파일러는 이러한 방식으로 작성된 코드를 이상 허용하지 않으며, 대신 컴파일러 오류 C2323 발생합니다.

Output복사

  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.

예제(이전)

C++복사

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

예제(이후)

C++복사

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

또한 컴파일러가 특정 진단을 제공 하지는 않지만, 인라인 operator new 잘못 형식으로 간주 됩니다.

·        비클래스 형식에서 'operator type()'(사용자 정의 변환) 호출 이전 버전의 컴파일러는 'operator type()' 자동으로 무시하면서 비클래스 형식에서 호출할 있었습니다. 이전 동작으로 잘못된 코드가 자동으로 생성되어 예기치 않은 런타임 동작이 발생하는 위험이 초래되었습니다. 컴파일러는 이러한 방식으로 작성된 코드를 이상 허용하지 않으며, 대신 컴파일러 오류 C2228 발생합니다.

Output복사

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

예제(이전)

C++복사

  typedef int index_t;

 

  void bounds_check(index_t index);

 

  void login(int column)

  {

      bounds_check(column.operator index_t());  // error C2228

  }

예제(이후)

C++복사

  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'

  }

·        상세 형식 지정자의 중복 typename 이전 버전의 컴파일러에서는 typename 상세 형식 지정자를 사용할 있습니다. 이러한 방식으로 작성 코드는 의미 체계가 잘못 되었습니다. 컴파일러는 이러한 방식으로 작성된 코드를 이상 허용하지 않으며, 대신 컴파일러 오류 C3406 발생합니다.

Output복사

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

예제(이전)

C++복사

  template <typename class T>

  class container;

예제(이후)

C++복사

  template <class T>  // alternatively, could be 'template <typename T>'; 'typename' is not elaborating a type specifier in this case

  class container;

·        이니셜라이저 목록에서 배열의 형식 추론 이전 버전의 컴파일러는 이니셜라이저 목록에서 배열의 형식 추론을 지원하지 않았습니다. 이제 컴파일러가 이러한 형태의 형식 추론을 지원합니다. 결과적으로 이니셜라이저 목록을 사용한 함수 템플릿 호출은 이제 모호하거나 이전 버전의 컴파일러와 다른 오버로드가 선택될 있습니다. 이러한 문제를 해결하려면 이제 프로그램에서 프로그래머가 의도한 오버로드를 명시적으로 지정해야 합니다.

새로운 동작으로 오버로드 확인에서 기록 후보와 똑같이 우수한 추가 후보를 고려하게 되는 경우, 호출이 모호해지며 결과적으로 컴파일러에서 컴파일러 오류 C2668 발생합니다.

Output복사

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

예제 1: 오버로드된 함수에 대한 호출이 모호합니다(이전).

C++복사

  // 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: 오버로드된 함수에 대한 호출이 모호합니다(이후).

C++복사

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

  }

새로운 동작으로 오버로드 확인에서 기록 후보보다 일치되는 추가 후보를 고려하게 되는 경우, 호출이 후보로 명확하게 확인되므로 프로그래머가 의도한 것과 다른 프로그램 동작 변경을 초래할 있습니다.

예제 2: 오버로드 확인의 변경(이전)

C++복사

  // 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: 오버로드 확인의 변경(이후)

C++복사

  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 경고의 복원

이전 버전의 컴파일러에서는 문과 관련 기존 경고를 제거 했습니다switch 이제 이러한 경고가 복원 되었습니다. 이제 컴파일러에서 복원된 경고가 발생합니다. 이제 특정 사례(기본 사례 포함) 관련된 경고가 switch 문의 마지막 대신, 잘못된 사례가 포함된 줄에서 발생합니다. 이제 과거와는 다른 줄에서 해당 경고가 발생하므로 이전에 #pragma warning(disable:####)  사용하면 표시되지 않았던 경고가 이상 의도한 대로 숨겨지지 않을 있습니다. 이러한 경고를 의도한 대로 표시하지 않으려면 #pragma warning(disable:####) 지시문을 잠재적으로 잘못된 번째 사례 위의 줄로 이동해야 있습니다. 다음은 복원된 경고입니다.

Output복사

  warning C4060: switch statement contains no 'case' or 'default' labels

Output복사

  warning C4061: enumerator 'bit1' in switch of enum 'flags' is not explicitly handled by a case label

Output복사

  warning C4062: enumerator 'bit1' in switch of enum 'flags' is not handled

Output복사

  warning C4063: case 'bit32' is not a valid value for switch of enum 'flags'

Output복사

  warning C4064: switch of incomplete enum 'flags'

Output복사

  warning C4065: switch statement contains 'default' but no 'case' labels

Output복사

  warning C4808: case 'value' is not a valid value for switch condition of type 'bool'

Output복사

  Warning C4809: switch statement has redundant 'default' label; all possible 'case' labels are given

C4063 예제(이전)

C++복사

  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 예제(이후)

C++복사

  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;

      }

  };

복원된 다른 경고의 예는 해당 설명서에 제공됩니다.

·        #include: 경로 이름에 부모 디렉터리 지정자 '..' 사용(/Wall /WX에만 영향을 )

이전 버전의 컴파일러에서는 #include 지시문의 경로 이름에서 부모 디렉터리 지정자('..') 사용을 검색하지 못했습니다. 이러한 방식으로 작성된 코드는 일반적으로 프로젝트 상대 경로를 부정확하게 사용하여 프로젝트의 외부에 존재하는 헤더를 포함합니다. 이전 동작은 프로그램이 프로그래머가 의도한 것과 다른 소스 파일을 포함하여 컴파일되거나 이러한 상대 경로가 다른 빌드 환경으로 이식되지 않는 위험을 초래했습니다. 이제 컴파일러는 이러한 방식으로 작성된 코드를 검색하여 프로그래머에게 알립니다. 그리고 사용하도록 설정된 경우 선택적으로 컴파일러 경고 C4464 발생합니다.

Output복사

  warning C4464: relative include path contains '..'

예제(이전)

C++복사

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

예제(이후)

C++복사

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

또한 컴파일러가 특정 진단을 제공하지는 않지만, 프로젝트의 Include 디렉터리를 지정하는 부모 디렉터리 지정자("..") 사용하지 않는 것이 좋습니다.

·        #pragma optimize()에서 헤더 파일의 끝을 넘어 확장(/Wall /WX에만 영향을 )

이전 버전의 컴파일러에서는 변환 단위 내에 포함된 헤더 파일을 이스케이프하는 최적화 플래그 설정에 대한 변경 내용을 검색하지 못했습니다. 이제 컴파일러는 이러한 방식으로 작성된 코드를 검색하여 프로그래머에게 알립니다. 그리고 사용하도록 설정된 경우 잘못된 #include 위치에서 선택적으로 컴파일러 경고 C4426 발생합니다. 경고는 변경 내용이 명령줄 인수에 의해 컴파일러에 설정된 최적화 플래그와 충돌하는 경우에만 발생합니다.

Output복사

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

예제(이전)

C++복사

  // C4426.h

  #pragma optimize("g", off)

  ...

  // C4426.h ends

 

  // C4426.cpp

  #include "C4426.h"  // warning C4426

예제(이후)

C++복사

  // 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에만 영향을 )

이전 버전의 컴파일러는 다른 소스 파일에서 #pragma warning(push) 상태 변경이 #pragma warning(pop) 상태 변경과 쌍을 이루는 (의도되는 경우가 드묾) 검색하지 못했습니다. 이전 동작으로 프로그램이 프로그래머가 의도한 것과 다르게 설정된 경고 집합으로 컴파일되어 잘못된 자동 런타임 동작이 발생하는 위험이 초래됩니다. 이제 컴파일러는 이러한 방식으로 작성된 코드를 검색하여 프로그래머에게 알립니다. 그리고 사용하도록 설정된 경우 일치하는 #pragma warning(pop) 위치에서 선택적으로 컴파일러 경고 C5031 발생합니다. 경고에는 해당 #pragma warning(push) 위치를 참조하는 참고가 포함되어 있습니다.

Output복사

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

예제(이전)

C++복사

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

  ...

예제(이후)

C++복사

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

  ...

드물긴 하지만 의도적으로 이러한 코드를 작성하는 경우가 있습니다. 이러한 방식으로 작성된 코드는 #include 순서의 변경에 민감합니다. 가능한 경우 소스 코드 파일에서 자동으로 포함된 방식으로 경고 상태를 관리하는 것이 좋습니다.

·        #pragma warning(push) 불일치(/Wall /WX에만 영향을 )

이전 버전의 컴파일러는 변환 단위의 끝에서 #pragma warning(push) 상태 변경 불일치를 검색하지 못했습니다. 이제 컴파일러는 이러한 방식으로 작성된 코드를 검색하여 프로그래머에게 알립니다. 그리고 사용하도록 설정된 경우 일치하지 않는 #pragma warning(push) 위치에서 선택적으로 컴파일러 경고 C5032 발생합니다. 경고는 변환 단위에 컴파일 오류가 없는 경우에만 발생합니다.

Output복사

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

예제(이전)

C++복사

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

예제(이후)

C++복사

  // 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 상태 추적의 결과로 추가 경고가 발생할 있습니다.

이전 버전의 컴파일러는 의도된 모든 경고를 발생시키기에는 불충분한 수준으로 #pragma warning 상태 변경을 추적했습니다. 동작으로 프로그래머가 의도한 것과 다른 상황에서 특정 경고가 효과적으로 표시되지 않는 위험이 초래됩니다. 이제 컴파일러는 #pragma warning 상태(특히 템플릿 내부의 #pragma warning 상태 변경과 관련된 내용) 더욱 강력하게 추적하며, 선택적으로 새로운 경고 C5031 C5032 발생합니다. 이러한 경고는 프로그래머가 #pragma warning(push)  #pragma warning(pop) 의도하지 않은 사용을 찾는 도움이 됩니다.

개선된 #pragma warning 상태 변경 추적의 결과로, 이전에 제대로 표시되지 않은 경고 또는 이전에 잘못 진단된 문제와 관련된 경고가 이제 발생할 있습니다.

·        접근할 없는 코드의 개선된 ID

C++ 표준 라이브러리의 변경 이전 버전의 컴파일러에 비해 향상된 인라인 함수 호출 기능을 통해 컴파일러가 이제 특정 코드에 접근할 없음을 증명할 있습니다. 새로운 동작으로 경고 C4720 인스턴스가 새로 그리고 더욱 자주 발생할 있습니다.

Output복사

  warning C4720: unreachable code

최적화 프로세스에서 많은 함수 호출을 인라인하거나 중복 코드를 제거하거나 특정 코드에 접근할 없는지 확인할 있도록 하므로, 경고는 대개 최적화를 사용하면서 컴파일할 경우에만 발생할 있습니다. 경고 C4720 인스턴스가 특히 std::find 사용과 관련하여 try/catch 블록에서 자주 발생했음을 관찰했습니다.

예제(이전)

C++복사

  try

  {

      auto iter = std::find(v.begin(), v.end(), 5);

  }

  catch(...)

  {

      do_something();  // ok

  }

예제(이후)

C++복사

  try

  {

      auto iter = std::find(v.begin(), v.end(), 5);

  }

  catch(...)

  {

      do_something();  // warning C4702: unreachable code

  }

·        pow(T, int)Unrolling 최적화 제거

이전 버전의 c + + 표준 라이브러리는 pow(T, int) pow 함수 호출을 일련의 곱셈 연산으로 하는 함수 템플릿을 정의 했습니다. 기법은 부동 소수점 작업의 특성으로 인해 많은 양의 부정확성을 초래 결과를 크게 부정확 만들 있습니다. Visual Studio 2015 업데이트 1에서 함수를 사용 하는 경우 의도 하지 않은 정확성을 방지 하기 위해이 동작이 제거 되었습니다 pow . 그러나이 버전의은 pow 올바른 계산 보다 훨씬 빠릅니다. 변경으로 인해 상당한 성능 재발이 발생 프로젝트에 정확한 부동 소수점 결과가 필요 하지 않은 경우 (: 프로젝트가 이미/fp: fast 컴파일되는 경우) 호출을이 해결 함수로 대체 하는 것이 좋습니다 pow .

C++복사

template <class T>

inline T pow_int(T x, int y) throw() {

     unsigned int n;

     if (y >= 0) {

         n = (unsigned int)(y);

     } else {

         n = (unsigned int)(-y);

     }

     for (T z = T(1); ; x *= x) {

         if ((n & 1) != 0) {

             z *= x;

         }

         if ((n >>= 1) == 0) {

             return (y < 0 ? T(1) / z : z);

         }

     }

}

구현은 이전 버전의 Visual Studio 포함 것과 동일 합니다.

Visual Studio 2015 업데이트 2 규칙 향상

·        SFINAE 식에 대한 부분 지원으로 인해 추가 경고 오류가 발생할 있습니다.

이전 버전의 컴파일러는 decltype SFINAE 식에 지원 부족으로 지정자 내의 특정 종류를 구문 분석 하지 않았습니다. 이전 동작은 올바르지 않으며 C++ 표준을 따르지 않습니다. 지속적인 규칙 향상으로 인해 이제 컴파일러는 이러한 식을 구문 분석하고 SFINAE 식에 대한 부분 지원을 합니다. 따라서 이제 컴파일러는 이전 버전의 컴파일러에서 구문 분석 하지 못한 식에서 발견 경고 오류를 발생 시킵니다.

새로운 동작이 decltype 아직 선언 되지 않은 형식을 포함 하는 식을 구문 분석 하는 경우 컴파일러는 C2039 컴파일러 오류를 발생 시킵니다.

Output복사

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

예제 1: 선언되지 않은 형식 사용(이전)

C++복사

  struct s1

  {

    template <typename T>

    auto f() -> decltype(s2<T>::type::f());  // error C2039

 

    template<typename>

    struct s2 {};

  }

예제 1(이후)

C++복사

  struct s1

  {

    template <typename>  // forward declare s2struct s2;

 

    template <typename T>

    auto f() -> decltype(s2<T>::type::f());

 

    template<typename>

    struct s2 {};

  }

동작에서 키워드를 decltype 사용 종속성 이름이 형식이 되도록 지정 하는 식을 구문 분석할 컴파일러는 컴파일러 typename 오류 C2923 함께 컴파일러 경고 C4346 발생 시킵니다.

Output복사

  warning C4346: 'S2<T>::Type': dependent name is not a type

Output복사

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

예제 2: 종속 이름이 형식이 아님(이전)

C++복사

  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(이후)

C++복사

  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 멤버 변수가 있는 클래스가 기본 복사/이동 생성자 기본 복사/이동 할당 연산자를 자동으로 생성 하도록 허용 했습니다. 이전 동작은 올바르지 않으며 C++ 표준을 따르지 않습니다. 이제 컴파일러는 volatile 멤버 변수가 있는 클래스는 특수한 생성자 대입 연산자가 있는 것으로 간주하여 이러한 연산자의 기본 구현이 자동으로 생성되는 것을 막습니다. 이러한 클래스가 공용 구조체(또는 클래스 내의 익명 공용 구조체) 멤버이면 공용 구조체(또는 익명 공용 구조체를 포함하는 클래스) 복사/이동 생성자 복사/이동 대입 연산자는 삭제된 것으로 암시적으로 정의됩니다. 명시적으로 정의하지 않고 공용 구조체(또는 익명 공용 구조체를 포함하는 클래스) 만들거나 복사하려 하면 오류가 발생하며 컴파일러에서 결과적으로 컴파일러 오류 C2280 발생합니다.

Output복사

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

예제(이전)

C++복사

  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

예제(이후)

C++복사

  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 한정자를 지원하지 않습니다.

이전 버전의 Visual C++ 2015 정적 멤버 함수에 cv 한정자가 포함되는 것을 허용했습니다. 동작은 Visual C++ 2015 Visual C++ 2015 업데이트 1에서의 문제 재발로 인한 것입니다. Visual C++ 2013 이전 버전의 Visual C++ 이런 식으로 작성된 코드를 거부합니다. Visual C++ 2015 Visual C++ 2015 업데이트 1 동작은 잘못되었으며 C++ 표준과 일치하지 않습니다. Visual Studio 2015 업데이트 2 이런 식으로 작성된 코드를 거부하며 대신 컴파일러 오류 C2511 발생합니다.

Output복사

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

예제(이전)

C++복사

  struct A

  {

    static void func();

  };

 

  void A::func() const {}  // C2511

예제(이후)

C++복사

  struct A

  {

    static void func();

  };

 

  void A::func() {}  // removed const

·        열거형의 정방향 선언은 WinRT 코드에서 허용되지 않습니다(/ZW에만 영향을 ).

Windows 런타임 (WinRT) 대해 컴파일된 코드는 enum 관리 되는 c + + 코드가 컴파일러 스위치를 사용 .Net Framework 대해 컴파일되는 경우와 마찬가지로 형식을 전방으로 선언할 없습니다 /clr . 동작은 열거형의 크기를 항상 있으며 WinRT 형식 시스템에 올바르게 프로젝션될 있음을 확인합니다. 컴파일러는 이러한 방식으로 작성된 코드를 거부하고 컴파일러 오류 C3197 함께 컴파일러 오류 C2599 발생합니다.

Output복사

  error C2599: 'CustomEnum': the forward declaration of a WinRT enum is not allowed

Output복사

  error C3197: 'public': can only be used in definitions

예제(이전)

C++복사

  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;

    }

  };

예제(이후)

C++복사

            // 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) 기본적으로 설정되어 있음).

이전 버전의 컴파일러는 멤버가 아닌 연산자 new  연산자 delete 함수가 인라인으로 선언될 경고를 발생하지 않습니다. 방식으로 작성된 코드는 형식이 잘못되었으며(진단이 필요하지 않음) 진단하기 힘들 있는 일치하지 않는 new delete 연산자로 인해 특히 크기가 지정된 할당 해제와 함께 사용 메모리 문제를 일으킬 있습니다. 이제 컴파일러는 이런 식으로 작성된 코드를 식별하기 위해 경고 C4595 발생합니다.

Output복사

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

예제(이전)

C++복사

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

  {

    ...

  }

예제(이후)

C++복사

  void* operator new(size_t sz)  // removed inline

  {

    ...

  }

이러한 방식으로 작성된 코드를 수정하려면 연산자 정의를 헤더 파일에서 해당하는 소스 파일로 이동해야 합니다.

Visual Studio 2015 업데이트 3 규칙 향상

·        std::is_convertable에서 자체 할당을 검색함(표준 라이브러리) 복사 생성자가 삭제되거나 private 경우 이전 버전의 std::is_convertable 형식 특성에서 class 형식의 자체 할당을 올바르게 검색하지 못했습니다. 이제 std::is_convertable<>::value  false 삭제 또는 전용 복사 생성자를 사용 클래스 형식에 적용 때로 올바르게 설정 됩니다.

변경과 관련된 컴파일러 진단은 없습니다.

예제

C++복사

  #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<>::value true 됩니다. 이제 std::is_convertable<>::value 이로 올바르게 설정 되어 false 정적 어설션이 실패 합니다.

·        기본값으로 설정되었거나 삭제된 trivial 복사 이동 생성자가 액세스 지정자를 따름

이전 버전의 컴파일러에서는 호출을 허용하기 전에 기본값으로 설정되었거나 삭제된 trivial 복사 이동 생성자의 액세스 지정자를 확인하지 않았습니다. 이전 동작은 올바르지 않으며 C++ 표준을 따르지 않습니다. 경우에 따라 이전 동작으로 잘못된 코드가 자동으로 생성되어 예기치 않은 런타임 동작이 발생하는 위험이 초래되었습니다. 이제 컴파일러에서 기본값으로 설정되었거나 삭제된 간단한 복사 이동 생성자의 액세스 지정자를 검사하여 호출 가능 여부를 확인하고, 호출할 없는 경우 결과로 컴파일러 경고 C2248 실행합니다.

Output복사

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

예제(이전)

C++복사

  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

  }

예제(이후)

C++복사

  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) 기본적으로 설정되어 있음)

이전 버전의 컴파일러에서는 특성 사용 ATL 코드를 지원했습니다Visual C++ 2008부터 시작 특성 사용 ATL 코드 지원 제거의 다음 단계로 특성 사용 ATL 코드가 이상 사용되지 않습니다. 이제 컴파일러에서 사용되지 않는 이러한 종류의 코드를 식별하기 위해 컴파일러 경고 C4467 실행합니다.

Output복사

  warning C4467: Usage of ATL attributes is deprecated

컴파일러에서 지원이 제거될 때까지 특성 사용 ATL 코드를 계속 사용하려는 경우 /Wv:18 또는 /wd4467 명령줄 인수를 컴파일러에 전달하거나 소스 코드에 #pragma warning(disable:4467) 추가하여 경고를 해제할 있습니다.

예제 1(이전)

C++복사

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

  class A {};

예제 1(이후)

C++복사

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

사용되지 않는 ATL 특성의 사용을 방지하기 위해 아래 예제 코드와 같이 IDL 파일을 만들 있습니다.

예제 2(이전)

C++복사

  [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 파일을 가져올 있습니다.

그런 다음 빌드에 MIDL 단계를 추가하여 C++ 인터페이스 정의가 생성되었는지 확인합니다.

예제 2 IDL(이후)

C++복사

  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 사용합니다.

예제 2 구현(이후)

C++복사

  #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에만 영향을 )

이전 버전의 컴파일러에서는 미리 컴파일된 헤더(PCH) 파일을 사용할  -Yc  -Yu 컴파일 간에 일치하지 않는 소스 파일의 #include 지시문을 허용했습니다. 이런 방식으로 작성된 코드는 컴파일러에서 이상 허용되지 않습니다. PCH 파일 사용 일치하지 않는 #include 지시문을 식별하기 위해 이제 컴파일러에서 컴파일러 경고 CC4598 실행합니다.

Output복사

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

예제(이전):

X.cpp(-Ycc.h)

C++복사

  #include "a.h"

  #include "b.h"

  #include "c.h"

Z.cpp(-Yuc.h)

C++복사

  #include "b.h"

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

  #include "c.h"

예제(이후)

X.cpp(-Ycc.h)

C++복사

  #include "a.h"

  #include "b.h"

  #include "c.h"

Z.cpp(-Yuc.h)

C++복사

  #include "a.h"

  #include "b.h" // matched order relative to X.cpp

  #include "c.h"

·        미리 컴파일된 헤더(PCH) 파일 일치하지 않는 include 디렉터리(/Wall /WX에만 영향을 )

이전 버전의 컴파일러에서는 미리 컴파일된 헤더(PCH) 파일을 사용할  -Yc  -Yu 컴파일 간에 일치하지 않는 컴파일러의 include 디렉터리(-I) 명령줄 인수를 허용했습니다. 이런 방식으로 작성된 코드는 컴파일러에서 이상 허용되지 않습니다. PCH 파일 사용 일치하지 않는 include 디렉터리(-I) 명령줄 인수를 식별하기 위해 이제 컴파일러에서 컴파일러 경고 CC4599 실행합니다.

Output복사

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

예제(이전)

ms-dos복사

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

  cl /c /Wall /Yuc.h Z.cpp

예제(이후)

ms-dos복사

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

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

Visual Studio 2013 새로운 C++ 기능

향상된 ISO C/C++ 표준 지원

컴파일러

MSVC 다음과 같은 ISO C++11 언어 기능을 지원합니다.

·        함수 템플릿의 기본 템플릿 인수

·        위임 생성자

·        명시적 변환 연산자

·        이니셜라이저 목록 균일 초기화

·        원시 문자열 리터럴

·        variadic 템플릿

·        별칭 템플릿

·        삭제된 함수

·        NSDMI(비정적 데이터 멤버 이니셜라이저)

·        기본값으로 설정된 함수 *

·        다음과 같은 ISO C99 언어 기능을 지원합니다.

·        _Bool

·        복합 리터럴

·        지정된 이니셜라이저

·        코드 혼합 선언

·        컴파일러 옵션 /Zc:strictStrings 사용하여 수정할 있는 값으로 문자열 리터럴 변환을 허용하지 않을 있습니다. C + + 98에서 문자열 리터럴과로의 변환 char* ( 와이드 문자열 리터럴은로 wchar_t* ) 사용 되지 않습니다. C++11에서 변환이 완전히 제거되었습니다. 컴파일러가 표준을 엄격하게 준수할 있지만 대신 사용자가 변환을 제어할 있도록 /Zc:strictStrings 옵션을 제공합니다. 기본적으로 옵션은 해제되어 있습니다. 디버그 모드에서 옵션을 사용하면 STL 컴파일되지 않습니다.

·        rvalue/lvalue 참조 캐스트. rvalue 참조를 사용하여 C++11 lvalue rvalue 명확하게 구별할 있습니다. 이전에는 컴파일러가 특정 캐스팅 시나리오에서 기능을 제공하지 않았습니다. 컴파일러 옵션인 /Zc:rvalueCast 추가되어 C++ Language Working Paper에서 컴파일러를 준수합니다(5.4단원, [expr.cast]/1 참조). 옵션이 지정되지 않은 경우 기본 동작은 Visual Studio 2012 동일합니다.

 참고

기본 설정된 함수의 경우 멤버 수준 이동 생성자 이동 대입 연산자를 요청하기 위한 =default 사용은 지원되지 않습니다.

C99 라이브러리

누락된 함수에 대한 선언과 구현이 math.h, ctype.h, wctype.h, stdio.h, stdlib.h wchar.h 헤더에 추가되었습니다. 또한 새로운 complex.h, stdbool.h, fenv.h inttypes.h 헤더가 추가되었고 모든 함수에 대한 구현이 여기에 선언되었습니다. 새로운 C++ 래퍼 헤더(ccomplex, cfenv, cinttypes, ctgmath) 있고, 다른 많은 헤더(ccomplex, cctype, clocale, cmath, cstdint, cstdio, cstring, cwchar cwctype) 업데이트되었습니다.

표준 템플릿 라이브러리

C++11 명시적 변환 연산자, 이니셜라이저 목록, 범위가 지정된 열거형 variadic 템플릿을 지원합니다. 이제 모든 컨테이너가 C++11 세부적인 요소 요구 사항을 지원합니다. 다음과 같은 C++14 기능을 지원합니다.

·        투명 연산자 구조 함수(less<>, greater<>, plus<>, multiplies<> )

·        make_unique<T>(args...) make_unique<T[]>(n)

·        cbegin()/cend(), rbegin()/rend(), crbegin()/crend() 비멤버 함수

·        <atomic> 다양 성능 향상을 받았습니다.

·        <type_traits> 주요 안정화 코드 수정을 받았습니다.

주요 변경 내용

이와 같이 향상된 ISO C/C++ 표준 지원 기능을 사용하려면 C++11 따르고 Visual Studio 2013 Visual C++에서 올바르게 컴파일되도록 기존 코드를 변경해야 있습니다.

Visual C++ 라이브러리 향상

·        C++ REST SDK 추가되었습니다. SDK에는 REST 서비스의 최신 C++ 구현이 포함되어 있습니다.

·        C++ AMP 질감 지원이 향상되었습니다. 이제 새로운 샘플링 모드를 지원합니다.

·        PPL 작업에서 여러 일정 관리 기술 비동기 디버깅을 지원합니다. API 사용하면 정상 결과 예외 조건 다에 대한 PPL 작업을 만들 있습니다.

C++ 애플리케이션 성능

·        자동 벡터화 도우미에서 많은 C++ 패턴을 인식하고 최적화하므로 코드를 빠르게 실행할 있습니다.

·        ARM 플랫폼 Atom 마이크로 아키텍처 코드 품질이 향상되었습니다.

·        __vectorcall 호출 규칙이 추가되었습니다. 백터 레지스터를 사용하는 __vectorcall 호출 규칙을 통해 벡터 형식 인수를 전달합니다.

·        링커 옵션이 제공됩니다/Gw(컴파일러)  /Gy(어셈블러) 스위치를 사용하면 링커 최적화에서 간결한 이진 파일을 생성할 있습니다.

·        C++ AMP 공유 메모리를 지원하여 CPU GPU 간의 데이터 복사를 줄이거나 제거합니다.

향상된 PGO(프로필 기반 최적화)

·        PGO 사용으로 최적화된 응용 프로그램 작업 집합의 감소로 인한 성능 향상

·        Windows 런타임 개발을 위한 새로운 PGO

Windows 런타임 개발 지원

·        구조체에서 boxed 형식 지원

이제와는 달리 null 있는 필드를 사용 형식을 정의할 있습니다 IBox<int>^ int . , 필드에 값을 포함 하거나와 같을 있습니다 nullptr .

·        다양한 예외 정보

C++/CX ABI(애플리케이션 이진 인터페이스)에서 자세한 예외 정보를 캡처하고 전파할 있도록 하는 새로운 Windows 오류 모델을 지원합니다. 여기에는 호출 스택과 사용자 지정 메시지 문자열이 포함됩니다.

·        가상 형식의 Object::ToString()

사용자 정의 Windows 런타임 ref 형식에서 ToString 재정의할 있습니다.

·        사용되지 않는 API 지원

공용 Windows 런타임 API 이제 사용되지 않는 것으로 표시되고 빌드 경고로 나타나는 사용자 지정 메시지가 제공될 있으며, 마이그레이션 지침을 제공할 있습니다.

·        향상 디버거.

네이티브/JavaScript interop 디버깅, Windows 런타임 예외 진단 비동기 코드 디버깅(Windows 런타임 PPL) 지원합니다.

 참고

섹션에서 설명한 C++ 관련 기능 향상된 기능 외에도, 향상된 다른 Visual Studio 기능을 사용하면 Windows 런타임 앱을 효과적으로 작성할 있습니다.

진단 향상

·        향상된 디버거. 비동기 디버깅 [ 코드만] 디버깅을 지원합니다.

·        코드 분석 범주. 이제 코드 분석기에서 분류된 출력을 보고 코드 결함을 찾아 수정할 있습니다.

·        XAML 진단. 이제 XAML에서 UI 응답성 배터리 사용 문제를 진단할 있습니다.

·        그래픽 GPU 디버깅 향상

·        원격 캡처 실제 디바이스에서의 재생

·        C++ AMP CPU 동시 디버깅

·        향상된 C++ AMP 런타임 진단

·        HLSL 컴퓨팅 셰이더 추적 디버깅

3차원 그래픽 향상

·        미리 곱한 알파 DDS 형식에 대한 이미지 콘텐츠 파이프라인 지원

·        이미지 편집기에서 렌더링을 위해 내부적으로 미리 곱한 알파를 사용하며, 이에 따라 짙은 후광과 같은 렌더링 아티팩트를 방지합니다.

·        이미지 모델 편집기. 이미지 편집기 모델 편집기의 셰이더 디자이너에서 사용자 정의 필터 만들기가 지원됩니다.

IDE 생산성

향상된 코드 서식 지정 C++ 코드에 보다 다양한 서식 설정을 적용할 있습니다. 이러한 설정을 사용하여 중괄호 키워드의 배치, 들여쓰기, 공백 바꿈을 제어할 있습니다. 문과 블록을 완료할 때와 파일에 코드를 붙여 넣을 코드의 서식이 자동으로 지정됩니다.

중괄호 완성 C++ 코드는 이제 다음 여는 문자에 해당하는 닫는 문자를 자동으로 완성합니다.

·        {(중괄호)

·        [(대괄호)

·        ((괄호)

·        '(작은따옴표)

·        "(큰따옴표)

추가 C++ 자동 완성 기능

·        클래스 형식에 세미콜론을 추가합니다.

·        원시 문자열 리터럴에 대한 괄호를 완성합니다.

·        여러 주석 (/ * /) 완료 합니다. *

모든 참조 찾기 에서 텍스트 일치 목록을 표시한 백그라운드에서 참조를 자동으로 확인하고 필터링합니다.

컨텍스트 기반 멤버 목록 필터링 액세스할 없는 멤버는 IntelliSense 멤버 목록에서 필터링됩니다. 예를 들어 형식을 구현하는 코드를 수정하지 않으면 개인 멤버는 멤버 목록에 표시되지 않습니다. 멤버 목록이 열려 있는 동안 ctrl + J  눌러 수준의 필터링을 제거할 있습니다 (현재 멤버 목록 창에만 적용 ). Ctrl + J  다시 눌러 텍스트 필터링을 제거 모든 멤버를 표시할 있습니다.

매개 변수 도움말 스크롤 매개 변수 도움말 도구 설명에 표시된 함수 시그니처는 임의의 시그니처를 표시하고 현재 컨텍스트에 따라 업데이트하는 것이 아니라 실제로 입력한 매개 변수의 수에 따라 변경됩니다. 매개 변수 도움말도 중첩된 함수에 표시될 올바르게 작동합니다.

헤더/코드 파일을 설정/해제 합니다. 이제 바로 가기 메뉴 또는 바로 가기 키의 명령을 사용하여 헤더와 해당 코드 파일 사이를 전환할 있습니다.

크기 조정 가능한 C++ 프로젝트 속성

C++/CX C++/CLI에서 이벤트 처리기 코드 자동 생성 C++/CX 또는 C++/CLI 코드 파일에 이벤트 처리기를 추가하는 코드를 입력하는 경우 편집기는 대리자 인스턴스와 이벤트 처리기 정의를 자동으로 생성할 있습니다. 도구 설명 창은 이벤트 처리기 코드를 자동으로 생성할 있을 나타납니다.

향상된 DPI 인식 이제 애플리케이션 매니페스트 파일의 DPI 인식 설정에서 "모니터 단위 높은 DPI 인식" 설정을 지원합니다.

빠른 구성 전환 대규모 애플리케이션에서 특히 후속 전환 작업과 같은 구성 전환이 훨씬 빠르게 실행됩니다.

빌드 시간 효율성 다양한 최적화 멀티 코어 활용으로 특히 대규모 프로젝트에서 빌드를 보다 빠르게 수행합니다. C++ WinMD 대한 참조가 있는 C++ 애플리케이션의 증분 빌드도 훨씬 빠릅니다.

Visual Studio 2012 새로운 C++ 기능

향상된 C++11 표준 지원

표준 템플릿 라이브러리

·        STL 헤더에 지원:,,,,,, <atomic> <chrono> <condition_variable> <filesystem> <future> <mutex> <ratio> <thread>

·        메모리 리소스 사용을 최적화하기 위해 컨테이너가 작아졌습니다. 예를 들어 기본 설정이 있는 x86 릴리스 모드에서 std::vector Visual Studio 2010 16바이트에서 Visual Studio 2012 12바이트로 축소되었으며std::map Visual Studio 2010 16바이트에서 Visual Studio 2012 8바이트로 축소되었습니다.

·        C++11 표준에서 허용되었지만 필요하지 않은 SCARY 반복기가 구현되었습니다.

기타 향상된 C++11 기능

·        범위 기반 for 루프. 배열, STL 컨테이너 Windows 런타임 컬렉션과 함께 작동하는 강력한 루프를 for (for-range-declaration : expression) 형식으로 작성할 있습니다. 핵심 언어 지원에 포함됩니다.

·        람다 도입자([]) 시작하고 로컬 변수를 갭처하지 않는 코드 블록인 상태 비저장 람다는 이제 C++11 표준에 필요한 함수 포인터로 암시적으로 변환됩니다.

·        범위가 지정된 열거형 지원 C++ enum class 열거형-키가 지원됩니다. 다음 코드에서는 열거형-키가 이전 열거형 동작과 다른 점을 보여 줍니다.

C++복사

enum class Element { Hydrogen, Helium, Lithium, Beryllium };

void func1(Element e);

func1(Hydrogen); // error C2065: 'Hydrogen' : undeclared identifier

func1(Element::Helium); // OK

Windows 런타임 개발 지원

·        네이티브 XAML 기반 UI 모델 Windows 런타임 앱의 경우 새로운 네이티브 XAML 기반 UI 모델을 사용할 있습니다.

·        구성 요소 확장을 Visual C++ 합니다. 이러한 확장은 Windows 런타임 앱의 필수 구성 요소인 Windows 런타임 개체의 사용을 간소화합니다. 자세한 내용은 C++  Visual C++ 언어 참조(C++/CX) 사용하는 Windows 런타임 앱에 대한 로드맵을 참조하세요.

·        DirectX 게임 Windows 런타임 앱에 대한 새로운 DirectX 지원을 사용하여 흥미로운 게임을 개발할 있습니다.

·        XAML/DirectX interop XAML DirectX 모두 사용하는 Windows 런타임 앱이 효율적으로 상호 운용됩니다.

·        Windows 런타임 구성 요소 DLL 개발 구성 요소 DLL 개발을 통해 Windows 런타임 환경을 확장할 있습니다.

컴파일러 링커

·        자동 벡터화 도우미 컴파일러는 코드에서 루프를 분석하고, 가능한 경우 모든 최신 프로세서에 있는 벡터 레지스터와 명령을 사용하는 명령을 내보냅니다. 이렇게 하면 루프가 빨리 실행됩니다. (스트리밍 SIMD 확장에 대한 프로세서 명령은 SSE 알려져 있습니다.) 최적화는 자동으로 적용되므로 사용하도록 설정하거나 요청할 필요가 없습니다.

·        자동 평행화 도우미 컴파일러는 코드에서 루프를 분석하고, 계산을 여러 코어 또는 프로세서에 분산시키는 명령을 내보냅니다. 이렇게 하면 루프가 빠르게 실행될 있습니다. 최적화는 기본적으로 사용하도록 설정되지 않으므로 요청해야 합니다. 대부분의 경우 코드에서 병렬화하려는 루프 바로 앞에 #pragma loop(hint_parallel(N)) 포함하는 것이 좋습니다.

·        자동 벡터화 도우미와 자동 평행화 도우미는 함께 작동하여 계산이 여러 코어에 분산되고 코어의 코드에서 벡터 레지스터를 사용합니다.

Visual Studio 2012 업데이트 1 새로운 기능

C++ 코드를 작성할 Windows XP 대상으로 지정합니다. Microsoft C++ 컴파일러 라이브러리를 사용하여 Windows XP Windows Server 2003 대상으로 지정할 있습니다.

병렬 프로그래밍 지원

C++ AMP(Accelerated Massive Parallelism)

C++ AMP 일반적으로 개별 그래픽 카드에서 GPU 존재하는 데이터 병렬 하드웨어를 활용하여 C++ 코드의 실행을 가속화합니다. C++ AMP 프로그래밍 모델에는 다차원 배열, 인덱싱, 메모리 전송, 바둑판식 배열 수학 함수 라이브러리가 포함됩니다. C++ AMP 언어 확장 컴파일러 제한을 사용하여 CPU에서 GPU 데이터를 이동하는 방법을 제어할 있습니다.

디버깅할. C++ AMP 사용하여 GPU 대상으로 하는 앱에 대한 디버깅 환경은 다른 C++ 앱의 디버깅과 같습니다. 여기에는 앞서 언급한 새로운 병렬 디버깅 추가 기능이 포함됩니다.

작성. C++ AMP 다른 Direct3D 기반 프로그래밍 모델을 기반으로 하는 GPU 작업에 대한 프로파일링 지원이 있습니다.

향상된 일반 병렬 프로그래밍

다중 코어 다중 코어 아키텍처로 이동하는 하드웨어를 사용하면 개발자는 이상 단일 코어에서 증가하는 클럭 속도를 맞출 없습니다. 개발자는 동시성 런타임의 병렬 프로그래밍 지원을 통해 이러한 아키텍처를 활용할 있습니다. Visual Studio 2010에는 정교한 데이터 흐름 파이프라인을 표현하여 동시성을 활용하는 기능과 함께 병렬 패턴 라이브러리와 같은 강력한 C++ 병렬 처리 라이브러리가 도입되었습니다. Visual Studio 2012에서 이러한 라이브러리는 개발자에게 가장 필요한 병렬 패턴에 대해 효율적인 성능, 많은 제어 다양한 지원을 제공하도록 확장되었습니다. 이제 제품에 포함된 기능은 다음과 같습니다.

·        비동기 연속성을 지원하는 풍부한 작업 기반 프로그래밍 모델

·        병렬 알고리즘은 분기 조인 병렬 처리(parallel_for, parallel_for with affinity, parallel_for_each, parallel_sort, parallel_reduce, parallel_transform) 지원합니다.

·        동시성 안전 컨테이너 - priority_queue, queue, vector map 같은 std 데이터 구조의 스레드 안전 버전을 제공합니다.

·        비동기 에이전트 라이브러리 - 개발자가 동시 단위로 자연스럽게 분해하는 데이터 흐름 파이프라인을 표현하는 사용할 있습니다.

·        목록에 있는 패턴의 원활한 구성을 용이하게 하는 사용자 지정 가능한 스케줄러 리소스 관리자

향상된 일반 병렬 디버깅

Visual Studio 2012에서는 병렬 태스크 창과 병렬 스택  외에도 새로운 병렬 조사식 창을 제공하여 모든 스레드와 프로세스에서 식의 값을 검사하고 결과를 정렬 필터링할 있습니다. 또한 사용자 고유의 시각화 도우미를 사용하여 창을 확장할 있으며, 모든 도구 창에서 새로운 다중 프로세스 지원을 활용할 있습니다.

IDE

Visual Studio 템플릿 지원 Visual Studio 템플릿 기술을 사용하여 C++ 프로젝트 항목 템플릿을 작성할 있습니다.

비동기 솔루션 로드 프로젝트는 비동기적으로 로드됩니다. , 솔루션의 주요 부분이 먼저 로드되어 작업을 빨리 시작할 있습니다.

원격 디버깅을 위한 자동화된 배포 Visual C++에서 원격 디버깅을 위한 파일 배포가 간소화되었습니다. 프로젝트 상황에 맞는 메뉴의 배포 옵션은 디버깅 구성 속성에 지정된 파일을 원격 컴퓨터에 자동으로 복사합니다. 이상 파일을 원격 컴퓨터에 수동으로 복사할 필요가 없습니다.

C++/CLI IntelliSense C++/CLI IntelliSense 완벽하게 지원합니다. 요약 정보, 매개 변수 도움말, 멤버 목록 자동 완성과 같은 IntelliSense 기능이 이제 C++/CLI에서 작동합니다. 또한 문서에 나오는 향상된 다른 IntelliSense IDE 기능도 C++/CLI에서 작동합니다.

다양한 IntelliSense 도구 설명 C++ IntelliSense 요약 정보 도구 설명에 다양한 XML 문서 주석 스타일 정보가 표시됩니다. XML 문서 주석이 있는 라이브러리의 API(: C++ AMP) 사용하는 경우 IntelliSense 도구 설명에 선언보다 많은 정보가 표시됩니다. 또한 코드에 XML 문서 주석이 있는 경우 IntelliSense 도구 설명에는 많은 정보가 표시됩니다.

C++ 코드 구문 switch, if-else, for 루프 다른 기본 코드 구문에 대한 구조 코드는 멤버 목록 드롭다운 목록에서 사용할 있습니다. 목록에서 코드 부분을 선택하여 코드에 삽입한 다음 필요한 논리를 입력합니다. 또한 편집기에서 사용할 사용자 고유의 사용자 지정 코드 조각을 만들 수도 있습니다.

향상된 멤버 목록 멤버 목록 드롭다운 목록은 코드 편집기에 코드를 입력할 자동으로 표시됩니다. 결과가 필터링되어 사용자가 입력하는 대로 관련 멤버만 표시됩니다. 멤버 목록에서 사용되는 필터링 논리의 종류는 텍스트 편집기, C/C++ > C/C++ > 고급 아래의 옵션 대화 상자에서 제어할 있습니다.

의미 체계 지정 형식, 열거형, 매크로 다른 C++ 토큰에 대한 색이 기본적으로 지정됩니다.

참조 강조 표시. 기호를 선택하면 현재 파일에서 기호의 모든 인스턴스가 강조 표시됩니다. + + + + 강조 표시 참조 간에 이동 하려면 ctrl shift 위쪽 화살표 또는 ctrl shift 아래쪽 화살표  누릅니다. 기능은 텍스트 편집기 > C/C++ > 고급 아래의 옵션 대화 상자에서 해제할 있습니다.

Application Lifecycle Management 도구

정적 코드 분석

C++ 대한 정적 분석은 다양한 오류 컨텍스트 정보, 많은 분석 규칙 나은 분석 결과를 제공하도록 업데이트되었습니다. 코드 분석 창에서 키워드, 프로젝트 심각도별로 메시지를 필터링할 있습니다. 창에서 메시지를 선택하면 코드 편집기에서 메시지가 트리거된 코드의 해당 줄이 강조 표시됩니다. 특정 C++ 경고의 경우 메시지에는 경고로 연결되는 실행 경로를 보여 주는 소스 줄이 나열됩니다. 의사 결정 지점 해당 특정 경로를 선택한 이유가 강조 표시됩니다. 코드 분석은 대부분의 Visual Studio 2012 버전에 포함되어 있습니다. Professional, Premium Ultimate 버전에는 모든 규칙이 포함되어 있습니다. Windows 8 Windows Phone Express 버전에는 가장 중요한 경고가 포함되어 있습니다. Web Express 버전에는 코드 분석이 포함되어 있지 않습니다. 다른 코드 분석에 대해 향상된 기능 가지는 다음과 같습니다.

·        새로운 동시성 경고를 사용하면 다중 스레드 C/C++ 프로그램에서 올바른 잠금 분야를 사용하고 있는지 확인하여 동시성 버그를 방지할 있습니다. 분석기에서 잠재적 경쟁 조건, 잠금 순서 반전, 호출자/호출 수신자 잠금 계약 위반, 일치 하지 않는 동기화 작업 기타 동시성 버그를 검색합니다.

·        규칙 집합을 사용하여 코드 분석 실행에 적용하려는 C++ 규칙을 지정할 있습니다.

·        코드 분석 창에서 선택한 경고를 표시하지 않는 pragma 소스 코드에 삽입할 있습니다.

·        버전의 Microsoft SAL(소스 코드 주석 언어) 사용하여 함수에서 매개 변수를 사용하는 방법, 해당 매개 변수에 적용되는 가정 함수가 완료될 해당 함수에서 수행하는 보장을 설명하여 정적 코드 분석의 정확성과 완성도를 높일 있습니다.

·        64비트 C++ 프로젝트를 지원합니다.

업데이트된 단위 테스트 프레임워크

Visual Studio에서 새로운 C++ 단위 테스트 프레임워크를 사용하여 C++ 단위 테스트를 작성합니다. 프로젝트 대화 상자의 Visual C++ 범주 아래에 C++ 단위 테스트 프로젝트 템플릿을 배치하여 기존 C++ 솔루션에 단위 테스트 프로젝트를 추가합니다. Unittest1.cpp 파일에 생성된 TEST_METHOD 코드 스텁에 단위 테스트를 작성합니다. 테스트 코드가 작성되면 솔루션을 빌드합니다. 테스트를 실행하려면 보기 > 다른  > 단위 테스트 탐색기 등을 선택하여 단위 테스트 탐색기 창을 다음, 원하는 테스트 사례에 대한 바로 가기 메뉴에서 선택한 테스트 실행  선택합니다. 테스트 실행이 완료되면 동일한 창에서 테스트 결과와 추가 스택 추적 정보를 있습니다.

아키텍처 종속성 그래프

코드를 이해하기 위해 솔루션의 이진 파일, 클래스, 네임스페이스 포함 파일에 대한 종속성 그래프를 생성할 있습니다. 메뉴 모음에서 아키텍처 > 생성 종속성 그래프  선택  솔루션 또는 포함 파일  종속성 그래프를 생성 합니다. 그래프 생성이 완료되면 노드를 펼치고, 노드 간을 이동하여 종속성 관계를 알아보고, 노드의 바로 가기 메뉴에서 콘텐츠 보기  선택하여 소스 코드를 탐색할 있습니다. 포함 파일에 종속성 그래프를 생성 하려면 * .cpp 소스 코드 파일 또는 .h 헤더 파일에 바로 가기 메뉴에서포함 파일의 그래프 생성  선택 합니다.

아키텍처 탐색기

아키텍처 탐색기  사용하여 C++ 솔루션, 프로젝트 또는 파일의 자산을 탐색할 있습니다. 메뉴 모음에서 아키텍처 > Windows > 아키텍처 탐색기  선택 합니다. 관심 있는 노드(클래스 ) 선택할 있습니다. 경우 도구 창의 오른쪽이 네임스페이스 목록으로 확장됩니다. 네임스페이스를 선택하면 네임스페이스의 클래스, 구조체 열거형 목록이 열에 표시됩니다. 이러한 자산을 계속 탐색하거나 왼쪽의 열로 돌아가서 다른 쿼리를 시작할 있습니다아키텍처 탐색기로 코드 찾기  참조하세요.

코드 검사

코드 검사에서 런타임에 이진 파일을 동적으로 계측하도록 업데이트되었습니다. 이렇게 하면 구성 오버헤드가 줄어들고 성능이 향상됩니다. 또한 C++ 앱에 대한 단위 테스트에서 코드 검사 데이터를 수집할 수도 있습니다. C++ 단위 테스트를 만들었으면 단위 테스트 탐색기  사용하여 솔루션의 테스트를 검색할 있습니다. 단위 테스트를 실행하고 테스트에 대한 코드 검사 데이터를 수집하려면 단위 테스트 탐색기 에서 코드 검사 분석  선택합니다. 메뉴 모음의 코드 검사 결과 창에서 코드 적용 결과를 검사하고테스트 >  > 코드 검사 결과  차례로 선택할 있습니다.

728x90
반응형

댓글