আমি কি ম্যালোকের ফলাফলটি দেব?


2405

ইন এই প্রশ্নের , কেউ একটি প্রস্তাব মন্তব্য যে আমি উচিত না ফল নিক্ষেপ malloc, অর্থাত্

int *sieve = malloc(sizeof(int) * length);

বরং:

int *sieve = (int *) malloc(sizeof(int) * length);

কেন এমন হবে?


221
এছাড়াও, চালনা = ম্যালোক (আকারের * চালুনি * দৈর্ঘ্য) লিখতে এটি আরও রক্ষণাবেক্ষণযোগ্য;
উইলিয়াম পার্সেল


3
এখানে উত্তরগুলি একতরফায়ের খনি ক্ষেত্র। উত্তরটি হল, এটা নির্ভরশীল". প্রোগ্রামটি কাজ করা কোনও প্রয়োজনীয় জিনিস নয়। তবে কিছু কোডিং মান এটির প্রয়োজন হয় ... উদাহরণস্বরূপ, দেখুন সিইআরটি সি কোডিং স্ট্যান্ডার্ড
ডঃ ব্যক্তি ব্যক্তি II

আশ্চর্যের বিষয় হল, সকলেই সম্মত হন যে আপনি castালাই করেন না NULL। (এই কারণেই সম্ভবত সি ++ প্রবর্তন করা হয়েছে nullptr: সি ++ কোনও অন্তর্নিহিত পয়েন্টার কাস্টকে অনুমতি দেয় না)
নীলা_ব্রীক

আপনি পারেন, কিন্তু আপনার দরকার নেই। তবে আপনার সি ++ এ থাকা দরকার।
কোনও দেহ

উত্তর:


2215

না ; আপনি ফলাফলটি নিক্ষেপ করবেন না , যেহেতু:

  • এটি যেমন অপ্রয়োজনীয় void * স্বয়ংক্রিয়ভাবে এবং নিরাপদে এই ক্ষেত্রে অন্য কোনও পয়েন্টার প্রকারে প্রচারিত হয়।
  • এটি কোডে বিশৃঙ্খলা যুক্ত করে, কাস্টগুলি পড়তে খুব সহজ নয় (বিশেষত যদি পয়েন্টারের ধরণটি দীর্ঘ হয়)।
  • এটি আপনাকে নিজেকে পুনরাবৃত্তি করে তোলে, যা সাধারণত খারাপ।
  • আপনি অন্তর্ভুক্ত করতে ভুলে গেলে এটি একটি ত্রুটিটি আড়াল করতে পারে <stdlib.h>। এটি ক্র্যাশগুলির কারণ হতে পারে (বা আরও খারাপভাবে কোডের কিছু সম্পূর্ণ ভিন্ন অংশে ক্র্যাশ ঘটায় না )। যদি পয়েন্টার এবং পূর্ণসংখ্যা পৃথক আকারের হয় তবে কী হয় তা বিবেচনা করুন; তারপরে আপনি কাস্টিং দ্বারা একটি সতর্কতা লুকিয়ে রেখেছেন এবং আপনার ফিরে দেওয়া ঠিকানার বিটগুলি হারাতে পারে। দ্রষ্টব্য: C99 হিসাবে অন্তর্নিহিত ফাংশনগুলি সি থেকে চলে গেছে, এবং এই বিন্দুটি আর প্রাসঙ্গিক নয় যেহেতু অঘোষিত ফাংশনগুলি ফিরে আসার কোনও স্বয়ংক্রিয় অনুমান নেই int

স্পষ্টতা হিসাবে, নোট করুন যে আমি বলেছিলাম "আপনি কাস্ট করবেন না", "আপনাকে কাস্ট করার দরকার নেই " না। আমার মতে, কাস্টটি অন্তর্ভুক্ত করতে এটি ব্যর্থতা, এমনকি যদি আপনি এটি সঠিকভাবে পান তবে। এটি করার কোনও সুবিধা নেই, তবে সম্ভাব্য ঝুঁকিগুলির একগুচ্ছ, এবং কাস্ট সহ এটি ইঙ্গিত করে যে আপনি ঝুঁকিগুলি সম্পর্কে জানেন না।

এছাড়াও লক্ষ্য করুন, যেমন মন্তব্যকারীরা উল্লেখ করেছেন যে উপরেরগুলি সি ++ নয়, স্ট্রেট সি সম্পর্কে কথা বলে। আমি খুব দৃ C়ভাবে সি এবং সি ++ পৃথক ভাষা হিসাবে বিশ্বাস করি।

আরও যোগ করতে, আপনার কোড অকারণে প্রকারের তথ্য ( int) এর পুনরাবৃত্তি করে যা ত্রুটির কারণ হতে পারে। দুটিকে একসাথে "লক" করতে রিটার্ন মান সঞ্চয় করতে ব্যবহৃত পয়েন্টারটিকে ডি-রেফারেন্স করা ভাল:

int *sieve = malloc(length * sizeof *sieve);

এটি lengthবর্ধিত দৃশ্যমানতার জন্য সামনে সরিয়ে নিয়ে যায়, এবং এর সাথে অপ্রয়োজনীয় বন্ধনীগুলি ফেলে দেয় sizeof; সেগুলি কেবল তখনই প্রয়োজন হয় যখন আর্গুমেন্ট কোনও প্রকারের নাম। অনেকের মনে হয় এটি এগুলি (বা উপেক্ষা করা) নয়, যা তাদের কোডকে আরও ভার্বোস করে। মনে রাখবেন: sizeofএকটি ফাংশন না! :)


lengthসামনের দিকে যাওয়ার পরে কিছু বিরল ক্ষেত্রে দৃশ্যমানতা বাড়তে পারে তবে সাধারণের ক্ষেত্রেও মনোযোগ দেওয়া উচিত যে মত প্রকাশটি লেখার চেয়ে ভাল হওয়া উচিত:

int *sieve = malloc(sizeof *sieve * length);

sizeofপ্রথমটি রাখার পরে , এক্ষেত্রে , কমপক্ষে size_tগণিত দিয়ে গুণ করা নিশ্চিত করে ।

তুলনা করুন: malloc(sizeof *sieve * length * width)বনাম malloc(length * width * sizeof *sieve)দ্বিতীয় ওভারফ্লো পারে length * widthযখন widthএবং lengthচেয়ে ছোট ধরনের হয় size_t


21
উত্তর আপডেট করার বিবেচনা করুন। Castালাই আর বিপজ্জনক নয় এবং নিজেকে পুনরাবৃত্তি করা কোনও খারাপ জিনিস নয় (রিডান্ডেন্স ত্রুটিগুলি ধরতে সহায়তা করতে পারে)।
এন। 'সর্বনাম' মি।

10
সংকলক পরিবর্তন হয়েছে। একটি আপ-টু-ডেট সংকলক আপনাকে ম্যালোকের অনুপস্থিত ঘোষণার বিষয়ে সতর্ক করবে।
এন। 'সর্বনাম' মি।

55
@ এনএম ঠিক আছে আমি মনে করি এটি এখানে খারাপ মনে হয় যে এখানে যে কেউ পড়বে তার একটি নির্দিষ্ট সংকলক রয়েছে। এছাড়াও, যেহেতু সি 11 সম্পূর্ণ "অন্তর্নিহিত ফাংশন" ধারণাটি শেষ হয়ে গেছে, আমি এটি জানতাম না। তবুও, আমি অর্থহীন castালাই যোগ করার বিন্দুটি দেখতে পাচ্ছি না। আপনি কি int x = (int) 12;কেবল বিষয়গুলি পরিষ্কার করার জন্যই করেন?
বিনোদন

22
@ এনএম যদি স্পষ্টভাবে একটি অকার্যকর পয়েন্টারটি "বাগ" সমাধানে সহায়তা করে, আপনি সম্ভবত সংজ্ঞায়িত আচরণের মুখোমুখি হবেন যার অর্থ সম্ভবত প্রশ্নটির প্রোগ্রামটির চেয়ে আরও খারাপ, অনাবৃত ত্রুটি রয়েছে যা আপনি এখনও চালাতে পারেননি। এবং একদিন, একটি শীতের শীতের সন্ধ্যায়, আপনি কাজ থেকে ঘরে ফিরে আপনার গিটহাব পৃষ্ঠাটি বন্যার সাথে ব্যবহারকারীদের নাক থেকে বেরিয়ে আসার অভিযোগের প্রতিবেদন সহ বন্যার সন্ধান পেয়ে যাবেন
ব্র্যাডেন বেস্ট

11
@ আনউইন্ড এমনকি আমিও আপনার সাথে একমত, (int)12তুলনামূলক নয়। 12 এটি একটি int, castালাই কিছু করেন না। এর প্রতিক্রিয়া malloc()হল void *, পয়েন্টার টাইপকে কাস্ট করা হয়নি। (যদি তা না হয় void *। সুতরাং উপমা থেকে (int)12হবে (void*)malloc(…)কি কেউ কিছু আলোচনা হয়।)
আমিন নেগাম-আওয়াদ

376

সি তে, আপনাকে এর ফেরতের মান castালাই করার দরকার নেই malloc। ফিরে আসা mallocশূন্যের পয়েন্টারটি স্বয়ংক্রিয়ভাবে সঠিক ধরণের রূপান্তরিত হয়। তবে আপনি যদি নিজের কোডটি সি ++ কম্পাইলারের সাথে সংকলিত করতে চান তবে একটি কাস্ট প্রয়োজন। সম্প্রদায়ের মধ্যে একটি পছন্দসই বিকল্প হ'ল নিম্নলিখিতটি ব্যবহার করা:

int *sieve = malloc(sizeof *sieve * length);

যা আপনাকে যদি কখনও এর ধরণটি পরিবর্তন করে তবে অভিব্যক্তির ডানদিকে পরিবর্তন করার বিষয়ে চিন্তাভাবনা থেকে মুক্তি দেয় sieve

বর্ণগুলি খারাপ, যেমনটি লোকেরা নির্দেশ করেছে। বিশেষত পয়েন্টার কাস্ট।


70
@ এমকেজেড আমি যুক্তি দিয়েছি যে malloc(length * sizeof *sieve)এটি দেখতে sizeofভেরিয়েবলের মতো দেখায় - তাই আমার মনে malloc(length * sizeof(*sieve))হয় আরও পড়া যায়।
মাইকেল অ্যান্ডারসন

21
এবং malloc(length * (sizeof *sieve))আরও পাঠযোগ্য। এই প্রোগ্রামটিতে।
টবি স্পিড

18
@ মিশেল অ্যান্ডারসন ()ইস্যুটি একপাশে রেখে নোট করুন, আপনার প্রস্তাবিত স্টাইলটি অর্ডার পরিবর্তন করেছে, বিবেচনা করুন, এলিমেন্ট গণনাটি কখন গণনা করা হয়, বিবেচনা করুন length*width, sizeofএই ক্ষেত্রে প্রথমটি বীমায় রাখলে কমপক্ষে size_tগণিত দিয়ে গুণ করা হবে । তুলনা malloc(sizeof( *ptr) * length * width)বনাম malloc(length * width * sizeof (*ptr))- 2nd ওভারফ্লো পারে length*widthযখন width,lengthছোট ধরনের যে size_t
chux - মনিকা

3
@ চাক্স এটি সুস্পষ্ট নয়, তবে উত্তরটি এমনভাবে সম্পাদনা করা হয়েছে যাতে আমার মন্তব্যটি কম প্রাসঙ্গিক - মূল পরামর্শটি ছিলmalloc(sizeof *sieve * length)
মাইকেল অ্যান্ডারসন

12
সি সি ++ নয়। তারা যে ভান করে চূড়ান্তভাবে বিভ্রান্তি এবং দু: খিত হতে হবে। আপনি যদি সি ++ ব্যবহার করেন তবে সি-স্টাইলের কাস্টটিও খারাপ (যদি আপনি খুব পুরানো সি ++ সংকলক ব্যবহার না করেন)। এবং static_cast>()(বা reinterpret_cast<>()) সি এর কোনও উপভাষার সাথে সামঞ্জস্যপূর্ণ নয়
ডেভিড সি

349

আপনি কি নিক্ষেপ, কারণ:

  • এটি আপনার কোডকে সি এবং সি ++ এর মধ্যে আরও পোর্টেবল করে তোলে এবং এসও অভিজ্ঞতা হিসাবে, অনেকগুলি প্রোগ্রামার দাবি করেন যে তারা যখন সি -++ (বা সি প্লাস স্থানীয় সংকলক এক্সটেনশানগুলি) লিখছেন তখন তারা সিটিতে লিখছেন।
  • এটি করতে ব্যর্থ হওয়া একটি ত্রুটিটি আড়াল করতে পারে : type *বিপরীতে লিখতে গেলে বিভ্রান্তির সমস্ত SO উদাহরণ নোট করুন type **
  • ধারণাটি যে এটি আপনাকে #includeকোনও উপযুক্ত শিরোলেখ ফাইলটিতে ব্যর্থ করে তা গাছগুলির জন্য বনকে মিস করে । এটি একই বলেছিলেন যে "আপনি প্রোটোটাইপগুলি না দেখে कंপাইলারকে অভিযোগ করতে জিজ্ঞাসা করতে ব্যর্থ হয়েছেন সে সম্পর্কে চিন্তিত হবেন না - যে pesky stdlib.h মনে রাখা সত্যিকারের গুরুত্বপূর্ণ বিষয়!"
  • এটি একটি অতিরিক্ত জ্ঞানীয় ক্রস-চেককে বাধ্য করে । এটি সেই পাথরের কাঁচা আকারের জন্য পাথের গাণিতিকের ঠিক পরে (কথিত) কাঙ্ক্ষিত প্রকারটি রাখে। আমি বাজি ধরছি আপনি এমন একটি সমীক্ষা করতে পারেন যা দেখায় যে malloc()কোনও কাস্ট আছে সেখানে বাগগুলি খুব দ্রুত ধরা পড়ে। দাবি হিসাবে, টীকাগুলি হ্রাস বাগগুলি প্রকাশ করে ot
  • নিজেকে এমনভাবে পুনরাবৃত্তি করা যাতে মেশিনটি পরীক্ষা করতে পারে তা প্রায়শই দুর্দান্ত ধারণা। প্রকৃতপক্ষে, এটি একটি দৃser়তা যা হয়, এবং castালাইয়ের এই ব্যবহারটি একটি দৃ as়তা। টিউরিং এত বছর আগে এই ধারণাটি নিয়ে আসার পরেও কোড সঠিক হওয়ার জন্য আমাদের কাছে থাকা সাধারণ কৌশলগুলি এখনও জোর দিয়েছিল।

39
@ulidtko আপনি জানেন না এমন ক্ষেত্রে, কোড লেখা সম্ভব যা সি এবং সি ++ উভয়ই সংকলিত করে iles আসলে বেশিরভাগ শিরোনামের ফাইলগুলি এ জাতীয় হয় এবং এগুলিতে প্রায়শই কোড থাকে (ম্যাক্রো এবং ইনলাইন ফাংশন)। উভয়ই সংকলন করার জন্য একটি ফাইল .c/ .cppফাইল থাকা খুব বেশি কার্যকর নয়, তবে একটি ক্ষেত্রে throwসি ++ সংকলক (তবে return -1;সি সংকলক বা যখন যা কিছু সংকলন করা হয়) সংকলনের সময় সি ++ সমর্থন যুক্ত করছে ।
হাইড

37
কারও কাছে যদি শিরোনামে মলোক কল থাকে তবে আমি প্রভাবিত হব না, #ifdef __cplusplus এবং বহিরাগত "C" {{এই কাজের জন্য, অতিরিক্ত ক্যাসটে যোগ না করে।
পলম

15
ঠিক আছে, পয়েন্ট 1 অপ্রাসঙ্গিক, যেহেতু সি! = সি ++, অন্যান্য পয়েন্টগুলিও তুচ্ছ, যদি আপনি আপনার কলটিতে ভেরিয়েবল ব্যবহার করেনmalloc : char **foo = malloc(3*sizeof(*foo));যদি পুরো পূর্ণ-প্রমাণ হয়: 3 পয়েন্টারে চর পয়েন্টার। তারপরে লুপ করুন এবং করুন foo[i] = calloc(101, sizeof(*(foo[i])));। 101 টি অক্ষরের অ্যারে বরাদ্দ করুন, সুন্দরভাবে জিরোতে আরম্ভ করা হয়েছে। কোনও কাস্টের দরকার নেই। এই বিষয়ে ঘোষণাপত্রটি unsigned charবা অন্য কোনও ধরণের পরিবর্তন করুন এবং আপনি এখনও ভাল
এলিয়াস ভ্যান ওটেজেম

33
আমি যখন চেষ্টা করেছি আমি পেয়েছিলাম, সেখানে আসে! চমত্কার উত্তর। স্ট্যাকওভারফ্লোতে এটিই প্রথমবার যে আমি দুটি বিপরীত উত্তর +1 করলাম! +1 না, আপনি কাস্ট করেন না, এবং +1 হ্যাঁ, আপনি কাস্ট করেন! হাঃ হাঃ হাঃ. আপনি ছেলেরা ভয়ঙ্কর। এবং আমার এবং আমার ছাত্রদের জন্য, আমি আমার মন তৈরি করেছি: আমি নিক্ষেপ করি। কাস্টিংয়ের সময় শিক্ষার্থীরা যে ধরণের ত্রুটি করে তা আরও সহজে চিহ্নিত হয় ted
ডাঃ বেকো

14
@ লুশেনকো: নিজেকে এমনভাবে পুনরাবৃত্তি করা যা মেশিন দ্বারা বৈধ হওয়া যায় না বা স্থানীয় পরিদর্শন দ্বারা খারাপ by এ জাতীয় উপায়ে যাচাই করা যায় এমন উপায়ে নিজেকে পুনরাবৃত্তি করা কম খারাপ। প্রদত্ত struct Zebra *p; ... p=malloc(sizeof struct Zebra);, malloc পি এর ধরণ সম্পর্কে দ্বৈতকরণ তথ্য এড়াতে পারবেন না, তবে সংকলক বা স্থানীয় কোড পরিদর্শন উভয়ই কোনও সমস্যা সনাক্ত করতে পারে না যদি একটি প্রকার পরিবর্তন হয় তবে অন্যটি তা করেনি। কোডটি পরিবর্তন করুন p=(struct Zebra*)malloc(sizeof struct Zebra);এবং সংকলকটি যদি কাস্টের ধরণটি মেলে না p, এবং লোকাল পরিদর্শনটি প্রকাশ পাবে ...
সুপারক্যাট

170

অন্যরা যেমন বলেছে, এটি সি এর জন্য প্রয়োজন হয় না, তবে সি ++ এর জন্য প্রয়োজনীয়। যদি আপনি মনে করেন যে আপনি যে কোনও কারণে সি ++ কম্পাইলারের সাথে আপনার সি কোডটি সংকলন করতে চলেছেন তবে আপনি এর পরিবর্তে ম্যাক্রো ব্যবহার করতে পারেন, যেমন:

#ifdef __cplusplus
# define NEW(type, count) ((type *)calloc(count, sizeof(type)))
#else
# define NEW(type, count) (calloc(count, sizeof(type)))
#endif

এইভাবে আপনি এখনও এটি খুব কমপ্যাক্ট পদ্ধতিতে লিখতে পারেন:

int *sieve = NEW(int, 1);

এবং এটি সি এবং সি ++ এর জন্য সংকলন করবে।


17
যেহেতু আপনি যে কোনও উপায়ে ম্যাক্রো ব্যবহার করছেন তাই আপনি কেন newসি ++ এর সংজ্ঞা ব্যবহার করবেন না ?
হোসাম অলি

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

8
স্মৃতি মুক্ত করে এমন আপনি না হলেও আপনি ব্যবহার করছেন এমন একটি সি লাইব্রেরি ইত্যাদি উল্লেখ না করা, কোনও লাভ ছাড়াই সম্ভাব্য অনেক সমস্যা।
কুইনমার্স

86
@ হোসাম: হ্যাঁ, এটি অবশ্যই আছে। আপনি ব্যবহার করেন তাহলে newআপনি ব্যবহার করা আবশ্যক deleteএবং যদি আপনি ব্যবহার malloc()আপনার অবশ্যই free()। এগুলি কখনও মিশ্রিত করবেন না।
গ্রিম পেরো

17
যদি কেউ এই পদ্ধতি অবলম্বন করতে চলেছে তবে ম্যাক্রো কল NEWকরা সম্ভবত একটি খারাপ ধারণা কারণ সম্পদটি কখনই delete(বা DELETE) ব্যবহার করে ফেরানো হয় না তাই আপনি নিজের শব্দভাণ্ডার মিশ্রণ করছেন। পরিবর্তে, নামকরণ করা MALLOC, বা বরং CALLOCএই ক্ষেত্রে, আরও অর্থবোধ করতে পারে।
মাহ

139

উইকিপিডিয়া থেকে :

Ingালাই সুবিধা

  • কাস্ট সহ অন্তর্ভুক্ত কোনও সি প্রোগ্রাম বা ফাংশনকে সি ++ হিসাবে সংকলনের অনুমতি দিতে পারে।

  • কাস্ট মেলোকের 1989 পূর্ববর্তী সংস্করণগুলির জন্য অনুমতি দেয় যা মূলত একটি চর * ফেরত দেয়।

  • Ingালাই গন্তব্য পয়েন্টার ধরণের পরিবর্তন হওয়া উচিত, নির্দিষ্ট আকারের আকারের ক্ষেত্রে অসঙ্গতিগুলি সনাক্ত করতে বিকাশকারীকে সহায়তা করতে পারে, বিশেষত যদি পয়েন্টারটি ম্যালোক () কল থেকে দূরে ঘোষিত হয় (যদিও আধুনিক সংকলক এবং স্থির বিশ্লেষকরা কাস্টের প্রয়োজন ছাড়াই এই জাতীয় আচরণ সম্পর্কে সতর্ক করতে পারেন))

Ingালাই অসুবিধা

  • এএনএসআই সি স্ট্যান্ডার্ডের অধীনে castালাই অপ্রয়োজনীয়।

  • কাস্ট যোগ করা শিরোনাম অন্তর্ভুক্ত করতে ব্যর্থতা মাস্ক করতে পারে stdlib.h, যেখানে ম্যালোকের জন্য প্রোটোটাইপ পাওয়া যায়। ম্যালোকের জন্য প্রোটোটাইপের অনুপস্থিতিতে, মানটির প্রয়োজন হয় যে সি সংকলকটি ম্যালোক একটি ইনট প্রদান করে। যদি কোনও castালাই না থাকে, যখন এই পূর্ণসংখ্যটি পয়েন্টারটিতে বরাদ্দ করা হয় তখন একটি সতর্কতা জারি করা হয়; তবে, নিক্ষেপ সহ, এই সতর্কতাটি তৈরি করা হয়নি, একটি বাগ লুকিয়ে। নির্দিষ্ট আর্কিটেকচার এবং ডেটা মডেলগুলিতে (যেমন 64৪-বিট সিস্টেমে এলপি ,৪, যেখানে দীর্ঘ এবং পয়েন্টারগুলি 64৪-বিট এবং ইন্টি 32-বিট হয়), এই ত্রুটিটি প্রকৃতপক্ষে অপরিজ্ঞাত আচরণের কারণ হতে পারে, কারণ সুস্পষ্টভাবে ঘোষিত মল্লোক একটি 32- বিট মান যেখানে প্রকৃত সংজ্ঞায়িত ফাংশন একটি 64৪-বিট মান দেয়। কলিং কনভেনশন এবং মেমরি লেআউটের উপর নির্ভর করে এর ফলে স্ট্যাক স্ম্যামিং হতে পারে। আধুনিক সংকলকগুলিতে এই সমস্যাটি নজরে যাওয়ার সম্ভাবনা কম less যেহেতু তারা অভিন্নভাবে সতর্কবার্তা দেয় যে একটি অঘোষিত ফাংশন ব্যবহার করা হয়েছে, তাই একটি সতর্কতা এখনও উপস্থিত হবে। উদাহরণস্বরূপ, জিসিসির ডিফল্ট আচরণ হ'ল একটি সতর্কতা দেখানো হয়েছে যা "বিল্ট-ইন ফাংশনটির বেমানান অন্তর্নিহিত ঘোষণাপত্র" পড়বে যা নির্ধারিত থাকুক না কেন।

  • যদি তার ঘোষণাপত্রে পয়েন্টারের ধরণের পরিবর্তন করা হয়, তবে ম্যালোককে ডেকে কাস্ট করা হয় এমন সমস্ত লাইনও পরিবর্তন করতে হবে।

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

অর্থাত্: আপনার যদি সি প্রোগ্রামটি সি ++ হিসাবে সংকলন করতে হয় তবে এটি পৃথক ভাষা হলেও ব্যবহারের ফলাফল অবশ্যই আপনাকে দিতে হবে malloc


1
" কাস্টিং গন্তব্য পয়েন্টার ধরণের পরিবর্তন হওয়া উচিত, বিশেষত যদি malloc()কলটি থেকে দূরে ঘোষিত হয় " এর অর্থ কী? আপনি একটি উদাহরণ দিতে পারেন?
স্পিক্যাট্রিক্স

3
@ কুলগুই: অন্য উত্তরের আগের মন্তব্য দেখুন । তবে মনে রাখবেন যে p = malloc(sizeof(*p) * count)আইডিয়ামটি স্বয়ংক্রিয়ভাবে ধরণের পরিবর্তনগুলি গ্রহণ করে, তাই আপনাকে সতর্কতা পেতে এবং কোনও পরিবর্তন করতে হবে না। সুতরাং এটি আসল সুবিধা নয় বনাম-কাস্টিংয়ের জন্য সেরা বিকল্প নয়।
পিটার কর্ডস

7
এটি যথাযথ উত্তর: এখানে বিভিন্ন উপকারিতা এবং বুদ্ধি রয়েছে, এবং এটি স্বাদের বিষয়টিতে ফোটে (যদি কোডটি সি ++ হিসাবে সংকলিত না হয় - তবে নিক্ষিপ্ত বাধ্যতামূলক)।
পিটার - মনিকা

3
পয়েন্ট 3 হ'ল মোটা, যেহেতু যদি এটির ঘোষণায় পয়েন্টারের ধরণটি পরিবর্তন করা হয় তবে ম্যালোক, রিলোক এবং ফ্রি ইনোলোভিংয়ের প্রতিটি উদাহরণ পরীক্ষা করা উচিত। Ingালাই আপনাকে ঠিক তা করতে বাধ্য করবে।
মিশাল রায়

104

সিতে আপনি স্পষ্টতই একটি voidপয়েন্টারকে অন্য কোনও ধরণের পয়েন্টারে রূপান্তর করতে পারেন , সুতরাং একটি কাস্ট প্রয়োজন হয় না। একটি ব্যবহার করা নৈমিত্তিক পর্যবেক্ষককে পরামর্শ দিতে পারে যে কারও কারও প্রয়োজন হওয়ার কারণ রয়েছে যা বিভ্রান্তিকর হতে পারে।


100

আপনি ম্যালোকের ফলাফলটি নিক্ষেপ করবেন না, কারণ এটি করা আপনার কোডে অর্থহীন বিশৃঙ্খলা যুক্ত করে।

লোকেরা কেন ম্যালোকের ফলাফল দেয় তার সর্বাধিক সাধারণ কারণ হ'ল সি ভাষা কীভাবে কাজ করে সে সম্পর্কে তারা অনিশ্চিত। এটি একটি সতর্কতা চিহ্ন: যদি কোনও নির্দিষ্ট ভাষা প্রক্রিয়া কীভাবে কাজ করে তা আপনি জানেন না, তবে অনুমান করবেন না । এটি সন্ধান করুন বা স্ট্যাক ওভারফ্লো সম্পর্কে জিজ্ঞাসা করুন।

কিছু মন্তব্য:

  • একটি অকার্যকর পয়েন্টারটি সুস্পষ্ট কাস্ট (সি 11 6.3.2.3 এবং 6.5.16.1) ব্যতীত অন্য কোনও পয়েন্টার ধরণের / থেকে রূপান্তরিত হতে পারে।

  • সি ++ তবে void*অন্য পয়েন্টার প্রকারের মধ্যে অন্তর্নিহিত কাস্টের অনুমতি দেবে না । সুতরাং সি ++ এ, কাস্টটি সঠিক হত। আপনি যদি সি ++ তে প্রোগ্রাম করেন তবে আপনার ব্যবহার করা উচিতnew এবং ম্যালোক () নয়। এবং আপনার কোনও সি ++ সংকলক ব্যবহার করে সি কোডটি কখনই সংকলন করা উচিত নয়।

    যদি আপনাকে একই উত্স কোডের সাহায্যে সি এবং সি ++ উভয়ই সমর্থন করতে হয় তবে পার্থক্য চিহ্নিত করতে সংকলক সুইচগুলি ব্যবহার করুন। উভয় ভাষার মান একই কোড দিয়ে সেট করার চেষ্টা করবেন না, কারণ তারা সামঞ্জস্যপূর্ণ নয়।

  • আপনি যদি শিরোনাম অন্তর্ভুক্ত করতে ভুলে গেছেন বলে কোনও সি সংকলক যদি কোনও ফাংশন খুঁজে না পায় তবে আপনি সে সম্পর্কে একটি সংকলক / লিঙ্কারের ত্রুটি পাবেন। সুতরাং যদি আপনি <stdlib.h>এটি কোনও বড় কথা অন্তর্ভুক্ত করতে ভুলে যান তবে আপনি আপনার প্রোগ্রামটি তৈরি করতে সক্ষম হবেন না।

  • প্রাচীন সংকলকগুলিতে যা 25 বছরেরও বেশি পুরানো স্ট্যান্ডার্ডের একটি সংস্করণ অনুসরণ করে, অন্তর্ভুক্ত <stdlib.h>করতে ভুলে গেলে বিপজ্জনক আচরণের ফলস্বরূপ। কারণ সেই প্রাচীন স্ট্যান্ডার্ডে, দৃশ্যমান প্রোটোটাইপ ব্যতীত ফাংশনগুলি প্রত্যাবর্তন প্রকারকে স্পষ্টভাবে রূপান্তরিত করে int। সুস্পষ্টভাবে malloc থেকে ফলাফল কাস্ট করা তখন এই বাগটি লুকিয়ে রাখবে।

    তবে এটি সত্যিই একটি নন-ইস্যু। আপনি 25 বছরের পুরানো কম্পিউটার ব্যবহার করছেন না, তাহলে আপনি কেন 25 বছরের পুরানো সংকলক ব্যবহার করবেন?


9
"অর্থহীন বিশৃঙ্খলা" বরখাস্ত হাইপারবোলে যা ইতিমধ্যে আপনার সাথে একমত নয় এমন কাউকে বোঝানোর যে কোনও সম্ভাবনা লাইনচ্যুত করে। একটি certainlyালাই অবশ্যই অর্থহীন নয়; রন বার্ক এবং কাজ এর উত্তরগুলি কাস্টিংয়ের পক্ষে যুক্তি দেয় যা আমি খুব সম্মত agree আপনার উদ্বেগগুলির তুলনায় সেই উদ্বেগগুলি বেশি ওজন কিনা তা জিজ্ঞাসা করার পক্ষে যুক্তিসঙ্গত প্রশ্ন। আমার কাছে, আপনার উদ্বেগগুলি তাদের তুলনায় অপেক্ষাকৃত ছোট দেখায়।
ডন হ্যাচ

"একটি অকার্যকর পয়েন্টার স্পষ্টতালীন castালাই ব্যতীত অন্য কোনও পয়েন্টার ধরণের / থেকে রূপান্তর করা যায়" 6.3.2.3 দ্বারা সমর্থিত নয়। সম্ভবত আপনি "কোনও বস্তুর ধরণের পয়েন্টার" ভাবছেন? "অকার্যকর পয়েন্টার" এবং "একটি ফাংশনটির পয়েন্টার" এত সহজে রূপান্তরিত হয় না।
chux - মনিকা পুনরায় ইনস্টল করুন

প্রকৃতপক্ষে উল্লেখটি অসম্পূর্ণ ছিল। "ফলস্বরূপ" এর জন্য প্রাসঙ্গিক অংশটি হ'ল সহজ অ্যাসাইনমেন্টের নিয়ম .5.৫.১6.১। "একটি অপারেন্ড হ'ল একটি অবজেক্টের ধরণের নির্দেশক এবং অন্যটি শূন্যতার যোগ্য বা অযোগ্য সংস্করণের পয়েন্টার"। আমি সম্পূর্ণতার জন্য উত্তরে এই উল্লেখটি যুক্ত করেছি।
লন্ডিন

91

সিতে আপনি void *অন্য কোনও (ডেটা) পয়েন্টার থেকে অন্তর্নিহিত রূপান্তর পান ।


6
@ জেনস: ঠিক আছে, সম্ভবত আরও সঠিক শব্দযুক্ত শব্দটি হ'ল "অন্তর্নিহিত রূপান্তর"। ভাসমান পয়েন্ট এক্সপ্রেশনতে ইন্টিগ্রাল ভেরিয়েবলের ব্যবহারের মতো।
EFraim

@ ইফ্রাইম এর ফলস্বরূপ একটি কাস্ট এবং এর মধ্যে অন্তর্নিহিত ফলাফল আসবে।
ম্যাড পদার্থবিদ

71

ফেরত দেওয়া মান ingালাই malloc() এখনই প্রয়োজনীয় নয় তবে আমি একটি পয়েন্ট যোগ করতে চাই যা দেখে মনে হয় যে কেউই উল্লেখ করেনি:

প্রাচীন দিনগুলিতে, যেহেতু, এএনএসআই সিvoid * সাধারণত জেনেরিক ধরণের পয়েন্টার হিসাবে সরবরাহ করে তার আগে char *এই জাতীয় ব্যবহার। সেক্ষেত্রে theালাই সংকলক সতর্কতা বন্ধ করতে পারে।

তথ্যসূত্র: সি এফএকিউ


2
সংকলক সতর্কতা বন্ধ করা একটি খারাপ ধারণা।
অ্যালবার্ট ভ্যান ডার হোর্স্ট

8
@ অ্যালবার্টভান্ডার হার্স্ট আপনি যদি সতর্কতা অবলম্বন করার জন্য সতর্কতা অবলম্বন করার জন্য সঠিক সমস্যাটি সমাধান করে থাকেন তবে তা নয়।
ড্যান বেচার্ড

@ ড্যান সঠিক সমস্যার সমাধানের মাধ্যমে যদি চর * এর পরিবর্তে আধুনিক এএনএসআই সি টাইপগুলি ফিরিয়ে আনার জন্য সাব্রোটিনের পুনর্লিখনের অর্থ হয় তবে আমি সম্মত। আমি এই সংকলকটি বন্ধ করে বলব না। সম্ভাব্য সমস্যাগুলি সন্ধানের জন্য প্রতিটি সংশোধনীর সাহায্যে তাদের পরিবর্তে কোনও সংকলক সতর্কতা নেই বলে জোর দিয়েছিলেন এমন ম্যানেজারগুলিকে ছেড়ে দেবেন না। গ্রোয়েটজেস অ্যালবার্ট
আলবার্ট ভ্যান ডার হোর্স্ট

53

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

সম্পাদনা: ingালাইয়ের একটি নির্দিষ্ট পয়েন্ট রয়েছে। আপনি অ্যারে স্বরলিপি ব্যবহার করার সময়, উত্পন্ন কোডটি জানতে হবে যে পরবর্তী উপাদানটির শুরুতে পৌঁছাতে কয়টি মেমোরি জায়গা রয়েছে, এটি কাস্টিংয়ের মাধ্যমে অর্জন করা হয়েছে। এইভাবে আপনি জানেন যে একটি ডাবলের জন্য আপনি 8 বাইট এগিয়ে যান যখন আপনি কোন ইন্টের জন্য যান 4 এবং আরও অনেক কিছু। সুতরাং আপনি যদি পয়েন্টার স্বরলিপি ব্যবহার করেন তবে এর কোনও প্রভাব নেই, অ্যারে স্বরলিপিতে এটি প্রয়োজনীয় হয়ে ওঠে।


3
ইতিমধ্যে উল্লিখিত হিসাবে বাদে, কাস্টগুলি বাগগুলি লুকিয়ে রাখতে পারে এবং সংকলক বা স্ট্যাটিক বিশ্লেষককে বিশ্লেষণ করতে কোডটিকে আরও শক্ত করে তুলবে।
লন্ডিন

2
"মূলত কাস্টিং এটি কীভাবে কাজ করে তাতে কোনও পরিবর্তন হবে না"। মিলে যাওয়ার ধরণে কাস্টিং কোনও পরিবর্তন করা উচিত নয়, তবে ভেরের ধরণের পরিবর্তন এবং কাস্টটি আর মিলবে না, সমস্যাগুলি দেখা দিতে পারে? আইডাব্লুও, .ালাই এবং ভার টাইপ সিঙ্কে রাখতে হবে - রক্ষণাবেক্ষণের কাজের দ্বিগুণ।
chux - মনিকা পুনরায় ইনস্টল করুন

আমি দেখতে পাচ্ছি কেন অধ্যাপকরা কাস্টিং পছন্দ করেন। Ingালাই একটি শিক্ষামূলক দৃষ্টিকোণ থেকে কার্যকর হতে পারে যেখানে এটি প্রশিক্ষকের তথ্যের সাথে যোগাযোগ করে এবং ছাত্র কোডটি বজায় রাখার প্রয়োজন হয় না - এর থ্রো-অ্যাওড কোড। তবুও কোডিং, পিয়ার-রিভিউ এবং রক্ষণাবেক্ষণের দৃষ্টিভঙ্গি p = malloc(sizeof *p * n);থেকে এত সহজ এবং ভাল।
chux - মনিকা পুনরায় ইনস্টল করুন

53

ফলাফলগুলি দেওয়া বাধ্যতামূলক নয় malloc, যেহেতু এটি প্রত্যাবর্তন করে void*এবং void*কোনও কোনও ডেটাটাইপের দিকে নির্দেশ করা যেতে পারে।


34

একটি শূন্য পয়েন্টার একটি জেনেরিক অবজেক্ট পয়েন্টার এবং সি একটি শূন্য পয়েন্টার টাইপ থেকে অন্য প্রকারের মধ্যে অন্তর্নিহিত রূপান্তরকে সমর্থন করে, সুতরাং এটি স্পষ্টভাবে টাইপকাস্ট করার দরকার নেই।

তবে আপনি যদি একই কোডটি সি ++ প্ল্যাটফর্মে পুরোপুরি সামঞ্জস্যপূর্ণ কাজ করতে চান, যা অন্তর্নিহিত রূপান্তরকে সমর্থন করে না, আপনার টাইপকাস্টিং করা দরকার, তাই এটি সমস্ত ব্যবহারের উপর নির্ভর করে।


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

1
"একটি শূন্য পয়েন্টার একটি জেনেরিক পয়েন্টার" -> "একটি শূন্য পয়েন্টার একটি জেনেরিক অবজেক্ট পয়েন্টার"। ফাংশন পয়েন্টার আকারগুলি অতিক্রম করতে পারে void *, এইভাবে void *কোনও ফাংশন পয়েন্টার ভালভাবে সঞ্চয় করতে অপর্যাপ্ত।
chux - মনিকা পুনরায় ইনস্টল করুন

আমার এই লাইনের উদ্দেশ্য একই ছিল তবে যাইহোক পরামর্শের জন্য @ chux ধন্যবাদ।
চেষ্টা করুন

33

এই কি GNU C লাইব্রেরি রেফারেন্স ম্যানুয়াল বলেছেন:

আপনি ফলাফলকে mallocকোনও পয়েন্টার ছাড়াই কোনও পয়েন্টার ভেরিয়েবলের মধ্যে সংরক্ষণ করতে পারেন , কারণ আইএসও সি প্রয়োজনীয়তার সময় স্বয়ংক্রিয়ভাবে টাইপটিকে void *অন্য প্রকারের পয়েন্টারে রূপান্তরিত করে । তবে অ্যাসাইনমেন্ট অপারেটর ব্যতীত অন্য প্রসঙ্গে কাস্ট করা প্রয়োজনীয় বা আপনি যদি নিজের কোডটি চিরায়ত সিতে চালিত করতে চান if

এবং প্রকৃতপক্ষে আইএসও সি 11 মানক (p347) তাই বলেছে:

পয়েন্টারটি ফিরে আসে যদি বরাদ্দ সফল হয় যথাযথভাবে প্রান্তিককরণ করা হয় যাতে এটি কোনও বিন্দুতে মৌলিক প্রান্তিককরণের প্রয়োজনীয়তা সহ যে কোনও ধরণের অবজেক্টকে নির্ধারিত হতে পারে এবং তারপরে বরাদ্দকৃত স্থানটিতে এই জাতীয় অবজেক্ট বা এই জাতীয় বস্তুর অ্যারে অ্যাক্সেস করতে ব্যবহৃত হয় স্পেস স্পষ্টভাবে deallocated হয়)


31

প্রত্যাবর্তিত প্রকারটি অকার্যকর *, যা পছন্দসই হওয়ার জন্য পছন্দসই ধরণের ডেটা পয়েন্টারটিতে ফেলে দেওয়া যেতে পারে।


1
void* পছন্দসই ধরণের কাস্ট করা যেতে পারে, তবে এটি করার দরকার নেই কারণ এটি স্বয়ংক্রিয়ভাবে রূপান্তরিত হবে। সুতরাং castালাই প্রয়োজনীয় নয় এবং প্রকৃতপক্ষে উচ্চ-স্কোরিং উত্তরে উল্লিখিত কারণে অনাকাঙ্ক্ষিত।
টবি স্পিড

তবে কেবলমাত্র যদি আপনার "ফ্লাইয়ের উপরে" এটির অধ্যাপনা করা দরকার, আপনি যদি পরিবর্তে কোনও পরিবর্তনশীল তৈরি করেন তবে এটি নিরাপদে এবং স্বয়ংক্রিয়ভাবে ভেরিয়েবলের কার্যকর ধরণের রূপান্তরিত হবে, castালাই ছাড়াই (সি)।
ফেরেরেজি

28

সি ভাষায়, একটি শূন্য পয়েন্টার যে কোনও পয়েন্টারকে বরাদ্দ করা যেতে পারে, এজন্য আপনাকে কোনও প্রকারের castালাই ব্যবহার করা উচিত নয়। আপনি যদি "টাইপ নিরাপদ" বরাদ্দ চান তবে আমি নিম্নলিখিত ম্যাক্রো ফাংশনগুলির সুপারিশ করতে পারি, যা আমি সর্বদা আমার সি প্রকল্পগুলিতে ব্যবহার করি:

#include <stdlib.h>
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
#define NEW(ptr) NEW_ARRAY((ptr), 1)

এগুলি জায়গায় আপনি কেবল বলতে পারেন

NEW_ARRAY(sieve, length);

অ-গতিশীল অ্যারেগুলির জন্য, তৃতীয়টি অবশ্যই ফাংশন ম্যাক্রো

#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])

যা অ্যারের লুপগুলিকে নিরাপদ এবং আরও সুবিধাজনক করে তোলে:

int i, a[100];

for (i = 0; i < LEN(a); i++) {
   ...
}

"কোনও অকার্যকর পয়েন্টার যে কোনও অবজেক্ট পয়েন্টারকে বরাদ্দ করা যেতে পারে " ফাংশন পয়েন্টারগুলি অন্য একটি বিষয়, যদিও এটি একটি নয় malloc()
chux - মনিকা পুনর্নির্ধারণ

একটি বরাদ্দ করা void*একটি ফাংশন পয়েন্টার থেকে / তথ্য হারাতে পারেন তাই "একটি অকার্যকর পয়েন্টার কোনো পয়েন্টার নির্ধারিত করা যেতে পারে," এইসব ক্ষেত্রেও কোন সমস্যা নয়। কোনও অবজেক্ট পয়েন্টার void*থেকে a নির্ধারণ malloc()করা কোনও সমস্যা নয়।
chux - মনিকা

doলুপ এখনো একটি লুপ জড়িত ম্যাক্রো যে শিরোনাম প্রশ্ন থেকে দূরে হতাশ হয় এর সাথে সম্পর্কিত মন্তব্য নেই। মন্তব্যটি সরানো হচ্ছে। এটিকে পরে নেমে যাবে।
chux -

27

এটি প্রোগ্রামিং ভাষা এবং সংকলকের উপর নির্ভর করে। আপনি যদি সিটিতে ব্যবহার mallocকরেন তবে এটি castালাই টাইপ করার দরকার নেই, কারণ এটি স্বয়ংক্রিয়ভাবে castালাই টাইপ করবে। তবে, আপনি যদি সি ++ ব্যবহার করেন তবে আপনার castালাই টাইপ করা উচিত কারণ mallocকোনও void*প্রকার ফিরে আসবে ।


1
ফাংশন ম্যালোক সি-তে একটি শূন্য পয়েন্টারও প্রদান করে তবে ভাষার নিয়মগুলি সি ++ থেকে আলাদা।
আগস্ট কার্লস্ট্রম

16

জিসিসি এবং কলং এর জন্য ব্যবহৃত লোকেরা নষ্ট হয়ে যায়। এটি সেখানে খুব ভাল কিছু নয়।

আমার বেশ কয়েক বছর ধরে বয়সের ভারসাম্যহীন হয়ে পড়েছে comp প্রায়শই সংস্থাগুলি পরিবর্তন করতে সংস্থাগুলি এবং পরিচালনাগুলি একটি অতি-রক্ষণশীল পদ্ধতি অবলম্বন করে এবং তাদের সিস্টেমে কোনও নতুন সংকলক (আরও ভাল মানের সম্মতি এবং কোড অপ্টিমাইজেশন সহ) কাজ করবে কিনা তাও পরীক্ষা করবে না । কাজের বিকাশকারীদের ব্যবহারিক বাস্তবতা হ'ল আপনি যখন কোডিং করছেন তখন আপনার ঘাঁটিগুলি আবরণ করা দরকার এবং দুর্ভাগ্যবশত, মেলোকগুলি ingালাই একটি ভাল অভ্যাস যদি আপনি নিজের কোডটিতে কোন সংকলক প্রয়োগ করতে পারেন তা নিয়ন্ত্রণ করতে পারেন না।

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

যুক্তি যে এটি বর্তমান মানের অধীনে প্রয়োজনীয় নয় তা যথেষ্ট বৈধ। কিন্তু সেই যুক্তি বাস্তব বিশ্বের বাস্তবতাকে বাদ দেয়। আমরা কোনও বিশ্বে দিনের মান অনুসারে একচেটিয়া শাসিত করি না, তবে "স্থানীয় পরিচালনার বাস্তবতা ক্ষেত্র" বলতে আমি কী পছন্দ করি তার ব্যবহারিক প্রয়োগ দ্বারা। এবং এটি বাঁকানো এবং স্থানের সময়ের চেয়ে বেশি পাকানো। :-)

YMMV।

আমি ম্যালোককে defালাই রক্ষণাত্মক অপারেশন হিসাবে ভাবার প্রবণতা করি। সুন্দর নয়, নিখুঁত নয়, তবে সাধারণত নিরাপদ। (সত্যি বলতে, আপনি যদি stdlib.h তারপর অন্তর্ভুক্ত না করেছি করেছি পথ যদি malloc ভোটদান চেয়ে বেশি সমস্যা!)।


15

আমি টাইপ সিস্টেমে কুরুচিপূর্ণ গর্তের অস্বীকৃতি প্রদর্শন করার জন্য কেবল কাস্টে রেখেছিলাম, যা নীচের স্নিপেটের মতো কোডগুলি ডায়াগনস্টিকস ছাড়াই সংকলন করতে দেয়, যদিও কোনও রূপান্তর খারাপ রূপান্তর আনতে ব্যবহৃত হয় না:

double d;
void *p = &d;
int *q = p;

আমি চাই যে এটি বিদ্যমান না (এবং এটি সি ++ তে নেই) এবং তাই আমি কাস্ট করেছি। এটি আমার স্বাদ এবং আমার প্রোগ্রামিং রাজনীতির প্রতিনিধিত্ব করে। আমি কেবল একটি পয়েন্টার castালাই করছি না, কার্যকরভাবে, একটি ব্যালট ingালাই করছি, এবং বোকামির ভূতদের বের করে দিচ্ছি । যদি আমি আসলে বোকামি ফেলে দিতে না পারি তবে কমপক্ষে আমাকে প্রতিবাদের ইঙ্গিত দিয়ে এমন করার ইচ্ছা প্রকাশ করতে দিন।

প্রকৃতপক্ষে, একটি ভাল অনুশীলন হ'ল mallocফাংশনগুলি (এবং বন্ধুরা) ফিরে আসে unsigned char *এবং মূলত void *আপনার কোডটিতে কখনও ব্যবহার না করা । আপনার যদি জেনেরিক পয়েন্টার-থেকে-যেকোন-অবজেক্টের প্রয়োজন হয় তবে একটি char *বা ব্যবহার করুন unsigned char *এবং উভয় দিকেই ক্যাসেট রয়েছে। যে এক শিথিলতায় লিপ্ত হতে পারে, তা হ'ল কাস্টের মতো memsetএবং memcpyব্যতীত ফাংশন ব্যবহার করা ।

Ingালাই এবং সি ++ সামঞ্জস্যের বিষয়ে, আপনি যদি আপনার কোডটি লিখেন যাতে এটি সি এবং সি ++ উভয় হিসাবে সংকলিত হয় (এই ক্ষেত্রে আপনাকে যদিmalloc অন্য কোনও কিছুতে নির্ধারিত করার সময় ফেরতের মান দিতে হয় void *) তবে আপনি খুব সহায়ক হতে পারেন নিজের জন্য জিনিস: আপনি কাস্টিংয়ের জন্য ম্যাক্রোগুলি ব্যবহার করতে পারেন যা সি ++ হিসাবে সংকলন করার সময় সি ++ স্টাইলের কাস্টগুলিতে অনুবাদ করে তবে সি হিসাবে সংকলন করার সময় কোনও সি কাস্টে হ্রাস করুন:

/* In a header somewhere */
#ifdef __cplusplus
#define strip_qual(TYPE, EXPR) (const_cast<TYPE>(EXPR))
#define convert(TYPE, EXPR) (static_cast<TYPE>(EXPR))
#define coerce(TYPE, EXPR) (reinterpret_cast<TYPE>(EXPR))
#else
#define strip_qual(TYPE, EXPR) ((TYPE) (EXPR))
#define convert(TYPE, EXPR) ((TYPE) (EXPR))
#define coerce(TYPE, EXPR) ((TYPE) (EXPR))
#endif

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

তারপরে, এগিয়ে যাওয়া, আপনি যদি নিয়মিত কোডটি সি ++ দিয়ে সংকলন করেন তবে এটি একটি উপযুক্ত কাস্টের ব্যবহার কার্যকর করবে। উদাহরণস্বরূপ, আপনি যদি strip_qualকেবল কোনও constবা মুছে ফেলার জন্য ব্যবহার করেন volatileতবে প্রোগ্রামটি এমনভাবে পরিবর্তিত হয় যে কোনও ধরণের রূপান্তর এখন জড়িত রয়েছে, আপনি একটি ডায়াগোনস্টিক পাবেন এবং কাঙ্ক্ষিত রূপান্তর পেতে আপনাকে ذاتগুলির সংমিশ্রণটি ব্যবহার করতে হবে।

আপনাকে এই ম্যাক্রোগুলিকে মেনে চলতে সহায়তা করার জন্য, জিএনইউ সি ++ (সি নয়!) সংকলকটির একটি সুন্দর বৈশিষ্ট্য রয়েছে: একটি alচ্ছিক ডায়াগনস্টিক যা সি স্টাইলের বর্ণের সমস্ত ঘটনার জন্য উত্পাদিত হয়।

     -ভোল্ড-স্টাইল-কাস্ট (কেবলমাত্র C ++ এবং উদ্দেশ্য-সি ++)
         যদি একটি পুরানো শৈলী (সি-স্টাইল) একটি অ-শূন্য প্রকারের কাস্ট ব্যবহার করা হয় তবে সতর্ক করুন
         একটি সি ++ প্রোগ্রামের মধ্যে। নতুন স্টাইলের কাস্ট (ডায়নামিক_কাস্ট,
         স্ট্যাটিক_কাস্ট, পুনরায় ব্যাখ্যা_কাস্ট এবং কনস্ট_কাস্ট) কম দুর্বল
         অনিচ্ছাকৃত প্রভাব এবং অনুসন্ধান করা অনেক সহজ to

যদি আপনার সি কোডটি সি ++ হিসাবে সংকলন করে, আপনি কোডটিতে ক্রাইপ হতে পারে -Wold-style-castএমন (type)কাস্টিং সিনট্যাক্সের সমস্ত উপস্থিতিগুলি খুঁজে পেতে এই বিকল্পটি ব্যবহার করতে পারেন এবং উপরের ম্যাক্রোগুলির (বা একটি থেকে উপযুক্ত পছন্দ হিসাবে এটি প্রতিস্থাপন করে এই ডায়াগনস্টিকগুলি অনুসরণ করতে পারেন) can সংমিশ্রণ, যদি প্রয়োজন হয়)।

রূপান্তরগুলির এই চিকিত্সা একটি "ক্লিন সি" তে কাজ করার একক বৃহত্তম প্রযুক্তিগত যৌক্তিকতা: সম্মিলিত সি এবং সি ++ উপভাষা, যা পরিবর্তিতভাবে এর ফেরতের মান কাস্টিংকে বৈধতা দেয় malloc


অন্যান্য নির্দেশিত হিসাবে, আমি সাধারণত সি এবং সি ++ কোড মিক্স না করার পরামর্শ দেব। তবে, যদি এটি করার উপযুক্ত কারণ থাকে তবে ম্যাক্রোগুলি কার্যকর হতে পারে।
ফিল 1970

@ ফিল 1970 এগুলি সমস্তই একত্রীকরণের উপভাষায় লেখা হয়েছে, যা সি এবং সি ++ সংকলকগুলিতে পোর্টেবল হতে পারে এবং সি ++ এর কিছু দক্ষতার সুযোগ নেয়। এটি অবশ্যই সমস্ত সি ++ হিসাবে সংকলিত হতে হবে, অথবা অন্যথায় সমস্ত সি হিসাবে সংকলিত হতে পারে
কাজ

অর্থাৎ আমি আগের মন্তব্যে যা বলতে চাইছিলাম তা হ'ল সি এবং সি ++ এর কোনও মিশ্রণ নেই। উদ্দেশ্যটি হ'ল কোডটি সমস্ত সি হিসাবে সংকলিত হয় বা সমস্ত সি ++ হিসাবে সংকলিত হয়।
কাজ

15

সি তে প্রোগ্রামিং করার সময় সবচেয়ে ভাল কাজটি যখনই সম্ভব হয়:

  1. সমস্ত সতর্কতা চালু -Wallএবং আপনার সমস্ত ত্রুটি এবং সতর্কতা সংশোধন করে একটি সি সংকলকের মাধ্যমে আপনার প্রোগ্রামটি সংকলন করুন
  2. নিশ্চিত করুন যে কোনও ভেরিয়েবল হিসাবে ঘোষণা করা হয়নি auto
  3. তারপরে -Wallএবং এর সাথে সি ++ সংকলক ব্যবহার করে এটি সংকলন করুন -std=c++11। সমস্ত ত্রুটি এবং সতর্কতা ঠিক করুন।
  4. এখন আবার সি কম্পাইলার ব্যবহার করে সংকলন করুন। আপনার প্রোগ্রামটি এখন কোনও সতর্কতা ছাড়াই সংকলন করা উচিত এবং এতে কম বাগ রয়েছে।

এই পদ্ধতিটি আপনাকে সি ++ কঠোর প্রকারের চেকিংয়ের সুবিধা নিতে দেয়, যাতে বাগের সংখ্যা হ্রাস হয়। বিশেষত, এই পদ্ধতি আপনাকে অন্তর্ভুক্ত করতে বাধ্য করে stdlib.hবা আপনি পাবেন

malloc এই সুযোগের মধ্যে ঘোষণা করা হয়নি

এবং আপনাকে ফলাফলটি কাস্ট করতে বাধ্য করে mallocবা আপনি পাবেন

থেকে অবৈধ রূপান্তর void*করতেT*

অথবা আপনার টার্গেটের ধরণটি কী।

সি ++ এর পরিবর্তে সিটিতে লেখার একমাত্র সুবিধা আমি খুঁজে পেতে পারি

  1. সি একটি ভাল নির্দিষ্ট এবিআই আছে
  2. সি ++ আরও কোড উত্পন্ন করতে পারে [ব্যতিক্রম, আরটিটিআই, টেম্পলেট, রানটাইম পলিমারফিজম]

লক্ষ্য করুন যে স্থির পলিমারফিক বৈশিষ্ট্যটির সাথে সি-এর সাধারণ উপসেটটি ব্যবহার করার সময় দ্বিতীয় ক্ষেত্রে আদর্শ ক্ষেত্রে অদৃশ্য হওয়া উচিত ।

যাঁরা সি ++ কঠোর নিয়মগুলি অসুবিধে করেন তাদের জন্য, আমরা অনুমানযুক্ত ধরণের সাথে সি ++ 11 বৈশিষ্ট্যটি ব্যবহার করতে পারি

auto memblock=static_cast<T*>(malloc(n*sizeof(T))); //Mult may overflow...

18
সি কোডের জন্য সি সংকলক ব্যবহার করুন। সি ++ কোডের জন্য একটি সি ++ সংকলক ব্যবহার করুন। কোন আইএফএস, কোনও বুট নেই। আপনার সি কোডটি সি ++ এ পুনরায় লিখন সম্পূর্ণরূপে অন্য জিনিস এবং সময় এবং ঝুঁকিগুলি - বা নাও হতে পারে।
টবির স্পিচ

2
আমি @ টবিস্পাইট পরামর্শে যুক্ত করতে চাই: আপনার যদি কোন সি ++ প্রকল্পে সি কোড ব্যবহার করতে হয় তবে আপনি সাধারণত সি কোডটি সি (যেমন gcc -c c_code.c) হিসাবে সি ++ কোড সি ++ (যেমন g++ -c cpp_code.cpp) হিসাবে সংকলন করতে পারেন এবং তারপরে সেগুলি সংযুক্ত করতে পারেন (যেমন gcc c_code.o cpp_code.oবা প্রকল্পের নির্ভরতার উপর নির্ভর করে তদ্বিপরীত)। এখন যে কোনও ভাষার কোনও দুর্দান্ত বৈশিষ্ট্য থেকে নিজেকে বঞ্চিত করার কোনও কারণ নেই ...
অটিস্টিক

1
@ ব্যবহারকারী 737373৩৯২ কেবলমাত্র "সি ++ সামঞ্জস্যপূর্ণ" হবার জন্য কোডটিতে শ্রদ্ধার সাথে কোডগুলি যুক্ত করার জন্য এটি একটি আরও বুদ্ধিমান বিকল্প।
অটিস্টিক

1
সম্ভবত এই প্রসঙ্গে মুখ্য সুবিধা হ'ল সি আপনাকে লিখতে দেয় p = malloc(sizeof(*p));যা প্রথমে পরিবর্তনের প্রয়োজন হয় না যদি pকোনও ভিন্ন ধরণের নাম পরিবর্তন হয়। Ingালাইয়ের প্রস্তাবিত "সুবিধা" হ'ল আপনি যদি pভুল টাইপ করে একটি সংকলন ত্রুটি পান তবে এটি ঠিক কাজ করলে এটি আরও ভাল।
পিটার কর্ডেস

1
আমি উল্লেখ করতে চাই যে উপযুক্ত সি ++ সংকলকগুলির অভাবযুক্ত প্ল্যাটফর্মগুলিকে লক্ষ্য করে যখন সিতে লেখার প্রয়োজন হতে পারে। ব্যতিক্রম এবং টেম্পলেটগুলি এমন বৈশিষ্ট্য যা সাধারণত সি ++ তে ছোট এবং / বা আরও কার্যকর কোড তৈরি করতে সহায়তা করে যখন সি ++ এ রানটাইম
পলিমারফিজম

15

না, আপনি ফলাফল নিক্ষেপ করেন না malloc()

সাধারণভাবে, আপনি কাস্ট বা কাস্ট করেন নাvoid *

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

তবে অপ্রয়োজনীয় পয়েন্টার কাস্টগুলি চালু না করার আরও শক্তিশালী কারণ রয়েছে :

সি-তে, একটি পয়েন্টার castালাই প্রায় সর্বদা একটি ত্রুটি । এটি নিম্নলিখিত নিয়মের কারণে ( এন 1570 -6.5 পি 7 , সি 11 এর সর্বশেষ খসড়া):

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

এটি কঠোর আলিয়াজিং বিধি হিসাবেও পরিচিত । সুতরাং নিম্নলিখিত কোডটি অপরিবর্তিত আচরণ :

long x = 5;
double *p = (double *)&x;
double y = *p;

এবং, কখনও কখনও আশ্চর্যজনকভাবে, নীচেরগুলিও পাশাপাশি:

struct foo { int x; };
struct bar { int x; int y; };
struct bar b = { 1, 2};
struct foo *p = (struct foo *)&b;
int z = p->x;

কখনও কখনও, আপনাকে পয়েন্টার castালাই করতে হবে তবে কঠোর এলিয়জিং নিয়ম দেওয়া আপনার এটির সাথে খুব সতর্কতা অবলম্বন করতে হবে। সুতরাং, আপনার কোডে কোনও পয়েন্টার কাস্টের যে কোনও ঘটনা হ'ল এমন একটি জায়গা যা এর বৈধতার জন্য আপনাকে ডাবল-চেক করতে হবে । অতএব, আপনি কখনও অপ্রয়োজনীয় পয়েন্টার castালাই লিখবেন না।

TL; ড

সংক্ষেপে: যেহেতু সি তে, কোনও পয়েন্টার কাস্টের যে কোনও ঘটনার জন্য বিশেষ নজর দেওয়ার জন্য কোডের জন্য একটি লাল পতাকা উত্থাপন করা উচিত, আপনার কখনই অপ্রয়োজনীয় পয়েন্টার কাস্টগুলি লিখতে হবে না ।


পার্শ্ব নোট:

  • এমন কিছু ক্ষেত্রে রয়েছে যেখানে আপনার আসলে একটি কাস্ট প্রয়োজন হয় void *, উদাহরণস্বরূপ যদি আপনি কোনও পয়েন্টার মুদ্রণ করতে চান:

    int x = 5;
    printf("%p\n", (void *)&x);

    The printf()ালাই এখানে প্রয়োজনীয়, কারণ বৈচিত্র্যময় ফাংশন, তাই অন্তর্নিহিত রূপান্তরগুলি কাজ করে না।

  • সি ++ তে পরিস্থিতি আলাদা। উত্সাহিত শ্রেণীর বস্তুগুলির সাথে কাজ করার সময় পয়েন্টার ধরণের কাস্টিং কিছুটা সাধারণ (এবং সঠিক)। অতএব, এটা জ্ঞান করে তোলে যে সি ++ এবং থেকে রূপান্তর void *হয় না অন্তর্নিহিত। সি ++ এর ofালাইয়ের বিভিন্ন স্বাদের পুরো সেট রয়েছে।


1
আপনার উদাহরণগুলিতে আপনি অকার্যকর * এড়ান। ডাবল * থেকে ইনট * এবং বিপরীতে কাস্টের মধ্যে পার্থক্য রয়েছে। malloc পয়েন্টেলটি বৃহত্তম স্ট্যান্ডার্ড টাইপের সাথে প্রান্তিক করে তোলে যাতে কোনও এলিয়াসিং নিয়ম ভাঙা হয় না এমনকি যদি কোনও ব্যক্তি অন্য ধরণের সাথে এই প্রান্তিক পয়েন্টার তৈরি করেও broken
পি__জে__

প্রান্তিককরণের সাথে এবং আপনার মন্তব্যের বাকী অংশের জন্য আলিয়াসিংয়ের কিছুই করার নেই - আপনি অবশ্যই বক্তব্যটি পেলেন না।

@ পিটারজে: ঠিক এক্ষেত্রে, বিন্দুটি একটি অপ্রয়োজনীয় পয়েন্টার কাস্ট এড়ানোর জন্য , সুতরাং এটি আপনাকে কোডের একটি অংশের মতো দেখাচ্ছে না যাতে আপনাকে বিশেষ মনোযোগ দিতে হবে।

কঠোর আলিয়াজিং ইস্যুটির শূন্য পয়েন্টারগুলির সাথে আসলে কোনও সম্পর্ক নেই। কঠোরভাবে অ্যালাইজিং লঙ্ঘনের কারণে বাগগুলি পেতে, আপনাকে অবশ্যই পয়েন্ট-এ ডেটা ডি-রেফারেন্স করতে হবে। এবং যেহেতু আপনি কোনও অকার্যকর পয়েন্টারটিকে ডি-রেফারেন্স করতে পারবেন না, এই জাতীয় বাগগুলি শূন্য পয়েন্টারের সাথে নয় বরং অন্য কোনও কিছুর সাথে সংজ্ঞা অনুসারে হয়।
লন্ডিন

বরং আপনাকে সমস্ত পয়েন্টার কাস্টকে নিষিদ্ধ করার জন্য একটি নিয়ম তৈরি করতে হবে। তবে কীভাবে আপনি সিরিয়ালাইজেশন রুটিন এবং হার্ডওয়্যার-সম্পর্কিত প্রোগ্রামিংয়ের মতো জিনিসগুলি লিখবেন? সি এর শক্তি যে জিনিস। আপনি কী করছেন তা যদি আপনি জানেন তবে এই জাতীয় কাস্টগুলি ঠিক আছে।
লুন্ডিন

15

আমি কাস্ট করতে পছন্দ করি তবে ম্যানুয়ালি নয়। আমার প্রিয় ব্যবহার করছে g_newএবং g_new0সাবলীল থেকে ম্যাক্রো। যদি গ্লিব ব্যবহার না করা হয় তবে আমি অনুরূপ ম্যাক্রোগুলি যুক্ত করব। এই ম্যাক্রোগুলি ধরণের সুরক্ষার সাথে কোনও আপস না করে কোড নকলকে হ্রাস করে। আপনি যদি ভুলটি টাইপ পান তবে আপনি অ-শূন্য পয়েন্টারগুলির মধ্যে একটি অন্তর্নিহিত কাস্ট পাবেন যা একটি সতর্কতা তৈরি করতে পারে (সি ++ এ ত্রুটি)। আপনি যদি শিরোনামটি সংজ্ঞায়িত করে g_newএবং এটি অন্তর্ভুক্ত করতে ভুলে যান তবে আপনি g_new0একটি ত্রুটি পাবেন। g_newএবং g_new0উভয় একই আর্গুমেন্ট গ্রহণ অসদৃশ mallocযে কম আর্গুমেন্ট লাগে calloc0শূন্য-আরম্ভের স্মৃতি পেতে কেবল যুক্ত করুন । কোডটি কোনও পরিবর্তন ছাড়াই সি ++ সংকলক দিয়ে সংকলন করা যায়।


12

Castালাই কেবল সি ++ এর জন্য নয় সি। নয় আপনি যদি সি ++ সংকলক ব্যবহার করছেন তবে আপনি এটি সি সংকলক হিসাবে আরও ভাল পরিবর্তন করতে পারেন।


9

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


11
" এটি বাধ্যতামূলক নয় - যদিও আপনাকে এটি করতেই হবে " - আমি মনে করি সেখানে একটি বৈপরীত্য রয়েছে!
টবি স্পিড

5
আমি মনে করি আপনার এই পোস্টটি কারও কাছে পড়তে হবে এবং আপনি কী বলতে চাইছেন তা তারা বুঝতে পারে কিনা see তারপরে এটি পুনর্লিখন করুন, আপনি কী বলতে চান তা পরিষ্কার করে। আপনার উত্তর কী তা আমি সত্যিই বুঝতে পারি না।
বিল উড্ডার

9

একটি শূন্য পয়েন্টার একটি জেনেরিক পয়েন্টার এবং সি একটি শূন্য পয়েন্টার টাইপ থেকে অন্য প্রকারের মধ্যে অন্তর্নিহিত রূপান্তরকে সমর্থন করে, সুতরাং এটি স্পষ্টভাবে টাইপকাস্ট করার দরকার নেই।

তবে আপনি যদি একই কোডটি সি ++ প্ল্যাটফর্মে পুরোপুরি সামঞ্জস্যপূর্ণ কাজ করতে চান, যা অন্তর্নিহিত রূপান্তরকে সমর্থন করে না, আপনার টাইপকাস্টিং করা দরকার, তাই এটি সমস্ত ব্যবহারের উপর নির্ভর করে।


9
  1. অন্যান্য বর্ণিত হিসাবে এটি সি এর জন্য প্রয়োজন হয় না, তবে সি ++ এর জন্য প্রয়োজন।

  2. কাস্ট সহ অন্তর্ভুক্ত কোনও সি প্রোগ্রাম বা ফাংশনকে সি ++ হিসাবে সংকলনের অনুমতি দিতে পারে।

  3. সিতে এটি অপ্রয়োজনীয়, কারণ অকার্যকর * স্বয়ংক্রিয়ভাবে এবং নিরাপদে অন্য কোনও পয়েন্টার প্রকারে প্রচারিত হয়।

  4. তবে আপনি যদি কাস্ট করেন তবে এটি stdlib.h অন্তর্ভুক্ত করতে ভুলে গেলে এটি একটি ত্রুটিটি আড়াল করতে পারে । এটি ক্র্যাশগুলির কারণ হতে পারে (বা আরও খারাপভাবে কোডের কিছু সম্পূর্ণ ভিন্ন অংশে ক্র্যাশ ঘটায় না)।

    কারণ stdlib.h তে ম্যালোকের প্রোটোটাইপ পাওয়া যায়। ম্যালোকের জন্য প্রোটোটাইপের অনুপস্থিতিতে, স্ট্যান্ডার্ডটির প্রয়োজন হয় যে সি সংকলকটি ম্যালোক একটি ইনট প্রদান করে। যদি কোনও castালাই না থাকে, যখন এই পূর্ণসংখ্যটি পয়েন্টারটিতে বরাদ্দ করা হয় তখন একটি সতর্কতা জারি করা হয়; তবে, নিক্ষেপ সহ, এই সতর্কতাটি তৈরি করা হয়নি, একটি বাগ লুকিয়ে।


7

সিতে ম্যালোকের ingালাই অপ্রয়োজনীয় তবে সি ++ এ বাধ্যতামূলক।

কাস্টিং সি এর কারণে অপ্রয়োজনীয়:

  • void * সি এর ক্ষেত্রে স্বয়ংক্রিয়ভাবে এবং নিরাপদে অন্য কোনও পয়েন্টার প্রকারে প্রচারিত হয়
  • আপনি অন্তর্ভুক্ত করতে ভুলে গেলে এটি একটি ত্রুটিটি আড়াল করতে পারে <stdlib.h>। এটি ক্রাশ হতে পারে।
  • যদি পয়েন্টার এবং পূর্ণসংখ্যার আকার আলাদা হয় তবে আপনি কাস্টিং দ্বারা একটি সতর্কতা লুকিয়ে রেখেছেন এবং আপনার ফিরে আসা ঠিকানার বিটগুলি হারাতে পারে।
  • যদি তার ঘোষণাপত্রে পয়েন্টারের ধরণের পরিবর্তন করা হয়, তবে যেখানে mallocডাকা এবং কাস্ট করা হয় সেখানে সমস্ত লাইনও পরিবর্তনের প্রয়োজন হতে পারে ।

অন্যদিকে, ingালাই আপনার প্রোগ্রামের বহনযোগ্যতা বাড়িয়ে তুলতে পারে। অর্থাত্ এটি একটি সি প্রোগ্রাম বা ফাংশনকে সি ++ হিসাবে সংকলন করতে দেয়।


0

আমার জন্য, নিতে বাড়ি এবং এখানে উপসংহার ভোটদান হয় mallocসম্পূর্ণই নয় সি প্রয়োজনীয় কিন্তু আপনি যদি তবে নিক্ষেপ, এটা প্রভাবিত অভ্যস্ত mallocযেমন mallocএখনও তোমাকে আপনার অনুরোধ আশীর্বাদ মেমরির স্থান বরাদ্দ হবে। অন্য বাড়িতে নিয়ে যাওয়া হ'ল লোকেরা peopleালাই করার কারণগুলি বা তার একটি কারণ এবং এটি তাদের সি বা সি ++ এ একই প্রোগ্রামটি সংকলন সক্ষম করে।

অন্যান্য কারণগুলিও হতে পারে তবে অন্যান্য কারণগুলিও প্রায় অবশ্যই তাড়াতাড়ি বা পরে আপনাকে গুরুতর সমস্যায় ফেলবে।


0

আপনি পারেন, তবে সি তে castালাই করার দরকার নেই যদি সেই কোডটি সি ++ হিসাবে সংকলিত হয় তবে আপনাকে কাস্ট করতে হবে।

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