উত্তরটি হ'ল: এটি নির্ভর করে যে আপনি C ++ স্ট্যান্ডার্ডের সাথে কী সংগ্রহ করছেন। এই কোডটি বাদ দিয়ে সমস্ত কোডই সমস্ত মানকে পুরোপুরি সুসংহত করে:
char * s = "My String";
এখন, স্ট্রিং আক্ষরিকের টাইপ আছে const char[10]
এবং আমরা এটির জন্য একটি নিরপেক্ষ পয়েন্টার আরম্ভ করার চেষ্টা করছি। char
স্ট্রিং আক্ষরিকের পরিবার ব্যতীত অন্য সমস্ত ধরণের ক্ষেত্রে , এই জাতীয় সূচনাটি সর্বদা অবৈধ। উদাহরণ স্বরূপ:
const int arr[] = {1};
int *p = arr; // nope!
তবে, প্রি-সি ++ 11-এ স্ট্রিং লিটারেলের ক্ষেত্রে, exception4.2 / 2 এ ব্যতিক্রম ছিল:
একটি স্ট্রিং আক্ষরিক (২.১.4.৪) যা প্রশস্ত স্ট্রিং আক্ষরিক নয়, " পয়েন্টারে টু চর " টাইপের মূল্যে রূপান্তরিত হতে পারে ; [...]। উভয় ক্ষেত্রেই ফলাফলটি অ্যারের প্রথম উপাদানটির জন্য একটি পয়েন্টার। এই রূপান্তরটি কেবল তখনই বিবেচনা করা হয় যখন স্পষ্টভাবে উপযুক্ত পয়েন্টার টার্গেট ধরণের থাকে এবং যখন কোনও লভাল্যু থেকে কোনও মূল্যকে রূপান্তর করার কোনও সাধারণ প্রয়োজন হয় না। [দ্রষ্টব্য: এই রূপান্তরটি হ্রাস করা হয়েছে । আনেকেক্স ডি দেখুন ]
সুতরাং C ++ 03 এ কোডটি পুরোপুরি ঠিক আছে (যদিও অবমূল্যায়ন করা হয়েছে), এবং এর স্পষ্ট, অনুমানযোগ্য আচরণ রয়েছে।
সি ++ ১১-এ, সেই ব্লকটির অস্তিত্ব নেই - স্ট্রিং লিটারেলগুলিতে রূপান্তরিত হওয়ার জন্য এরকম কোনও ব্যতিক্রম নেই char*
এবং তাই কোডটি ঠিক যেমনটি int*
আমি প্রদান করেছি তার মতোই দুর্বোধ্য। সংকলকটি ডায়াগনস্টিক ইস্যু করার জন্য বাধ্যতামূলক, এবং আদর্শ ক্ষেত্রে যেমন সি ++ টাইপ সিস্টেমের স্পষ্ট লঙ্ঘন, আমরা আশা করি একটি ভাল সংকলক কেবলমাত্র এই ক্ষেত্রে মেনে চলবে না (যেমন একটি সতর্কতা জারি করে) তবে ব্যর্থ হবে সরাসরি।
কোডটি আদর্শভাবে সংকলন করা উচিত নয় - তবে এটি জিসিসি এবং ঝনঝন উভয় ক্ষেত্রেই করে (আমি ধরে নিলাম কারণ সম্ভবত সেখানে প্রচুর কোড রয়েছে যা সামান্য লাভের সাথে ভেঙে দেওয়া হবে, যদিও এই ধরণের সিস্টেমের গর্তটি এক দশক ধরে অবহেলিত রয়েছে)। কোডটি দুর্গঠিত, সুতরাং কোডটির আচরণ কী হতে পারে সে সম্পর্কে যুক্তিযুক্ত তা বোঝা যায় না। তবে এই নির্দিষ্ট কেসটি এবং এর পূর্বে অনুমোদিত হওয়ার ইতিহাসটি বিবেচনা করে, আমি বিশ্বাস করি না যে ফলাফলের কোডটি ব্যাখ্যা করার জন্য এটি একটি যুক্তিসঙ্গত প্রসারিত বলে মনে হচ্ছে যেন এটি কোনও অন্তর্নিহিত const_cast
, যেমন:
const int arr[] = {1};
int *p = const_cast<int*>(arr); // OK, technically
এটির সাথে, প্রোগ্রামটির বাকী অংশগুলি পুরোপুরি ঠিক আছে, কারণ আপনি আর কখনও স্পর্শ করেন s
না। অ- পয়েন্টারটির মাধ্যমে একটি তৈরি- অবজেক্ট পড়া পুরোপুরি ঠিক। এই জাতীয় পয়েন্টারের মাধ্যমে একটি তৈরি- অবজেক্ট রচনা অপরিজ্ঞাত আচরণ:const
const
const
std::cout << *p; // fine, prints 1
*p = 5; // will compile, but undefined behavior, which
// certainly qualifies as "unpredictable"
যেহেতু s
আপনার কোডের কোথাও কোনও পরিবর্তন নেই , প্রোগ্রামটি সি ++ 03 তে ঠিক আছে, সি ++ 11-এ সংকলন করতে ব্যর্থ হওয়া উচিত তবে যাইহোক - এবং সংকলকরা এটির অনুমতি দেয়, এখনও এটির মধ্যে কোনও অপরিবর্তিত আচরণ নেই † । সংযোজকরা এখনও [ভুলভাবে] সি ++ 03 বিধিগুলির ব্যাখ্যা দিচ্ছেন এমন ভাতা দিয়ে, আমি এমন কোনও কিছুই দেখি না যা "অনাকাঙ্ক্ষিত" আচরণের দিকে পরিচালিত করে। s
যদিও লিখুন , এবং সমস্ত বেট বন্ধ আছে। সি ++ 03 এবং সি ++ 11 উভয়ই।
† যদিও, আবার সংজ্ঞা অনুসারে অ-গঠিত কোডটি যুক্তিসঙ্গত আচরণের প্রত্যাশা দেয়
না not না বাদে ম্যাট ম্যাকনাব্বের উত্তর দেখুন