[c++] 더 이상 사용되지 않는 것으로 C ++ 표시

휴대용 C ++에서 더 이상 사용하지 않으려는 인터페이스에 메소드가 있습니다. 내가 이것을 구글 검색했을 때 내가 얻은 것은 마이크로 소프트 전용 솔루션이었다. 의 #pragma는 추천__declspec는 (사용되지 않음) .

두 번째 상 솔루션은 MSVC와 GCC 솔루션을 ifdef하는 것입니다.
감사



답변

C ++ 14에서는 [[deprecated]]속성 을 사용하여 함수가 더 이상 사용되지 않는 것으로 표시 할 수 있습니다 (섹션 7.6.5 [dcl.attr.deprecated] 참조).

속성 토큰은 deprecated 표시 이름과 그 사용을 계속 허용되는 개체에 사용할 수 있지만, 어떤 이유로 좋습니다.

예를 들어 다음 기능 foo은 더 이상 사용되지 않습니다.

[[deprecated]]
void foo(int);

이름 또는 엔티티가 더 이상 사용되지 않는 이유를 설명하는 메시지를 제공 할 수 있습니다.

[[deprecated("Replaced by bar, which has an improved interface")]]
void foo(int);

메시지는 문자열 리터럴이어야합니다.

자세한 내용은 “C ++ 14에서 더 이상 사용되지 않는 것으로 표시”를 참조하십시오 .


답변

트릭을 수행해야합니다.

#ifdef __GNUC__
#define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED(func) __declspec(deprecated) func
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED(func) func
#endif

...

//don't use me any more
DEPRECATED(void OldFunc(int a, float b));

//use me instead
void NewFunc(int a, double b);

그러나 함수 리턴 유형에 이름에 쉼표가있는 경우 문제점이 발생합니다. 예 std::pair<int, int>를 들어 선행 프로 시저가 2 개의 인수를 DEPRECATED 매크로에 전달하는 것으로 해석됩니다. 이 경우 반환 유형을 typedef해야합니다.

편집 : 더 간단하지만 호환성이 낮은 버전은 here .


답변

2008 답변 의 단순화 된 버전은 다음과 같습니다 .

#if defined(__GNUC__) || defined(__clang__)
#define DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED __declspec(deprecated)
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED
#endif

//...

//don't use me any more
DEPRECATED void OldFunc(int a, float b);

//use me instead
void NewFunc(int a, double b);

또한보십시오:


답변

GCC에서는 다음과 같이 더 이상 사용되지 않는 속성으로 함수를 선언 할 수 있습니다.

void myfunc() __attribute__ ((deprecated));

이 함수가 .c 파일에서 사용될 때 컴파일 타임 경고가 트리거됩니다.

http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html의 “진단 pragmas”에서 자세한 정보를 찾을 수 있습니다.


답변

2018 년에 대한 더 완벽한 답변입니다.

요즘에는 많은 도구를 사용하여 무언가를 더 이상 사용되지 않는 것으로 표시 할뿐만 아니라 메시지를 제공 할 수 있습니다. 이를 통해 사람들에게 더 이상 사용되지 않는시기를 알려주고 교체를 지시 할 수 있습니다.

여전히 많은 컴파일러 지원이 있습니다 :

  • C ++ 14는 [[deprecated]]/를 지원합니다 [[deprecated(message)]].
  • __attribute__((deprecated)) GCC 4.0 이상 및 ARM 4.1 이상에서 지원
  • __attribute__((deprecated))다음을 __attribute__((deprecated(message)))지원합니다 :
    • GCC 4.5+
    • GCC 4.5+로 가장 한 여러 컴파일러 ( __GNUC__/ __GNUC_MINOR__/ 설정 __GNUC_PATCHLEVEL__)
    • Intel C / C ++ Compiler는 16 이상으로 돌아갑니다 (신뢰할 수는 없습니다 __GNUC__/ __GNUC_MINOR__설치된 GCC 버전으로 설정하십시오)
    • ARM 5.6 이상
  • MSVC는 __declspec(deprecated)13.10부터 지원 (Visual Studio 2003)
  • __declspec(deprecated(message))14.0 이후 MSVC 지원 (Visual Studio 2005)

[[gnu::deprecated]]C ++ 11의 최신 버전의 clang을 기반으로 사용할 수도 있습니다 __has_cpp_attribute(gnu::deprecated).

Hedley 에는 자동 으로이 모든 것을 자동으로 처리 하는 매크로가 있지만 현재 버전 (v2)은 다음과 같습니다.

#if defined(__cplusplus) && (__cplusplus >= 201402L)
#  define HEDLEY_DEPRECATED(since) [[deprecated("Since " #since)]]
#  define HEDLEY_DEPRECATED_FOR(since, replacement) [[deprecated("Since " #since "; use " #replacement)]]
#elif \
  HEDLEY_GCC_HAS_EXTENSION(attribute_deprecated_with_message,4,5,0) || \
  HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
  HEDLEY_ARM_VERSION_CHECK(5,6,0)
#  define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
#  define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
#elif \
  HEDLEY_GCC_HAS_ATTRIBUTE(deprcated,4,0,0) || \
  HEDLEY_ARM_VERSION_CHECK(4,1,0)
#  define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
#  define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
#elif HEDLEY_MSVC_VERSION_CHECK(14,0,0)
#  define HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
#  define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0)
#  define HEDLEY_DEPRECATED(since) _declspec(deprecated)
#  define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
#else
#  define HEDLEY_DEPRECATED(since)
#  define HEDLEY_DEPRECATED_FOR(since, replacement)
#endif

Hedley를 사용하지 않으려면 매크로 *_VERSION_CHECK*_HAS_ATTRIBUTE매크로를 제거하는 방법을 연습으로 남겨 두겠습니다 (Hedley를 크게 썼으므로 정기적으로 그것에 대해 생각할 필요가 없습니다).

GLib을 사용하는 경우 G_DEPRECATEDG_DEPRECATED_FOR매크로를 사용할 수 있습니다 . Hedley의 것만 큼 강력하지는 않지만 이미 GLib을 사용하고 있다면 추가 할 것이 없습니다.


답변

이식 가능한 프로젝트를 다루는 경우 어느 시점에서 다양한 플랫폼에 대한 사전 처리 된 대안 섹션이 필요하다는 것은 거의 불가피합니다. #ifdef this #ifdef 등등.

이러한 섹션에서 심볼을 더 이상 사용하지 않는 방법을 조건부로 정의 할 수 있습니다. 대부분의 툴체인은 사용자 정의 컴파일러 경고를 지원하므로 일반적으로 “경고”매크로를 정의하는 것이 좋습니다. 그런 다음 더 이상 사용되지 않는 특정 경고 매크로를 사용할 수 있습니다. 전용 지원 중단 방법을 지원하는 플랫폼의 경우 경고 대신 사용할 수 있습니다.


답변

Intel Compiler v19.0의 경우 다음을 __INTEL_COMPILER평가할 때 이것을 사용하십시오 1900.

#  if defined(__INTEL_COMPILER)
#    define DEPRECATED [[deprecated]]
#  endif

다음 언어 수준에서 작동합니다.

  • C ++ 17 지원 (/ Qstd = c ++ 17)
  • C ++ 14 지원 (/ Qstd = c ++ 14)
  • C ++ 11 지원 (/ Qstd = c ++ 11)
  • C11 지원 (/ Qstd = c11)
  • C99 지원 (/ Qstd = c99)

인텔 컴파일러에는 [[deprecated]]다른 모든 컴파일러가 수행하는 특정 언어 요소 의 속성을 지원하지 않는다는 점에서 버그 가 있습니다. 예를 들어 Intel Compiler v19.0을 사용하여 GitHub에있는 {fmtlib / fmt} 라이브러리의 v6.0.0을 컴파일하십시오. 고장날 것입니다. 그런 다음 GitHub 커밋수정 사항을 참조하십시오 .