স্ট্রিং থেকে ধীরে ধীরে 'চর *' রূপান্তর কেন সি-তে বৈধ তবে সি ++ এ অবৈধ


163

সি ++ 11 স্ট্যান্ডার্ড (আইএসও / আইইসি 14882: 2011) এতে বলেছে § C.1.1:

char* p = "abc"; // valid in C, invalid in C++

সি ++ এর জন্য স্ট্রিং লিটারালটির পয়েন্টার হিসাবে এটি ঠিক আছে ক্ষতিকারক যেহেতু এটির সংশোধন করার যে কোনও প্রচেষ্টা ক্রাশের দিকে নিয়ে যায়। তবে কেন এটি সি বৈধ?

সি ++ 11 আরও বলেছে:

char* p = (char*)"abc"; // OK: cast added

যার অর্থ হ'ল যদি প্রথম বিবৃতিতে কোনও কাস্ট যুক্ত করা হয় তবে তা বৈধ হয়ে যায়।

Theালাই কেন দ্বিতীয় বিবৃতিটিকে সি ++ এ বৈধ করে তোলে এবং এটি প্রথমটির থেকে আলাদা কীভাবে হয়? এটি কি এখনও ক্ষতিকারক নয়? যদি এটি হয় তবে মানকটি কেন এটি ঠিক আছে?


3
সি ++ 11 প্রথমটিকে অনুমতি দেয় না। আমার কেন কোন ধারণা নেই যে সি কেন char[]প্রথমে স্ট্রিংয়ের ধরণটি তৈরি করেছিল । দ্বিতীয়টি হচ্ছে const_castছদ্মবেশে।
ক্রিস

4
কেবলমাত্র প্রচুর উত্তেজনাপূর্ণ সি কোড রয়েছে যা এই নিয়মটি পরিবর্তন করা হলে ভঙ্গ হবে।
পল আর

1
দয়া করে পাঠ্যটি উদ্ধৃত করুন যেখানে স্ট্যান্ডার্ড দ্বিতীয়টি বলে OK
নওয়াজ

13
সি ভাষার আগে এটির স্ট্রিং অক্ষর ছিল constতাই এগুলি অগত্যা ছিল না const
কেসি

2
সি এবং সি ++ আপনাকে প্রায় কোনও প্রকার থেকে অন্য প্রকারে কাস্ট করতে দেয়। এর অর্থ এই নয় যে এই ক্যাসেটগুলি অর্থবহ এবং নিরাপদ।
সিয়ুয়ান রেন

উত্তর:


207

C ++ 03 এর মাধ্যমে আপনার প্রথম উদাহরণটি বৈধ ছিল, তবে একটি অবহিত অন্তর্নিহিত রূপান্তর ব্যবহৃত হয়েছিল - একটি স্ট্রিং আক্ষরিককে ধরণের বলে ধরা উচিত char const *, যেহেতু আপনি এর বিষয়বস্তুগুলি সংশোধন করতে পারবেন না (অপরিজ্ঞাত আচরণের কারণ ছাড়াই)।

সি ++ 11 হিসাবে, অবহিত করা হয়েছে এমন অন্তর্নিহিত রূপান্তরটি সরকারীভাবে সরানো হয়েছে, সুতরাং এটির উপর নির্ভর করে কোড (আপনার প্রথম উদাহরণের মতো) আর সংকলন করা উচিত নয়।

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

কোডটি সঠিকভাবে ফিক্স করার জন্য পয়েন্টারের ধরণটি সঠিক প্রকারে পরিবর্তন করা দরকার:

char const *p = "abc"; // valid and safe in either C or C++.

কেন এটি সি ++ এ অনুমতি দেওয়া হয়েছিল (এবং এখনও সি তে রয়েছে): কেবলমাত্র এমন প্রচুর কোড রয়েছে যা সেই অন্তর্নিহিত রূপান্তরের উপর নির্ভর করে এবং সেই কোডটি (কমপক্ষে কিছু সরকারী সতর্কতা ছাড়াই) ভঙ্গ করা আপাতদৃষ্টিতে স্ট্যান্ডার্ড কমিটিগুলিকে মনে হয়েছিল একটি খারাপ ধারণা


8
@ অরলফ: এটি যথেষ্ট বিপজ্জনক যে এটি কোনও অর্থবহ নমনীয়তা দেয় না, কমপক্ষে এমন কোডের জন্য যা বহনযোগ্যতার বিষয়ে যত্নশীল (মোটেও)। স্ট্রিং আক্ষরিকের কাছে লেখা সাধারণত আপনার প্রোগ্রামটিকে একটি আধুনিক ওএসে বাতিল করে দিতে পারে, সুতরাং কোড লেখার (অনুমতি দেওয়ার) অনুমতি দেওয়ার ফলে কোনও অর্থবহ নমনীয়তা যুক্ত হয় না।
জেরি কফিন

3
কোডটির এই উত্তর দেওয়া স্নিপেট char const *p = "abc";"বৈধ এবং নিরাপদ হয় উভয় সি এবং সি ++", "বৈধ এবং নিরাপদ নেই পারেন সি বা সি ++"।
ড্যানিয়েল লে

4
@ ড্যানিয়েল এই বাক্যগুলির উভয়েরই একই অর্থ রয়েছে
কালেথ

3
হে আমার পালনকর্তা! [গালে জিহ্বার দৃ firm়ভাবে প্রবেশ করান] দুঃখিত, তবে এখানে "বা" সঠিক শব্দটি রয়েছে। কোডটি সি হিসাবে বা সি ++ হিসাবে সংকলিত হতে পারে তবে একই সাথে সি এবং সি ++ উভয় হিসাবে সংকলন করা যায় না। আপনি যে কোনওটি চয়ন করতে পারেন তবে আপনাকে অবশ্যই একটি পছন্দ করতে হবে। আপনার দু'জন একসাথে থাকতে পারে না [জিহ্বার সাধারণ প্রক্রিয়া পুনরায় শুরু করুন]।
জেরি কফিন

2
না, উভয়ই / এবং এখানেই সবচেয়ে স্পষ্ট এবং সঠিক শব্দটি। হয় / বা এছাড়াও সঠিক অর্থ জানাতে ঘটে তবে প্রযুক্তিগত দিক থেকে এটি পরিষ্কার নয়। বা একা অকাট্য ভুল ( A বা B A এবং B এর সমান নয় )।
অ্যাপলিগুলি মনিকে

15

এটি inতিহাসিক কারণে বৈধ। সি traditionতিহ্যগতভাবে উল্লেখ করেছে যে স্ট্রিং আক্ষরিকের char *পরিবর্তে এটির ধরণ ছিল const char *, যদিও এটি আপনাকে এটি সংশোধন করার অনুমতি দিচ্ছে না বলে উপযুক্ত করে তুলেছে।

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


3
এটি একটি char[N]এবং পরিবর্তিত হয়েছিল const char[N]। এটির সাথে আকারের তথ্য সংযুক্ত রয়েছে।
ক্রিস

1
সি ধরণের স্ট্রিং আক্ষরিক char[N]তবে char*উদাহরণস্বরূপ "abc"নয়char[4]
গ্রিজেশ চৌহান

2

আপনি স্টার্ডআপ ব্যবহার করতে পারেন :

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