Kullanımdan kaldırıldı olarak C ++ işareti


Yanıtlar:


197

C ++ 14'te, [[deprecated]]özniteliği kullanarak bir işlevi kullanımdan kaldırılmış olarak işaretleyebilirsiniz (bkz. Bölüm 7.6.5 [dcl.attr.deprecated]).

Nitelik belirteci deprecated işareti adları ve kimin kullanımı hala izin verilir kuruluşlar için kullanılabilir, ama nedense önerilmez.

Örneğin, aşağıdaki işlev fookullanımdan kaldırılmıştır:

[[deprecated]]
void foo(int);

Adın veya varlığın neden kullanımdan kaldırıldığını açıklayan bir mesaj sağlamak mümkündür:

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

Mesaj bir dizge olmalıdır.

Daha fazla ayrıntı için bkz. "C ++ 14'te kullanımdan kaldırıldı olarak işaretleme" .


Bir makroda [[kullanımdan kaldırıldı]] kullanabilir misiniz?
Daniel Ryan

2
@Zammbi Makroyu derlemeden önce önişlemci tarafından işlendiği için yapabilmelisiniz. Makronun değerlendirildiği yerde [[kullanımdan kaldırıldı]] görünmeli (ve derleyicinin ilgili uyarıları vermesine izin vermelidir).
Florian Castellane

130

Bu hile yapmalı:

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

Bununla birlikte, bir işlev dönüş türünün adında virgül varsa sorunlarla karşılaşırsınız, örneğin std::pair<int, int>bu, önişleyici tarafından DEPRECATED makroya 2 bağımsız değişken geçirdiği şeklinde yorumlanacaktır. Bu durumda dönüş türünü yazmanız gerekir.

Düzenleme: daha basit (ancak muhtemelen daha az uyumlu) versiyon burada .


6
#Error

1
mxp: Kullanımdan kaldırma yalnızca bir uyarıdır ve bu nedenle, ihtiyacınız olan tek şeyin desteklenmediğini belirten bir uyarı olduğunu söyleyebilirim.
Leon Timmermans

1
Evet, "#warning Bu derleyici için KULLANIMDAN KALDIRILMIŞTIR uygulamanız gerekir" veya benzeri bir şey için giderdim. Eğer bu imkansızsa, kapıcı # KULLANIMDAN KALDIRILMIŞ (FUNC) FUNC tanımlayabilir ve onsuz yaşayabilir.
Steve Jessop

2
Ne yazık ki, C ++ 'da bir derleme uyarısı vermenin standart bir yolu yoktur: P #pragma mesajının yapılması gerekecek.
Michael Platings

3
gcc'nin öznitelik sözdizimi, özniteliğin __declspec(deprecated)şimdiki ile aynı yerlerde olmasını sağlar , böylece makro basitleştirilebilir.
bames53

59

İşte 2008 cevabımın basitleştirilmiş bir versiyonu :

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

Ayrıca bakınız:


17
Kullanımdan [[deprecate]]kaldırılan makrolarınız nasıl ? :-)
graham.reeds

3
Bu iki cevap arasında önemli bir fark göremiyorum. Neden ikinci kez gönderdin?
Tomáš Zato - Monica'yı eski durumuna getir

4
İşlevin etrafına sarmak zorunda değilsiniz, bu yüzden DEPRECATED void foo(...);yerineDEPRECATED(void foo(...));
dsh Shepherd

12
2008 cevabınızı yenisini göndermek yerine düzenlemelisiniz.
Yakov Galka

4
Bu, diğer cevabım kadar geniş çapta uyumlu olmayabilir, dolayısıyla bunu ayrı ayrı ekledim.
Michael Platings

23

GCC'de, işlevinizi kullanımdan kaldırılan özniteliğiyle şu şekilde bildirebilirsiniz:

void myfunc() __attribute__ ((deprecated));

Bu işlev bir .c dosyasında kullanıldığında bir derleme zamanı uyarısını tetikleyecektir.

Http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html adresindeki "Teşhis pragmaları" altında daha fazla bilgi bulabilirsiniz.


8

İşte 2018 için daha eksiksiz bir cevap.

Bugünlerde pek çok araç, bir şeyi sadece kullanımdan kaldırıldı olarak işaretlemenize değil, aynı zamanda bir mesaj vermenize de izin veriyor. Bu, insanlara bir şeyin ne zaman kullanımdan kaldırıldığını söylemenize ve belki onları değiştirmeye yönlendirmenize olanak tanır.

Derleyici desteğinde hala çok fazla çeşitlilik var:

  • C ++ 14, [[deprecated]]/ [[deprecated(message)]].
  • __attribute__((deprecated)) GCC 4.0+ ve ARM 4.1+ tarafından desteklenmektedir
  • __attribute__((deprecated))ve __attribute__((deprecated(message)))şunlar için desteklenir:
    • GCC 4.5+
    • GCC 4.5+ gibi görünen birkaç derleyici ( __GNUC__/ __GNUC_MINOR__/ ayarlayarak __GNUC_PATCHLEVEL__)
    • En az 16'ya geri dönen Intel C / C ++ Derleyici (güvenemezsiniz __GNUC__/ __GNUC_MINOR__, sadece GCC'nin hangi sürümünün yüklü olduğunu ayarlarlar)
    • ARM 5.6+
  • MSVC, 13.10'dan __declspec(deprecated)beri desteklemektedir (Visual Studio 2003)
  • MSVC, 14.0'dan __declspec(deprecated(message))beri desteklemektedir (Visual Studio 2005)

Ayrıca [[gnu::deprecated]]clang'ın son sürümlerinde C ++ 11'de __has_cpp_attribute(gnu::deprecated).

Hedley'de tüm bunları otomatik olarak işlemek için güncel tuttuğum bazı makrolarım var , ancak mevcut sürüm (v2) şöyle görünüyor:

#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'i kullanmak istemiyorsanız , *_VERSION_CHECKve *_HAS_ATTRIBUTEmakrolardan nasıl kurtulacağınızı anlamak için bir egzersiz olarak bırakacağım (büyük ölçüde Hedley'i yazdım, böylece bunu düzenli olarak düşünmek zorunda kalmayayım).

GLib kullanıyorsanız, G_DEPRECATEDve G_DEPRECATED_FORmakrolarını kullanabilirsiniz . Hedley'den olanlar kadar sağlam değiller, ancak GLib'i zaten kullanıyorsanız ekleyecek hiçbir şey yok.


4

Taşınabilir projelerle uğraşmak, bir noktada çeşitli platformlar için önceden işlenmiş alternatifler bölümüne ihtiyaç duymanız neredeyse kaçınılmazdır. #ifdef bu #ifdef şunun gibi.

Böyle bir bölümde sembolleri kullanımdan kaldırmanın bir yolunu koşullu olarak çok iyi tanımlayabilirsiniz. Çoğu araç zinciri özel derleyici uyarılarını desteklediğinden, tercihim genellikle bir "uyarı" makrosu tanımlamaktır. Daha sonra, kullanımdan kaldırma vb. İçin belirli bir uyarı makrosuyla devam edebilirsiniz. Tahsis edilmiş kullanımdan kaldırma yöntemlerini destekleyen platformlar için, uyarılar yerine bunu kullanabilirsiniz.


1

Intel Compiler v19.0 için şunu __INTEL_COMPILERdeğerlendirirken bunu kullanın 1900:

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

Aşağıdaki dil seviyeleri için çalışır:

  • C ++ 17 Desteği (/ Qstd = c ++ 17)
  • C ++ 14 Desteği (/ Qstd = c ++ 14)
  • C ++ 11 Desteği (/ Qstd = c ++ 11)
  • C11 Desteği (/ Qstd = c11)
  • C99 Desteği (/ Qstd = c99)

Intel Derleyici, [[deprecated]]diğer tüm derleyicilerin yaptığı belirli dil öğelerinin özniteliğini desteklememesi nedeniyle bir hata gibi görünen bir şeye sahiptir . Bir örnek için, GitHub'da (son derece süper) {fmtlib / fmt} kitaplığının v6.0.0'ını Intel Compiler v19.0 ile derleyin. Kırılacak. Ardından GitHub kaydındaki düzeltmeye bakın .


Bu yanlış; C ++ öznitelikleri, ICC'de C modunda çalışmaz. Örnek . __attribute__((deprecated)), OTOH, en azından ICC 13.0'a geri giderek C ve C ++ 'da çalışıyor, muhtemelen çok daha ileri (Intel bu tür şeyleri belgelememe eğiliminde olduğundan emin olamıyorum).
nemequ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.