কেন ফ্রি রিটার্ন মান বাতিল হবে?


82

আমি একটি বই পড়ছি ( বুটেনহফ, ১৯৯ with দ্বারা প্রোগ্রামিং সহ প্রোগ্রামিং ) যা সি ব্যবহার করে এবং আমি নিম্নলিখিত পংক্তিতে এসেছি:

(void)free(data);

এখানে, dataএকটি বরাদ্দ কাঠামোর কেবলমাত্র পয়েন্টার,

data = malloc(sizeof(my_struct_t));

কেন ফলাফল দেওয়া freeহচ্ছে void?

সি সম্পর্কে আমার বোঝাপড়া থেকে, এটি দুটি কারণে বোধ হয় না:

  • ফ্রি ফাংশন ইতিমধ্যে ফিরে আসে void
  • কোডটি রিটার্ন মান ব্যবহার করছে না (এটি কোনও ভেরিয়েবলের জন্য বরাদ্দও দেওয়া হচ্ছে না)

বইটি 1997 সালে লেখা হয়েছিল। এটি কি কোনও ধরণের উত্তরাধিকার বিষয়?

লেখক উল্লেখ করেছেন যে উদাহরণগুলি ডিজিটাল ইউনিক্স 4.0.০ ডি তে চালানো হয়েছিল, তবে আপনি যদি এখনও সেই ফলাফলটি ব্যবহার না করেন তবে কোনও ফাংশনের ফলাফল কাস্ট করার কোনও কারণ আমি এখনও কল্পনা করতে পারি না।


কিছু সম্ভাব্য ব্যাখ্যা এখানে পাওয়া যাবে: stackoverflow.com/questions/689677/…
টিম্বো

3
কৌতূহলের বাইরে, আপনার সি বই প্রকাশের তারিখটি কী? (এটি কোন বই?) এটি যদি 1995 এর আগে হয় তবে এর জন্য কিছুটা ন্যায়সঙ্গততা থাকতে পারে - স্ট্যান্ডার্ড সি সংকলক তখনকার আগে সর্বব্যাপী ছিল না। যদি এটির পরে প্রকাশিত হয় এবং এখনও theালাই রয়েছে (এবং কেন এর কোনও ব্যাখ্যা নেই) তবে এটি আপনাকে কী অন্যান্য খারাপ অভ্যাসগুলি শিখিয়ে দিচ্ছে তা নিয়ে চিন্তা করুন। আরও একটি সাম্প্রতিক বই পান!
জোনাথন লেফলার


3
@ জোনাথনলফলার আমার মূল পোস্টে উল্লিখিত হিসাবে, বইটি 1997 সালে প্রকাশিত হয়েছিল এবং ইউএনআইএক্স 4.0.0 ব্যবহার করছিল। বইটি ডেভিড আর বুটেনফের লেখা "প্রোগ্রামিং উইথ পসিক্স থ্রেডস"। এখনও অবধি এটি অত্যন্ত তথ্যবহুল এবং POSIX থ্রেড স্ট্যান্ডার্ডের মূল অবদানকারীদের একজন লিখেছেন।
অ্যাডাম জনস্টন

6
আমি গত সপ্তাহে আমার অনুলিপিটি ব্যবহার করেছি - হ্যাঁ, এটি এখনও কার্যকর। এটি 'সর্বব্যাপী স্ট্যান্ডার্ড সি' (আমি 1995 সম্পর্কে 'বলেছিলাম) এর চিপিতে লেখা হয়েছিল। 'UNIX 4.0d' ডিজিটাল ইউনিক্সের মতো শোনাচ্ছে - এটিই বুটেনহফ কাজ করেছিল এবং এর প্রবন্ধটিতে এর উল্লেখ নেই। free()কাস্টটিকে বইয়ের একটি বিজোড় হিসাবে বিবেচনা করুন যা আপনার অনুকরণ করার দরকার নেই। এটি দীর্ঘ সময় আগে একবার আধা-প্রাসঙ্গিক ছিল, তবে এটি আর প্রাসঙ্গিক নয়।
জোনাথন লেফলার

উত্তর:


100

যদি আমরা স্ট্যান্ডার্ড freeফাংশন সম্পর্কে কথা বলি তবে এর প্রোটোটাইপটি

void free(void *ptr);

সুতরাং castালাই সম্পূর্ণ অকেজো।
এখন কিছু জল্পনা।

লেখক সম্ভবত stdlib.hএই প্রোটোটাইপটি ঘোষণা করে শিরোলেখকে অন্তর্ভুক্ত করতে ভুলে গিয়েছেন , তাই সংকলক এটির ফেরতের ধরন হিসাবে ধরে নিচ্ছে int। এখন এই কোডটির স্থির বিশ্লেষণের সময় সংকলকটি এটি অ- voidকার্যকারিতা বলে মনে করে এর অব্যবহৃত রিটার্ন মান সম্পর্কে সতর্ক করে দিয়েছিল । এ জাতীয় সতর্কতাগুলি সাধারণত .ালাই যোগ করে চুপ করে দেওয়া হয় void


50
তবে মনে রাখবেন যে যদি অনুমানের কারণেই theালাই প্রবর্তন করা হয়, তবে সতর্কতাটি নিঃশব্দ করতে এটি ব্যবহার করা ভুল । সংস্থাপক সেই ক্ষেত্রে freeএটির চেয়ে ভিন্ন ধরণের বৈশিষ্ট্যযুক্ত করবে, ফলস্বরূপ যে কলটি অনির্ধারিত আচরণ করেছে (ধরুন C90 শব্দার্থবিজ্ঞান, যেখানে একটি অঘোষিত ফাংশন কল করা সমস্ত ক্ষেত্রে সহজাতভাবে ইউবি প্রদর্শন করে না)। বাস্তবে, এটি প্রশংসনীয় যে এর ফলে কিছু সিস্টেমে ভয়াবহ দুর্ব্যবহার ঘটে। সঠিক সমাধানটি হ'ল ফাংশনটির জন্য একটি সঠিক ঘোষণা প্রদান।
জন বলিঞ্জার

11
উল্লেখযোগ্যভাবে, "পজিক্স থ্রেড সহ প্রোগ্রামিং" এর উদাহরণগুলি প্রাসঙ্গিক মানক শিরোনাম অন্তর্ভুক্ত করতে বারবার ব্যর্থ হয়। হতে পারে এটি লেখকের কিছু খারাপ অভ্যাস ছিল, তারা একটি অ-মানক সংকলক সেটআপ ব্যবহার করতে পারত যা ডিফল্টরূপে সমস্ত স্ট্যান্ডার্ড libs অন্তর্ভুক্ত করে।
লন্ডিন

74

এটা একটা উত্তরাধিকার বিষয় হবে!

কোনও সি স্ট্যান্ডার্ড থাকার আগে, free()ফাংশনটি (স্পষ্টভাবে) টাইপের intহত - কারণ voidএটির ফেরার জন্য এখনও নির্ভরযোগ্যভাবে কোনও ধরণ ছিল না । কোনও মূল্য ফেরত পাওয়া যায়নি।

কোডটি যখন প্রথমে স্ট্যান্ডার্ড সি সংকলকগুলির সাথে কাজ করার জন্য সংশোধন করা হয়েছিল, সম্ভবত এটি অন্তর্ভুক্ত হয়নি <stdlib.h>(কারণ এটি স্ট্যান্ডার্ডের আগে উপস্থিত ছিল না)। পুরাতন কোড বরাদ্দ ফাংশনগুলির জন্য extern char *malloc();(সম্ভবত এটি ছাড়া extern) লিখত ( একইভাবে calloc()এবং এর জন্য realloc()), এবং এটি ঘোষণার দরকার পড়ে না free()। এবং কোডটি তারপরে রিটার্নের মানটি সঠিক ধরণে ফেলে দেবে - কারণ এটি কমপক্ষে কয়েকটি সিস্টেমে (যা আমি সি শিখেছি তার সাথে অন্তর্ভুক্ত) প্রয়োজনীয় ছিল।

কিছু সময় পরে, (void)অভিনেতা সংযোজনকারীকে (বা আরও সম্ভবত, lint) বলার জন্য যুক্ত করা হয়েছিল যে free()কোনও অভিযোগ এড়াতে "ইচ্ছাকৃতভাবে প্রত্যাবর্তনের মান অগ্রাহ্য করা হয়"। কিন্তু এটি যোগ করতে ভাল হতো <stdlib.h>এবং তার ঘোষণা দেবেন extern void free(void *vp);বলুন lintবা কম্পাইলার উপেক্ষা করার কোনো মূল্যই নেই।

জেএফটিআর: '80-এর দশকের মাঝামাঝি সময়ে, আইসিএল পার্ক মূলত একটি শব্দ-ভিত্তিক স্থাপত্যে ছিল এবং char *মেমরির অবস্থানের ঠিকানাটি 'যেকোন_সেরা পয়েন্টার' থেকে একই লোকেশনে খুব আলাদা একটি সংখ্যা ছিল। এটি char *malloc()কোনওভাবে ঘোষণা করা অত্যন্ত গুরুত্বপূর্ণ ; এটি থেকে অন্য কোনও পয়েন্টার ধরণের ক্ষেত্রে ফলাফলটি ফেলে দেওয়া অত্যন্ত গুরুত্বপূর্ণ। কাস্টটি আসলে সিপিইউ দ্বারা ব্যবহৃত নম্বরটি পরিবর্তন করেছে। (যখন আমাদের সিস্টেমে মূল মেমরিটি 1 এমআইবি থেকে 2 মাইবিতে আপগ্রেড করা হয়েছিল তখনও অনেক আনন্দ হয়েছিল - যেহেতু কার্নেলটি প্রায় 3/4 মাইবি ব্যবহার করে, এর অর্থ হ'ল ব্যবহারকারী প্রোগ্রামগুলি পেজিংয়ের আগে 1 1/4 মাইবি ব্যবহার করতে পারে))


9
আমি সবেমাত্র কে অ্যান্ড আর, প্রথম সংস্করণের একটি অনুলিপি খুলেছি, যা free()পি - তে একটি বাস্তবায়ন রয়েছে । 177 যা সুস্পষ্টভাবে ফেরত দেয় int
প্রাক্তন নিহিলো

9
অবশ্যই - voidস্ট্যান্ডার্ডটি প্রকাশের আগে কিছু সিস্টেমে (ইউনিক্স সিস্টেম তৃতীয়, সম্ভবত) যোগ করা হয়েছিল, তবে কে অ্যান্ড আর 1 ম এডন যখন লেখা হয়েছিল (1978) তখন এটি সি এর অংশ ছিল না। কোনও ফাংশন যা কোনও মান ফেরত দেয় না তা কোনও রিটার্নের ধরণ ছাড়াই ঘোষণা করা হয়েছিল (যার অর্থ এটি ফিরে এসেছে int), এবং যতক্ষণ না আপনি যে মানটি প্রত্যাবর্তিত হয়নি তা ব্যবহার না করে কোনও সমস্যা নেই। সি 90 স্ট্যান্ডার্ডকে এই ধরণের কোডটিকে বৈধ হিসাবে গণ্য করতে হবে - এটি স্ট্যান্ডার্ড না থাকলে এটি অসম্পূর্ণভাবে ব্যর্থ হত। তবে সি 99 'অন্তর্নিহিত int' এবং 'অন্তর্নিহিত ফাংশন ঘোষণার' নিয়ম সরিয়ে দিয়েছে। বিশ্বের সমস্ত কোড ধরা পড়ে না।
জোনাথন লেফলার

5
ওপ দাবী করেন যে বইটি 1997 সালে লেখা হয়েছিল। আপনি এখানে যে বিষয়টির কথা বলছেন তা খুব প্রথম দিকের প্রাক-মানক "কে অ্যান্ডআর সি" এবং এটি সম্ভবত কেউই এই সম্পর্কে একটি বই লিখতে পারে বলে মনে হয় না। আমার জ্ঞানের অস্তিত্ব ছিল এমন একমাত্র বই আসলেই কে ওআরআর ১ ম সংস্করণ।
লন্ডিন

আপনি যদি মনে করেন যে আপনি অন্তর্নিহিত ঘোষণা দিয়ে দূরে সরে যেতে পারেন, তবে শিরোনামকে অন্তর্ভুক্ত না করা একটি ঘন ঘন (কুইক্সটিক) অনুশীলন ছিল, কারণ লোকেরা মনে করেছিল যে এটি নির্মাণের সময়কে হ্রাস করবে।
স্পেন্সার

কেউ কি (void)কাস্ট ব্যবহার করেন printf()??
লুইস কলোরাডো

11

এই castালাইয়ের দরকার নেই। সি সম্ভবত সি 89 এর আকারে মানীকৃত হওয়ায় এটি সম্ভবত তখনই ঘটেনি।

যদি এটি থাকত তবে তা অন্তর্নিহিত ঘোষণার কারণে হত । এর অর্থ সাধারণত যে কোডটি লিখেছেন সে ভুলে গিয়েছিল #include <stdlib.h>এবং একটি স্ট্যাটিক বিশ্লেষক ব্যবহার করা হচ্ছে। এটি সর্বোত্তম কাজ নয় এবং এর #include <stdlib.h>পরিবর্তে আরও ভাল ধারণা পাওয়া উচিত । অন্তর্নিহিত ঘোষণা সম্পর্কে C89 এর কিছু শব্দ এখানে দেওয়া হয়েছে:

যদি কোনও ফাংশন কলের মধ্যে প্রথম বন্ধনীযুক্ত আর্গুমেন্ট তালিকার পূর্বে প্রকাশিত অভিব্যক্তিটি কেবল কোনও সনাক্তকারীকে অন্তর্ভুক্ত করে এবং যদি এই সনাক্তকারীটির জন্য কোনও ঘোষণা দৃশ্যমান না হয় তবে সনাক্তকারীটি স্পষ্টভাবে ঠিক এমনভাবে ঘোষিত হয় যেমন, ফাংশন কলযুক্ত অন্তর্নিহিত ব্লকে, ঘোষণাটি

extern int identifier();

হাজির.

কিন্তু যে কারণ তারা ফল কাস্ট করছেন না অদ্ভুত mallocপারেন, এবং mallocএবং freeএকই হেডার ফাইল রয়েছে।

এটিও সম্ভব যে এটি কেবল একটি ভুল বা পাঠককে বলার কোনও উপায় যা freeকোনও ফল দেয় না।


5
যেহেতু কোনও ভাষা প্রমিত হয়ে যায় তার অর্থ এই নয় যে প্রত্যেকে তাত্ক্ষণিকভাবে তার অনুসারে তাদের সরঞ্জামচেইন এবং কোড আপডেট করে। এটি পুরানো ধাঁচের "কেএন্ডআর" সি আরও 8 বছর ধরে আটকে থাকার জন্য প্রশংসনীয়। তবুও আমি সম্মত হন যে এটা বিশ্রী যে একটি স্ট্যাটিক বিশ্লেষণ টুল জন্য একটি ঢালাই করতে হবে freeকিন্তু এর জন্য malloc
dan04

4
@ dan04 আপনি সাধারণত মলোকের ফলাফল ব্যবহার করেন;) সংকলককে স্পিটিং সতর্কতা বন্ধ করতে আমি (শূন্য) প্রিন্টফ (...) এর মতো জিনিসগুলি লেখার কোনও অনুরাগী নই তবে "কোনও সতর্কতা ছাড়াই সংকলন করতে হবে, এমনকি বোকা লোকগুলি" এমন একটি বিষয় যা এমন অনেক প্রকল্পে ঘটে।
রিচার্ডব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.