কেন `শূন্য *` গুলি স্পষ্টভাবে সি ++ এ কাস্ট করা হয় না?


30

সি তে, void *অন্য কোনও পয়েন্টার ধরণের কাছে কাস্ট করার দরকার নেই , এটি সর্বদা নিরাপদে প্রচার করা হয়। যাইহোক, সি ++ এ, এটি ক্ষেত্রে নয়। যেমন,

int *a = malloc(sizeof(int));

সি তে কাজ করে তবে সি ++ তে নয়। (দ্রষ্টব্য: আমি জানি যে আপনি mallocসি ++ এ ব্যবহার করবেন না , বা সেই বিষয়ে ব্যবহার করা উচিত নয় newএবং পরিবর্তে স্মার্ট পয়েন্টার এবং / বা এসটিএলকে পছন্দ করা উচিত; এটি নিখুঁতভাবে কৌতূহলের বাইরে জিজ্ঞাসা করা হয়েছিল) কেন সি ++ স্ট্যান্ডার্ড এই নিষ্ক্রিয় অভিনেতাকে অনুমতি দেয় না, সি স্ট্যান্ডার্ড যখন না?


3
long *a = malloc(sizeof(int));উফফফফ, কেউ কেবল একটি প্রকার পরিবর্তন করতে ভুলে গেছে!
ডোভাল

4
@ ডোভাল: এটি সহজেই sizeof(*a)পরিবর্তে ব্যবহার করে ঠিক করা হয়েছে।
উলফপ্যাক 88

3
আমি বিশ্বাস করি @ র‌্যাচেটফ্রেকের বক্তব্যটি হ'ল সি এই নিখুঁত রূপান্তরটি করার কারণ হ'ল বরাদ্দিত ধরণেরটিতে mallocকোনও পয়েন্টার ফিরিয়ে দিতে পারে না। newসি ++ বরাদ্দ করা টাইপটিতে একটি পয়েন্টার ফেরত দেয়, তাই সঠিকভাবে লিখিত সি ++ কোডে কখনও void *কাস্ট করার কোনও দরকার নেই ।
রোবট

3
অন্যদিকে, এটি অন্য কোনও পয়েন্টার প্রকার নয়। শুধুমাত্র ডেটা-পয়েন্টারগুলি প্রয়োগ করতে হবে।
উত্সাহক 16

3
@ wolfPack88- এ আপনার ইতিহাস ভুল আছে। সি ++ ছিল void, সি করেনি না । যখন সেই কীওয়ার্ড / ধারণাটি সিতে যুক্ত হয়েছিল, তারা এটি সি এর প্রয়োজন অনুসারে পরিবর্তন করে। পয়েন্টারের ধরণগুলি একেবারে চেক করা শুরু হওয়ার কিছুক্ষণ পরেই এটি হয়েছিল । আপনি অনলাইনে কেঅ্যান্ডআর সি বর্ণনার পামফলেট বা ওয়েট গ্রুপের সি প্রাইমারের মতো সি প্রোগ্রামিং পাঠ্যের একটি ভিনটেজ অনুলিপি খুঁজে পেতে পারেন কিনা তা দেখুন । এএনএসআই সি পূর্ণ, সি -++ দ্বারা অনুপ্রাণিত বা অনুপ্রাণিত বৈশিষ্ট্যগুলির ছিল এবং কেএন্ডআর সি ছিল আরও সহজ। সুতরাং এটি আরও সঠিক যে সি ++ সি প্রসারিত সি এর সময়ে বিদ্যমান ছিল এবং আপনি যে সি জানেন তা সি ++ থেকে সরে গেছে।
জেডিগোগস

উত্তর:


39

কারণ অন্তর্নিহিত ধরণের রূপান্তরগুলি সাধারণত অনিরাপদ থাকে এবং সি ++ সি-র চেয়ে টাইপ করার ক্ষেত্রে আরও সুরক্ষিত অবস্থান নেয়।

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

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

আপনি যদি জিজ্ঞাসা করতে পারেন যে এটি কীভাবে বন্ধুত্বপূর্ণ হয় যখন এটি আপনাকে আসলে আরও বেশি টাইপ করার প্রয়োজন হয়।

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

তদ্ব্যতীত, স্পষ্টরূপে castালাই টাইপ করার অসুবিধাগুলি সমস্যা সমাধানের সময় কয়েক ঘন্টা অসুবিধার সাথে তুলনা করে ত্রুটিযুক্ত যা কোনও ভুল কার্যভারের কারণে ঘটেছিল যা সম্পর্কে আপনাকে সতর্ক করা যেতে পারে, তবে কখনও হয়নি।

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


সি মেশিন কোড থেকে মূলত এক ধাপ উপরে। আমি সি এর মতো জিনিসের জন্য ক্ষমা করতে পারি।
কিউস

8
প্রোগ্রাম (ভাষা যাই হোক না কেন) পড়তে বোঝায়। সুস্পষ্ট অপারেশনগুলি বাইরে দাঁড়িয়ে stand
ম্যাথিউ এম।

10
লক্ষ এটা এর মূল্য, যে মাধ্যমে কাস্ট void*হয় আরো কারণ উপায় নির্দিষ্ট গলি বৈশিষ্ট্য সি বাস্তবায়িত হয় সি অনিরাপদ ++ ++ একই বস্তু পয়েন্টার পয়েন্টার ধরনের উপর নির্ভর করে বিভিন্ন মান থাকতে পারে।
হাইড

@MatthieuM। খুবই সত্য. এটি যোগ করার জন্য ধন্যবাদ, এটি উত্তরের অংশ হওয়ার মতো।
মাইক নকিস

1
@ ম্যাথিউইউম: আহ, তবে আপনি সত্যিই সমস্ত কিছু স্পষ্টভাবে করতে চান না। বেশি পড়ার কারণে পাঠযোগ্যতা বাড়ানো হয় না। যদিও এই বিন্দুতে সুষম সুস্পষ্ট হওয়ার জন্য পরিষ্কারভাবে।
Deduplicator

28

স্ট্রস্ট্রস্ট্র যা বলে তা এখানে :

সি তে, আপনি স্পষ্টভাবে একটি শূন্য * কে একটি টি * তে রূপান্তর করতে পারেন। এটি অনিরাপদ

তারপরে তিনি কীভাবে শূন্য * বিপজ্জনক হতে পারে তার একটি উদাহরণ দেখিয়ে বলেছেন এবং বলেছেন:

... ফলস্বরূপ, সি ++ এ, শূন্য * থেকে টি * পেতে আপনার স্পষ্ট নকলের প্রয়োজন। ...

অবশেষে, তিনি নোট করেছেন:

সি-তে এই অনিরাপদ রূপান্তরটির সবচেয়ে সাধারণ ব্যবহারগুলির মধ্যে একটি হ'ল ম্যালোক () এর ফলাফলকে একটি উপযুক্ত পয়েন্টারের কাছে বরাদ্দ করা। উদাহরণ স্বরূপ:

int * p = malloc (মাপের (int));

সি ++ এ, টাইপসেফ নতুন অপারেটরটি ব্যবহার করুন:

int * p = নতুন ইনট;

তিনি সি ++ এর ডিজাইন এবং বিবর্তনটিতে এ সম্পর্কে আরও অনেক বিশদে যান ।

সুতরাং উত্তরটি এখানে ফুটে উঠেছে: ভাষা ডিজাইনার বিশ্বাস করে যে এটি একটি অনিরাপদ প্যাটার্ন, এবং তাই এটিকে অবৈধ করে তোলে এবং প্যাটার্নটি সাধারণত কীভাবে ব্যবহৃত হত তা সম্পাদনের বিকল্প উপায় সরবরাহ করে।


1
mallocউদাহরণের সাথে সম্পর্কিত , এটি লক্ষণীয় যে mallocএটি (স্পষ্টতই) কোনও কনস্ট্রাক্টরকে কল করবে না, সুতরাং এটি যদি শ্রেণীর ধরণের হয় তবে আপনি মেমরি বরাদ্দ করছেন, ক্লাসের ধরণে স্পষ্টতই কাস্ট করতে সক্ষম হওয়া বিভ্রান্তিকর হবে।
chbaker0

এটি একটি খুব ভাল উত্তর, আমার চেয়ে তর্কাতীত ভাল। আমি "কর্তৃপক্ষ থেকে যুক্তি" পদ্ধতির সামান্যই অপছন্দ করি।
মাইক নাকিস

"নতুন ইনট" - বাহ, সি ++ নবাগত হিসাবে আমি গাদাতে বেস টাইপ যুক্ত করার উপায় চিন্তা করতে সমস্যা হচ্ছিলাম এবং আপনি এটি করতে পারবেন তা আমি জানি না। ম্যালোকের জন্য -1 ব্যবহার।
কাতানা 314

3
@ মাইকনাকিস এফডাব্লুআইডাব্লু, আমার উদ্দেশ্য ছিল আপনার উত্তরটির পরিপূরক করা। এই ক্ষেত্রে, প্রশ্নটি ছিল "তারা এগুলি কেন করেছিল", তাই আমি অনুভব করেছি যে প্রধান ডিজাইনারের কাছ থেকে শুনানি ন্যায়সঙ্গত।
রোবট

11

সি-তে অন্য কোনও পয়েন্টার ধরণের শূন্য * লাগানোর দরকার নেই, এটি সর্বদা নিরাপদে প্রচার করা হয়।

এটি সর্বদা প্রচারিত হয়, হ্যাঁ, তবে নিরাপদে নিরাপদে

সি ++ এই আচরণটিকে নিখুঁতভাবে অক্ষম করে কারণ এটি সি এর চেয়ে নিরাপদ প্রকারের ব্যবস্থা করার চেষ্টা করে এবং এই আচরণটি নিরাপদ নয়


রূপান্তর টাইপ করার জন্য এই 3 টি পদ্ধতির সাধারণভাবে বিবেচনা করুন:

  1. ব্যবহারকারীকে সবকিছু লিখতে বাধ্য করুন, সুতরাং সমস্ত রূপান্তর সুস্পষ্ট
  2. ধরে নিন যে ব্যবহারকারী জানেন যে তারা কী করছে এবং যে কোনও প্রকারকে অন্য কোনও রূপান্তর করে
  3. টাইপ-সেফ জেনেরিকস (টেমপ্লেটগুলি, নতুন এক্সপ্রেশন), স্পষ্টভাবে ব্যবহারকারী-সংজ্ঞায়িত রূপান্তর অপারেটরগুলি সহ একটি সম্পূর্ণ টাইপ সিস্টেমটি প্রয়োগ করুন এবং সংকলকটি দেখতে পাবে না এমন বিষয়গুলির স্পষ্ট রূপান্তরকে বাধ্য করুন স্পষ্টভাবে নিরাপদ are

ঠিক আছে, 1 হ'ল কুশ্রী এবং কিছু করার ক্ষেত্রে ব্যবহারিক বাধা, তবে যেখানে দুর্দান্ত যত্নের প্রয়োজন সেখানে সত্যই ব্যবহৃত হতে পারে। সি মোটামুটিভাবে 2 এর জন্য বেছে নিয়েছিল, এটি কার্যকর করা সহজ এবং 3+ এর জন্য সি ++, এটি কার্যকর করা তবে নিরাপদ তবে নিরাপদ।


এটি 3 এ পৌঁছনোর জন্য দীর্ঘ দীর্ঘ রাস্তা ছিল, পরে ব্যতিক্রমগুলি পরে যুক্ত হয়েছিল এবং পরে এখনও টেমপ্লেট রয়েছে।
জেডুগোস্জ

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

1

সংজ্ঞা অনুসারে, একটি শূন্য পয়েন্টার যে কোনও কিছুতে নির্দেশ করতে পারে। যে কোনও পয়েন্টারকে একটি অকার্যকর পয়েন্টারে রূপান্তর করা যায় এবং সুতরাং, আপনি ঠিক একই মানটিতে ফিরে এসে রূপান্তর করতে সক্ষম হবেন। তবে অন্যান্য ধরণের পয়েন্টারগুলিতে বাধা থাকতে পারে যেমন সারিবদ্ধকরণের সীমাবদ্ধতা। উদাহরণস্বরূপ, এমন একটি আর্কিটেকচারের কল্পনা করুন যেখানে অক্ষরগুলি কোনও মেমরি ঠিকানা দখল করতে পারে তবে পূর্ণসংখ্যার এমনকি ঠিক ঠিকানা সীমানায় শুরু করা উচিত। নির্দিষ্ট আর্কিটেকচারে, পূর্ণসংখ্যার পয়েন্টারগুলি একসাথে 16, 32 বা 64 বিটও গণনা করতে পারে যাতে কোনও চর * মেমরির একই স্থানটির দিকে ইঙ্গিত করার সময় প্রকৃতপক্ষে সংখ্যার সংখ্যাটির একাধিক থাকতে পারে। এই ক্ষেত্রে, একটি অকার্যকর * থেকে রূপান্তর করা আসলে বিটগুলি গোল করে যা পুনরুদ্ধার করা যায় না এবং তাই বিপরীত হয় না।

সহজ কথায় বলতে গেলে, অকার্যকর পয়েন্টারটি এমন কোনও কিছুতে নির্দেশ করতে পারে, যা অন্যান্য পয়েন্টারগুলি নির্দেশ করতে সক্ষম নাও হতে পারে including সুতরাং, অকার্যকর পয়েন্টারে রূপান্তরটি নিরাপদ তবে অন্যভাবে নয়।

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