অব্যবহৃত রিটার্ন মান বাতিল করা কেন?


112
int fn();

void whatever()
{
    (void) fn();
}

অব্যবহৃত রিটার্ন মান শূন্য করার জন্য কোনও কারণ আছে কি, বা আমি কি এটি সম্পূর্ণরূপে সময় নষ্ট করার ভেবে সঠিক?

অনুসরণ করুন:

ভাল যে বেশ ব্যাপক বলে মনে হচ্ছে। আমি মনে করি এটি একটি অব্যবহৃত রিটার্ন মান মন্তব্য করার চেয়ে ভাল, যেহেতু স্ব নথিবদ্ধকরণ কোড মন্তব্যগুলির চেয়ে ভাল। ব্যক্তিগতভাবে, আমি এই সতর্কতাগুলি বন্ধ করব কারণ এটি অযথা শোনাচ্ছে।

আমি আমার কথাগুলি খাবো যদি কোনও বাগ এর কারণে পালিয়ে যায় ...

উত্তর:


79

ডেভিডের উত্তরটি আরও স্পষ্টভাবে অন্যান্য "বিকাশকারীদের" দেখানোর জন্য এটিটির অনুপ্রেরণাকে কভার করে, আপনি জানেন যে এই ফাংশনটি ফিরে আসে তবে আপনি তা স্পষ্টভাবে এড়িয়ে যাচ্ছেন।

প্রয়োজনীয় ত্রুটি কোডগুলি সর্বদা পরিচালনা করা হয় তা নিশ্চিত করার একটি উপায় এটি।

আমি মনে করি সি ++ এর জন্য এটিই কেবলমাত্র একমাত্র জায়গা যেখানে আমি সি-স্টাইলের কাস্ট ব্যবহার করতে পছন্দ করি, যেহেতু সম্পূর্ণ স্ট্যাটিক কাস্ট স্বরলিপি ব্যবহার করে এখানে ওভারকিলের মতো মনে হয়। অবশেষে, আপনি যদি কোনও কোডিং স্ট্যান্ডার্ডটি পর্যালোচনা করছেন বা একটি লিখেছেন, তবে স্পষ্টভাবে এটি বলা ভাল যে ওভারলোডেড অপারেটরগুলিকে কল (ফাংশন কল স্বরলিপি ব্যবহার না করে) এটি থেকেও অব্যাহতি দেওয়া উচিত:

class A {};
A operator+(A const &, A const &);

int main () {
  A a;
  a + a;                 // Not a problem
  (void)operator+(a,a);  // Using function call notation - so add the cast.

এটি কেবলমাত্র আমি সি-স্টাইলের কাস্ট পছন্দ করি। আমার কোডিং স্ট্যান্ডার্ডের মধ্যে, আমি "অ + এ" (অকার্যকর) যুক্ত করব; খুব (যথাযথভাবে প্যারেনড, অবশ্যই: পি)
জোহানেস স্কাউব - লিটব

8
কিছুটা বন্ধ বিষয়, তবে আপনি কেন কখনও "এ + এ" করবেন? রিটার্ন ভ্যালু ব্যবহার না করেই এমন? এটি সত্যিই আমার কাছে পার্শ্ব প্রতিক্রিয়াগুলির অপব্যবহারের মতো বলে মনে হচ্ছে এবং কোডের উদ্দেশ্যকে অবিচ্ছিন্ন করে দেয়।
রব কে

5
ঠিক আছে, আপনি প্রতিদিন যেটি ব্যবহার করবেন সেটি হ'ল 'a = a'। এটি বস্তুকে বরাদ্দ করা (সমস্ত ভাল আচরণের ক্লাসগুলির জন্য যা :)!) প্রদান করে। আর একটি উদাহরণ হ'ল: << "হ্যালো ওয়ার্ল্ড" << স্টাড :: এন্ডেল। তাদের প্রত্যেকে "ওএস" বস্তুটি ফেরত দেয়।
রিচার্ড কর্ডেন

46

কর্মক্ষেত্রে আমরা এটি ব্যবহার করে ফাংশনটির একটি ফেরতের মান রয়েছে তা স্বীকার করতে এটি ব্যবহার করি তবে বিকাশকারী দৃ as়ভাবে জানিয়েছিলেন যে এটি এড়ানো নিরাপদ। যেহেতু আপনি প্রশ্নটিকে সি ++ হিসাবে ট্যাগ করেছেন আপনার স্ট্যাটিক_কাস্ট ব্যবহার করা উচিত :

static_cast<void>(fn());

সংকলক হিসাবে যতদূর শূন্যে ফেরতের মান .ালাই যায় তেমন অর্থ হয় না।


এটি অব্যবহৃত রিটার্ন মান সম্পর্কে সতর্কতা দমন করে?
পল টমবলিন 13

না, তা হয় না। @ মাইকোলা: জিসিসি 4 এর সাহায্যে আপনি এমন একটি বৈশিষ্ট্য সংযুক্ত করতে পারেন যা বলে যে রিটার্ন মানটিকে অগ্রাহ্য করা উচিত নয় যা একটি সতর্কবার্তা ট্রিগার করবে।
ডেভিড হল্ম

2
আমি জি ++ ব্যবহার করি এবং এটি এমন কাস্ট দিয়েও সতর্কতা দেয়।
ক্লিও করুন

2
আপনি কোন সতর্কতা বিকল্পটি ব্যবহার করেন? -চলাচল করা মানটি আমার পরিবেশে সতর্কবার্তাটি ট্রিগার করে না
মাইকোলা গোলুবিয়েভ

ভিসি ++ এ, এটি সতর্কতা দমন করে
জাল্ফ ২

39

এটি করার আসল কারণটি সি কোডে ব্যবহৃত একটি সরঞ্জামে ফিরে আসে যার নাম লিন্ট

এটি সম্ভাব্য সমস্যাগুলির সন্ধান এবং সতর্কতা এবং পরামর্শ জারি করার কোড বিশ্লেষণ করে। যদি কোনও ফাংশন এমন কোনও মান ফেরত দেয় যা যাচাই না করা হয়, lintতবে এটি যদি দুর্ঘটনাক্রমে ঘটে তবে সতর্ক করে দেবে। lintএই সতর্কতার উপর নীরবতা বজায় রাখার জন্য , আপনি কলটি কল করেছেন (void)


2
এটি সম্ভবত এইভাবে শুরু হয়েছিল তবে বেশিরভাগ সরঞ্জামগুলিতে এখন এই জাতীয় সতর্কতা দমন করার জন্য অন্যান্য প্রক্রিয়া রয়েছে। এছাড়াও - বিশেষ করে সুরক্ষা সমালোচনামূলক কোডের ডোমেনের মধ্যেই কেন এটি শুরু হয়েছিল তা নির্বিশেষে এটি বিকাশকারীদের উদ্দেশ্যগুলিকে "নথিভুক্ত" করার স্বাভাবিক উপায় হয়ে দাঁড়িয়েছে।
রিচার্ড কর্ডেন

5
জিসিসি-ওয়াল দিয়ে এর জন্য একটি সতর্কতা দেয়।
গ্রেফেইড

23

কাস্টিং void অব্যবহৃত ভেরিয়েবল এবং অরক্ষিত ফেরত মান বা এক্সপ্রেশনগুলির জন্য সংকলক সতর্কতা দমন করতে ব্যবহৃত হয়।

স্ট্যান্ডার্ড (2003) §5.2.9 / 4 এ বলেছেন,

যে কোনও এক্সপ্রেশন স্পষ্টভাবে "সিভি অকার্যকর" টাইপে রূপান্তরিত হতে পারে। এক্সপ্রেশন মান বাতিল করা হয়

সুতরাং আপনি লিখতে পারেন:

//suppressing unused variable warnings
static_cast<void>(unusedVar);
static_cast<const void>(unusedVar);
static_cast<volatile void>(unusedVar);

//suppressing return value warnings
static_cast<void>(fn());
static_cast<const void>(fn());
static_cast<volatile void>(fn());

//suppressing unsaved expressions
static_cast<void>(a + b * 10);
static_cast<const void>( x &&y || z);
static_cast<volatile void>( m | n + fn());

সমস্ত ফর্ম বৈধ। আমি সাধারণত এটিকে ছোট করে তুলি:

//suppressing  expressions
(void)(unusedVar);
(void)(fn());
(void)(x &&y || z);

এটাও ঠিক আছে।


1
এটি সর্বদা সংকলক সতর্কতাগুলি বন্ধ করে না Ex জিসিসি অকার্যকর কাস্টিংয়ের প্রতিক্রিয়া বলে মনে হচ্ছে না
ম্যাট

@ ম্যাট: আপনি জিসিসির কোন সংস্করণ ব্যবহার করছেন? আপনি কি আদর্শ কোড.কম বা স্ট্যাকড-ক্রুকড ডট কম এ আপনার কোড পোস্ট করতে পারেন (উত্তরটি আরও ভাল)।
নওয়াজ

1
স্ট্যান্ডার্ড "ফেলে দেওয়া" শব্দটি কি বোঝায় যে সতর্কবাণীটি রেখা দ্বারা উত্থাপন করা উচিত নয়?
সিরো সান্তিলি 郝海东 冠状 病 六四 事件 法轮功

2
@ সিরোস্যান্টিলি 巴拿馬 文件 六四 事件 法轮功: .... এটি একটি আকর্ষণীয় প্রশ্ন। বর্তমানে, আমি এর উত্তর জানি না। আপনি যদি কোনওভাবে জানতে পারেন তবে দয়া করে আমার সাথে ভাগ করুন।
নওয়াজ

8

সি ++ 17 হ'ল আমাদের কাছে [[maybe_unused]]বৈশিষ্ট্য রয়েছে যা voidকাস্টের পরিবর্তে ব্যবহার করা যেতে পারে ।


1
সি ++ 17 এছাড়াও যুক্ত হয়েছে nodiscardযা আগ্রহী হতে পারে: stackoverflow.com/a/61675726/895245 এছাড়াও আমি মনে করি আপনি [[maybe_unused]]কলটি সরাসরি প্রয়োগ করতে পারবেন না বলে মনে হয়, কেবলমাত্র একটি ডামি ভেরিয়েবল যা কলটির রিটার্ন গ্রহণ করে? যদি এটি সঠিক হয় তবে এটি কিছুটা দুর্বল।
সিরো সান্তিলি 法轮功 冠状 病 六四 事件

4

অকার্যকর যাও Castালাই ব্যয়বহুল। এটি কীভাবে চিকিত্সা করা যায় তা কেবল কম্পাইলারের জন্য তথ্য।


1
কোডটি লেখার সময় এবং পরবর্তী সময় পড়ার, বোঝার (এবং তারপরে উপেক্ষা করা) কোড বিনামূল্যে থাকলে এটি "ব্যয়বহুল"। আইএমও, লেখার (void)জন্য আমার সময় এবং শক্তি ব্যয় হয় এবং লেখক কীভাবে এক্সপ্রেশন কাজ করে তা জানেন কিনা তা অবাক করে তোলে।
ওয়াল্ক

4

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


2
এটি অন্যদেরকে সুস্পষ্টরূপে জানাতে একটি পরিচিত প্যাটার্ন যা আপনি রিটার্ন মানটির বিষয়ে চিন্তা করেন না, আপনি এটি হ্যান্ডেল করতে ভুলে যাননি।
স্পাইডি

For the functionality of you program casting to void is meaninglessসংকলনের সময় স্ব-ডকুমেন্টেশন এবং সতর্কতার সংখ্যার জন্য, এটি আসলে তা নয়। কোডটি নিজের ব্যাখ্যা দিলে you should not use it to signal something to the person that is reading the code [...] it is better to use a comment.সেরা মন্তব্যটি কোনও মন্তব্য নয়। এবং, আবারও, একটি কার্যকরভাবে সতর্কতা সংকলক প্রক্রিয়ায় খুশি রাখে।
আন্ডারস্কোর_ডি

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

1

এছাড়াও আপনার কোডটি মিস্টা (বা অন্যান্য) মান মেনে চলার সময়, স্বয়ংক্রিয় সরঞ্জামগুলি যেমন এলডিআরএ আপনাকে কোনও ফাংশন কল করতে দেয় না যা কোনও মান ফেরত না দিয়েই কোনও ফাংশন কল করতে দেয় না যদি আপনি স্পষ্টভাবে প্রত্যাবর্তিত মানটিকে (শূন্য) না ফেলে থাকেন


0

সি ++ 17 [[nodiscard]]

সি ++ 17 একটি বৈশিষ্ট্যের সাথে "রিটার্ন মান উপেক্ষা করা ব্যবসার" মানকৃত করে।

অতএব, আমি আশা করি যে অনুগত বাস্তবায়নগুলি সর্বদা কেবল তখনই সতর্ক করবে nodiscard হয় এবং অন্যথায় কখনও সতর্ক করে না।

উদাহরণ:

main.cpp

[[nodiscard]] int f() {
    return 1;
}

int main() {
    f();
}

কম্পাইল:

g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -o main.out main.cpp

ফলাফল:

main.cpp: In function int main()’:
main.cpp:6:6: warning: ignoring return value of int f()’, declared with attribute nodiscard [-Wunused-result]
    6 |     f();
      |     ~^~
main.cpp:1:19: note: declared here
    1 | [[nodiscard]] int f() {
      | 

নিম্নলিখিত সমস্ত সতর্কতা এড়ান:

(void)f();
[[maybe_unused]] int i = f();

আমি maybe_unusedসরাসরি f()কলটিতে ব্যবহার করতে পারিনি :

[[maybe_unused]] f();

দেয়:

main.cpp: In function int main()’:
main.cpp:6:5: warning: attributes at the beginning of statement are ignored [-Wattributes]
    6 |     [[maybe_unused]] f();
      |     ^~~~~~~~~~~~~~~~

(void)ঢালাই কাজ বাধ্যতামূলক করা বলে মনে হচ্ছে না কিন্তু "উৎসাহিত" হয় মান মধ্যে: আমি কিভাবে ইচ্ছাকৃতভাবে একটি [[nodiscard]] ফেরত মান বাতিল করতে পারে?

সতর্কতা বার্তা থেকে দেখা যায়, সতর্কতার একটি "সমাধান" হ'ল -Wno-unused-result:

g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result -o main.out main.cpp

যদিও আমি অবশ্যই বিশ্বব্যাপী সতর্কতাগুলি উপেক্ষা করার পরামর্শ দেব না।

সি ++ 20 এছাড়াও আপনি একটি কারণ যোগ করতে পারবেন nodiscardহিসাবে [[nodiscard("reason")]]: যেমন পদে উল্লেখিত https://en.cppreference.com/w/cpp/language/attributes/nodiscard

জিসিসি warn_unused_result গুণাবলী

মানককরণের আগে [[nodiscard]]এবং সি এর জন্য পরিশেষে গুনগুলি মানক করার সিদ্ধান্ত নেওয়ার আগে, জিসি ঠিক একই কার্যকারিতাটি প্রয়োগ করে warn_unused_result:

int f() __attribute__ ((warn_unused_result));

int f() {
    return 1;
}

int main() {
    f();
}

যা দেয়:

main.cpp: In function int main()’:
main.cpp:8:6: warning: ignoring return value of int f()’, declared with attribute warn_unused_result [-Wunused-result]
    8 |     f();
      |     ~^~

তারপরে এটি লক্ষ করা উচিত যেহেতু এএনএসআই সি এর জন্য কোনও মানদণ্ড নেই, তাই এএনএসআই সি নির্দিষ্ট করে না যে কোন সি স্ট্যান্ডার্ড লাইব্রেরির ফাংশনগুলির বৈশিষ্ট্য রয়েছে কি না এবং তাই বাস্তবায়নের সাথে কী চিহ্নিত করা উচিত বা না চিহ্নিত করা উচিত সে সম্পর্কে তাদের নিজস্ব সিদ্ধান্ত নিয়েছে warn_unuesd_result, কোনটি কোনও কারণেই (void)কোনও প্রয়োগে সতর্কতা এড়ানোর জন্য সাধারণভাবে আপনাকে স্ট্যান্ডার্ড লাইব্রেরি ফাংশনে যে কোনও কল ফেরত উপেক্ষা করতে কাস্ট ব্যবহার করতে হবে ।

জিসিসি 9.2.1, উবুন্টু 19.10 এ পরীক্ষিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.