C ++ का पदावनत चिह्न


147

मेरे पास एक इंटरफ़ेस में एक विधि है जिसे मैं पोर्टेबल सी ++ के साथ चित्रित करना चाहता हूं। जब मैंने इस सब के लिए Googled मुझे मिला एक Microsoft विशिष्ट समाधान था; #pragma पदावनत और __declspec (पदावनत)

एक दूसरा पुरस्कार समाधान एक MSVC और एक GCC समाधान ifdef होगा।
धन्यवाद

जवाबों:


193

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 में चिह्नित के रूप में चिह्नित करें" देखें ।


क्या आप एक मैक्रो में [[पदावनत]] का उपयोग कर सकते हैं?
डेनियल रयान

2
@ ज़म्बी आपको सक्षम होना चाहिए, क्योंकि संकलन से पहले मैक्रो प्रीप्रोसेसर द्वारा नियंत्रित किया जाता है। [[पदावनत]] दिखाई देना चाहिए (और संकलक आउटपुट संबंधित चेतावनियों को) जहां मैक्रो का मूल्यांकन किया जाता है।
फ्लोरियन कैस्टेलन

129

यह काम कर जाना चाहिए:

#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>कि यह प्रीप्रोसेसर द्वारा व्याख्या किया जाएगा क्योंकि DEPRECated मैक्रो के लिए 2 तर्क पारित करेगा। उस स्थिति में आपको रिटर्न टाइप लिखना होगा।

संपादित करें: सरल (लेकिन संभवतः कम व्यापक रूप से संगत) संस्करण यहां


6
# फेर के बजाय, यह बेहतर होगा कि #define DEPRECATED (फंक) फंक
CesarB

1
mxp: डिप्रेसेशन केवल एक चेतावनी है, और इसलिए मैं कहूंगा कि यह चेतावनी कि यह समर्थित नहीं है आप सभी की जरूरत है।
लियोन टिम्मरमैन

1
हां, मैं "#warning के लिए जाऊंगा। आपको इस कंपाइलर के लिए DEPRECATED" लागू करना होगा। यदि यह असंभव है, तो पोर्टर #define DEPRECATED (FUNC) FUNC कर सकता है, और इसके बिना रह सकता है।
16:17 पर स्टीव जेसोप

2
दुर्भाग्य से C ++ में संकलित चेतावनी को आउटपुट करने का कोई मानक तरीका नहीं है: P #pragma संदेश को करना होगा।
माइकल प्लेटिंग्स

3
gcc की विशेषता वाक्यविन्यास विशेषता को उसी स्थान पर रखने की अनुमति देती है __declspec(deprecated), जिससे मैक्रो को सरल बनाया जा सके।
bames53

57

यहाँ मेरे 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);

यह सभी देखें:


17
आप [[deprecate]]अपने अपदस्थ मैक्रोज़ कैसे हैं ? :-)
ग्रैहम.ड्रेड्स

3
मैं उन दो उत्तरों के बीच कोई महत्वपूर्ण अंतर नहीं देख सकता। आपने इसे दूसरी बार क्यों पोस्ट किया?
टॉम ज़ातो -

4
आपको इसे फंक्शन के चारों ओर लपेटना नहीं है, इसलिए इसके DEPRECATED void foo(...);बजायDEPRECATED(void foo(...));
dshepherd

12
आपको एक नया पोस्ट करने के बजाय अपने 2008 के उत्तर को संपादित करना चाहिए।
याकॉव गल्का

4
यह मेरे अन्य उत्तर के समान व्यापक रूप से संगत नहीं हो सकता है, इसलिए मैंने इसे अलग से जोड़ा है।
माइकल प्लेटिंग्स

22

GCC में आप अपने कार्य को इस तरह दर्शाए गए विशेषता के साथ घोषित कर सकते हैं:

void myfunc() __attribute__ ((deprecated));

जब वह फ़ंक्शन .c फ़ाइल में उपयोग किया जाता है, तो यह संकलन-समय चेतावनी को ट्रिगर करेगा।

आप http://gcc.gnu.org/onbuildocs/gcc/Prag.html पर "डायग्नोस्टिक प्रैग्मस" के तहत अधिक जानकारी प्राप्त कर सकते हैं


8

यहां 2018 के लिए अधिक पूर्ण उत्तर दिया गया है।

इन दिनों, बहुत सारे उपकरण आपको न केवल कुछ के रूप में चिह्नित करने की अनुमति देते हैं, बल्कि एक संदेश भी प्रदान करते हैं। यह आपको लोगों को यह बताने की अनुमति देता है कि कब कुछ निकाला गया था, और शायद उन्हें बदलने की ओर इशारा करें।

कंपाइलर समर्थन में अभी भी बहुत विविधता है:

  • C ++ 14 समर्थन [[deprecated]]/ [[deprecated(message)]]
  • __attribute__((deprecated)) GCC 4.0+ और ARM 4.1+ द्वारा समर्थित है
  • __attribute__((deprecated))और इसके __attribute__((deprecated(message)))लिए समर्थित है:
    • जीसीसी 4.5+
    • कई संकलक जो जीसीसी 4.5+ (सेटिंग __GNUC__/ __GNUC_MINOR__/ द्वारा __GNUC_PATCHLEVEL__) के रूप में सामने आते हैं
    • Intel C / C ++ कंपाइलर कम से कम 16 पर वापस जा रहा है (आप विश्वास नहीं कर सकते __GNUC__/ __GNUC_MINOR__, वे बस इसे सेट करते हैं जो भी जीसीसी का संस्करण स्थापित है)
    • एआरएम 5.6+
  • MS.10 __declspec(deprecated)13.10 से समर्थन करता है (विजुअल स्टूडियो 2003)
  • MSVC __declspec(deprecated(message))14.0 के बाद से समर्थन करता है (विजुअल स्टूडियो 2005)

आप [[gnu::deprecated]]C ++ 11 के हाल के संस्करणों में, इसके आधार पर भी उपयोग कर सकते हैं __has_cpp_attribute(gnu::deprecated)

मैं में कुछ मैक्रो हेडली जो मैं नवीनतम जानकारी रखना है, लेकिन स्वचालित रूप से यह सब संभाल करने वर्तमान संस्करण (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

मैं इसे एक अभ्यास के रूप में छोड़ दूंगा कि कैसे *_VERSION_CHECKऔर *_HAS_ATTRIBUTEमैक्रोज़ से छुटकारा पाएं यदि आप हडले का उपयोग नहीं करना चाहते हैं (मैंने हडले को बड़े पैमाने पर लिखा है तो मुझे नियमित रूप से इसके बारे में नहीं सोचना होगा)।

यदि आप GLib का उपयोग करते हैं, तो आप G_DEPRECATEDऔर G_DEPRECATED_FORmacros का उपयोग कर सकते हैं । वे हेडली से उतने मजबूत नहीं हैं, लेकिन अगर आप पहले से ही GLib का उपयोग करते हैं तो जोड़ने के लिए कुछ भी नहीं है।


4

पोर्टेबल परियोजनाओं से निपटना लगभग अपरिहार्य है कि आपको कुछ बिंदु पर प्लेटफार्मों की एक श्रृंखला के लिए प्रीप्रोसेस किए गए विकल्पों के अनुभाग की आवश्यकता होती है। #ifdef ये #ifdef वो वगैरह।

इस तरह के एक खंड में आप बहुत अच्छी तरह से प्रतीकों को चित्रित करने का एक तरीका निर्धारित कर सकते हैं। मेरी प्राथमिकता आमतौर पर "चेतावनी" मैक्रो को परिभाषित करना है क्योंकि अधिकांश टूलचाइन्स कस्टम कंपाइलर चेतावनी का समर्थन करते हैं। फिर आप डिप्रेसेशन आदि के लिए एक विशिष्ट चेतावनी मैक्रो के साथ जा सकते हैं। समर्पित डिप्रेसेशन विधियों का समर्थन करने वाले प्लेटफार्मों के लिए आप चेतावनी के बजाय इसका उपयोग कर सकते हैं।


1

इंटेल कंपाइलर 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]]कुछ भाषा तत्वों पर विशेषता का समर्थन नहीं करता है जो अन्य सभी कंपाइलर करते हैं। एक उदाहरण के लिए, इंटेल कंपाइलर v19.0 के साथ GitHub पर (उल्लेखनीय रूप से शानदार) {fmtlib / fmt} लाइब्रेरी का v6.0.0 संकलन करें। यह टूट जाएगा। फिर GitHub कमिट में फिक्स देखें ।


यह गलत है; C ++ विशेषताएँ ICC पर C मोड में काम नहीं करती हैं। उदाहरण है__attribute__((deprecated)), OTOH, C और C ++ में काम करता है, कम से कम ICC 13.0 पर वापस जाता है, शायद बहुत आगे (इंटेल इस प्रकार के सामान का दस्तावेजीकरण नहीं करता है ताकि मुझे यकीन न हो)।
19 फरवरी को nemequ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.