অবহিত হিসাবে সি ++ চিহ্ন


147

আমার একটি ইন্টারফেসে এমন একটি পদ্ধতি রয়েছে যা আমি পোর্টেবল সি ++ দিয়ে ছাড়তে চাই। আমি যখন এটির জন্য গুগল করেছি তখন আমার কাছে মাইক্রোসফ্টের নির্দিষ্ট সমাধান ছিল; #pragma অবচয় এবং __declspec (হ্রাস করা)

দ্বিতীয় পুরষ্কার সমাধান হ'ল ifdef একটি এমএসভিসি এবং একটি জিসিসি সমাধান।
ধন্যবাদ

উত্তর:


193

সি ++ ১৪ এ, আপনি [[deprecated]]অ্যাট্রিবিউটটি ব্যবহার করে অবহেলিত হিসাবে কোনও ফাংশন চিহ্নিত করতে পারেন (বিভাগ 7.6.5 [dcl.attr.drecated] দেখুন)।

অ্যাট্রিবিউট-টোকেন deprecated চিহ্ন নাম এবং সত্ত্বা যার ব্যবহার এখনও অনুমতি দেওয়া হয় ব্যবহার করা যেতে পারে, কিন্তু কোনো কারণে নিরুৎসাহিত করা হয়।

উদাহরণস্বরূপ, নিম্নলিখিত ফাংশনটি fooঅবচয় করা হয়েছে:

[[deprecated]]
void foo(int);

নাম বা সত্তাকে কেন অবচিত করা হয়েছিল তা বর্ণনা করে এমন কোনও বার্তা সরবরাহ করা সম্ভব:

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

বার্তাটি অবশ্যই একটি স্ট্রিং আক্ষরিক হওয়া উচিত।

আরও বিশদের জন্য, "সি ++ 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>হবেন যেমন প্রিপ্রোসেসর দ্বারা এটি ব্যাখ্যা করা হবে মীমাংসিত ম্যাক্রোতে 2 টি আর্গুমেন্ট পাস করার কারণে। সেক্ষেত্রে আপনাকে রিটার্ন টাইপ টাইপ করতে হবে।

সম্পাদনা: সহজ (কিন্তু সম্ভবত কম ব্যাপকভাবে সামঞ্জস্যপূর্ণ) সংস্করণ এখানে


6
# অররের পরিবর্তে, #
নির্ধারিত

1
এমপিএস: অবমূল্যায়ন হ'ল কেবল একটি সতর্কতা, এবং তাই আমি বলব যে একটি সতর্কতা যা এটি সমর্থন করে না এটি আপনার প্রয়োজন কেবল।
লিওন টিমারম্যানস

1
হ্যাঁ, আমি "# সতর্কতার জন্য আপনাকে এই সংকলকের জন্য অগ্রাহ্য" প্রয়োগ করতে হবে, বা এই জাতীয় কিছু। যদি এটি অসম্ভব, তবে পোর্টার ডেপ্রেসিটেড (এফইউএনসি) এফএনওসি নির্ধারণ করতে এবং এটি ছাড়া বাঁচতে পারে।
স্টিভ জেসোপ

2
দুর্ভাগ্যক্রমে সি ++ তে একটি সংকলন সতর্কতা আউটপুট করার কোনও মানক উপায় নেই: পি #pragma বার্তাটি করতে হবে।
মাইকেল প্লাটিং

3
জিসিসির অ্যাট্রিবিউট সিনট্যাক্সের সাহায্যে অ্যাট্রিবিউটটি __declspec(deprecated)এখনকার জায়গাগুলিতে থাকার অনুমতি দেয় , তাই ম্যাক্রোটিকে সরলীকৃত করা যায়।
bames53

57

আমার ২০০৮ উত্তরের একটি সরলীকৃত সংস্করণ এখানে :

#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(...));
মুড়ে

12
আপনার একটি নতুন পোস্ট করার চেয়ে আপনার 2008 উত্তরটি সম্পাদনা করা উচিত ছিল।
ইয়াকভ গালকা

4
এটি আমার অন্যান্য উত্তরের মতো ব্যাপকভাবে সামঞ্জস্যপূর্ণ নাও হতে পারে, তাই আমি এটিকে পৃথকভাবে যুক্ত করেছি।
মাইকেল প্লাটিংগুলি

22

জিসিসিতে আপনি নিজের ফাংশনটি এই জাতীয়ভাবে অবচয় করা বৈশিষ্ট্যের সাথে ঘোষণা করতে পারেন:

void myfunc() __attribute__ ((deprecated));

যখন সেই ফাংশনটি .c ফাইলে ব্যবহৃত হয় তখন এটি একটি সংকলিত-সময় সতর্কবার্তাটি ট্রিগার করবে।

আপনি "ডায়াগনস্টিক প্রাগমাস" এর অধীনে http://gcc.gnu.org/onlinesocs/gcc/Pragmas.html এ আরও তথ্য পেতে পারেন


8

এখানে 2018 এর আরও সম্পূর্ণ উত্তর দেওয়া হয়েছে।

এই দিনগুলিতে প্রচুর সরঞ্জাম আপনাকে কেবল কিছু হ্রাস করা হিসাবে চিহ্নিত না করে একটি বার্তা সরবরাহ করার অনুমতি দেয়। এটি আপনাকে কোনও কিছু যখন অবমূল্যায়ন করা হয়েছিল তা লোকেদের বলতে এবং এটি কোনও প্রতিস্থাপনের দিকে নির্দেশ করতে সহায়তা করে।

সংকলক সমর্থনে এখনও প্রচুর বৈচিত্র্য রয়েছে:

  • সি ++ 14 সমর্থন করে [[deprecated]]/ [[deprecated(message)]]
  • __attribute__((deprecated)) GCC 4.0+ এবং এআরএম 4.1+ দ্বারা সমর্থিত
  • __attribute__((deprecated))এবং এর __attribute__((deprecated(message)))জন্য সমর্থিত:
    • GCC 4.5+
    • বেশ কয়েকটি সংকলক যা জিসিসি 4.5+ হিসাবে সজ্জিত করে (সেট করে __GNUC__/ __GNUC_MINOR__/ __GNUC_PATCHLEVEL__)
    • ইনটেল সি / সি ++ কম্পাইলার কমপক্ষে 16 এ ফিরে যেতে পারে (আপনি বিশ্বাস করতে পারবেন না __GNUC__/ __GNUC_MINOR__, তারা কেবল এটি জিসিসির যে কোনও সংস্করণ ইনস্টল করা আছে এটিতে সেট করে)
    • এআরএম 5.6+
  • এমএসভিসি __declspec(deprecated)13.10 (ভিজ্যুয়াল স্টুডিও 2003) থেকে সমর্থন করে
  • এমএসভিসি __declspec(deprecated(message))14.0 (ভিজ্যুয়াল স্টুডিও 2005) থেকে সমর্থন করে

এছাড়াও আপনি ব্যবহার করতে পারেন [[gnu::deprecated]]সি ++ 11 ঝনঝন সাম্প্রতিক সংস্করণ উপর ভিত্তি করে __has_cpp_attribute(gnu::deprecated)

আমি হেটলিতে এই সমস্তগুলি স্বয়ংক্রিয়ভাবে পরিচালনা করতে কিছু ম্যাক্রো রেখেছি যা আমি আপ টু ডেট রাখি তবে বর্তমান সংস্করণ (ভি 2) এর মতো দেখাচ্ছে:

#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ম্যাক্রো থেকে মুক্তি পাবেন তা নির্ধারণের জন্য আমি এটি একটি অনুশীলন হিসাবে ছেড়ে দেব (আমি হিডলি বেশিরভাগ ক্ষেত্রে লিখেছি যাতে আমাকে নিয়মিতভাবে সে সম্পর্কে ভাবতে হবে না)।

যদি আপনি জিএলিব ব্যবহার করেন তবে আপনি G_DEPRECATEDএবং G_DEPRECATED_FORম্যাক্রোগুলি ব্যবহার করতে পারেন । এগুলি হিডলির মতো শক্তিশালী নয় তবে আপনি যদি ইতিমধ্যে জিএলিব ব্যবহার করেন তবে যুক্ত করার মতো কিছুই নেই।


4

পোর্টেবল প্রকল্পগুলির সাথে ডিল করা প্রায় অনিবার্য যে আপনার এক পর্যায়ে একাধিক প্ল্যাটফর্মের জন্য প্রিপ্রোসেসড বিকল্পগুলির একটি বিভাগ প্রয়োজন। #ifdef এই #ifdef যে এবং আরও।

এই জাতীয় বিভাগে আপনি শর্তাধীন প্রতীককে হ্রাস করার একটি উপায় নির্ধারণ করতে পারেন। আমার পছন্দ সাধারণত একটি "সতর্কতা" ম্যাক্রো সংজ্ঞায়িত করা হয় যেহেতু বেশিরভাগ সরঞ্জামচেন কাস্টম সংকলক সতর্কতা সমর্থন করে। তারপরে আপনি অবচয় ইত্যাদির জন্য একটি নির্দিষ্ট সতর্কতা ম্যাক্রো সহ যেতে পারেন dedicated


1

ইন্টেল সংকলক v19.0 এর জন্য, __INTEL_COMPILERমূল্যায়ণ হিসাবে এটি ব্যবহার করুন 1900:

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

নিম্নলিখিত ভাষার স্তরের জন্য কাজ করে:

  • সি ++ 17 সমর্থন (/ কিএসটিডি = সি ++ 17)
  • সি ++ ১৪ সমর্থন (/ কিএসটিডি = সি ++ ১৪)
  • সি ++ 11 সমর্থন (/ কিএসটিডি = সি ++ 11)
  • সি 11 সহায়তা (/ কিএসটিডি = সি 11)
  • সি 99 সহায়তা (/ কিএসটিডি = সি 99)

ইন্টেল সংকলকটিতে একটি বাগ উপস্থিত রয়েছে যা এতে [[deprecated]]অন্য সমস্ত সংকলকরা কিছু নির্দিষ্ট ভাষা উপাদানগুলির বৈশিষ্ট্যটিকে সমর্থন করে না। উদাহরণস্বরূপ, গিটহাবের ইনটেল সংকলক v19.0 সহ (উল্লেখযোগ্য চমত্কার) {fmtlib / fmt} লাইব্রেরির v6.0.0 সংকলন করুন। এটি ভেঙে যাবে। তারপরে গিটহাব কমিটের স্থিরতা দেখুন


এটি ভুল; সি ++ বৈশিষ্ট্যগুলি আইসিসিতে সি মোডে কাজ করে না। উদাহরণ__attribute__((deprecated)), ওটিওএইচ, সি এবং সি ++ এ কাজ করে কমপক্ষে আইসিসি ১৩.০-তে ফিরে যাচ্ছে, সম্ভবত আরও অনেক কিছু (ইনটেল এই ধরণের স্টাফ্ট ডকুমেন্ট না করে যাতে আমি নিশ্চিত হতে পারি না)।
nemequ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.