c++ - সি++ বই




সি++ 11 কেন স্টেড:: স্ট্রিং:: ডেটা তৈরি করেছে() একটি নল সমাপ্তির চরিত্র যোগ করবেন? (2)

এখানে আলোচনা করতে দুটি পয়েন্ট আছে:

নাল টারমিনেটর জন্য স্থান

তত্ত্ব অনুসারে সি ++ 03 বাস্তবায়ন টার্মিনাটারের জন্য বরাদ্দ করা স্থান এড়িয়ে চলতে পারে এবং / অথবা অনুলিপিগুলি সম্পাদন করার প্রয়োজন হতে পারে (উদাহরণস্বরূপ unsharing )।

যাইহোক, c_str() শুরু করতে c_str() সমর্থন করার জন্য সমস্ত সাইন বাস্তবায়নগুলি নল-টারমিনেটরের জন্য রুম বরাদ্দ করে, কারণ অন্যথায় যদি এটি একটি তুচ্ছ কল না হয় তবে কার্যত অব্যবহারযোগ্য হবে।

নল-টারমিনেটর নিজেই

এটা সত্য যে কিছু very (1999), খুব পুরানো বাস্তবায়ন (2001) লিখেছেন প্রতি \0 c_str() কল।

যাইহোক, বড় বাস্তবায়নগুলি changed (2004) বা সি (সিটি) 11 প্রকাশ করার আগে এ ধরনের জিনিস এড়ানোর জন্য (2010) একই রকম ছিল, তাই যখন নতুন মান আসে তখন অনেক ব্যবহারকারীর জন্য কিছু পরিবর্তন হয়নি।

এখন, একটি C ++ 03 বাস্তবায়ন এটি করা উচিত কিনা বা না:

আমার কাছে এটি CPU চক্রগুলির বর্জ্য হিসাবে মনে হচ্ছে

আসলে তা না. যদি আপনি c_str() কে একাধিক বার কল c_str() , আপনি ইতিমধ্যে কয়েক বার লিখে চক্রগুলি নষ্ট করছেন। শুধু এটিই নয়, আপনি ক্যাশের শ্রেণীবিন্যাসের সাথে জড়িয়ে পড়েছেন, যা বহু-পাঠিত সিস্টেমে বিবেচনা করা গুরুত্বপূর্ণ। 2001 এবং 2006 মধ্যে মাল্টি-কোর / এসএমটি CPU গুলি প্রদর্শিত হতে শুরু করে যা আধুনিক, নন-কোওডাব্লিউ বাস্তবায়নের সুইচ ব্যাখ্যা করে (এমনকি এটির কয়েক দশক আগেও মাল্টি-সিপিএম সিস্টেমগুলি ছিল না)।

একমাত্র পরিস্থিতি যেখানে আপনি কিছু সংরক্ষণ করবেন যদি আপনি c_str() কখনও না বলে c_str() । যাইহোক, নোট করুন যে আপনি যখন স্ট্রিংটি পুনরায় আকার দিচ্ছেন, তখনও আপনি সবকিছু আবার লিখছেন। একটি অতিরিক্ত বাইট সম্ভবত পরিমাপযোগ্য হতে যাচ্ছে।

অন্য কথায়, পুনরায় আকারে টারমিনেটরটি লেখার দ্বারা, আপনি নিজেকে খারাপ কর্মক্ষমতা / বিলম্বিত করার জন্য প্রকাশ করছেন। একই সময়ে এটি একবারে আপনাকে স্ট্রিংয়ের একটি অনুলিপি সঞ্চালন করতে হবে, কর্মক্ষমতা আচরণটি আরো প্রত্যাশাযোগ্য এবং আপনি c_str() বিশেষ করে c_str() সিস্টেমে ব্যবহার করে শেষ পর্যন্ত কর্মক্ষমতা c_str() এড়াতে পারেন।

পূর্বে std::string::c_str() এর কাজ ছিল, কিন্তু C ++ 11 হিসাবে, data() এটিও সরবরাহ করে, কেন c_str() এর null-terminating-character std::string::data() যোগ করা হলো std::string::data() ? আমার কাছে এটি CPU চক্রগুলির বর্জ্যের মতো মনে হয়, যেখানে কোনও নরম-টার্মিনেটর-চরিত্রটি প্রাসঙ্গিক নয় এবং শুধুমাত্র data() ব্যবহার করা হয়, একটি C ++ 03 কম্পাইলারটি টারমিনেটরের যত্ন নিতে হবে না এবং প্রতিটি সময় স্ট্রিং পুনরায় আকারে টাইমারটি লিখতে হবে না, তবে একটি C ++ 11 কম্পাইলার, data() -রল-গ্যারান্টি কারণে, স্ট্রিংটির আকার পরিবর্তন করার সময় প্রতিলিখন 0 নষ্ট করতে হবে, তাই যেহেতু এটি সম্ভাব্য কোড ধীর করে তোলে, আমি অনুমান করি যে তাদের গ্যারান্টি যুক্ত করার কিছু কারণ ছিল, এটা কি ছিল?


পরিবর্তনের উপকারিতা:

  1. যখন data নল টার্মিনাইটারেরও নিশ্চয়তা দেয়, তখন প্রোগ্রামারকে c_str এবং data মধ্যে পার্থক্যগুলির অস্পষ্ট বিশদ জানার প্রয়োজন হয় না এবং ফলস্বরূপ ক্রম পাস করা থেকে অকার্যকর আচরণ এড়াতে পারে না যা ফাঁকা বাতিলের গ্যারান্টি ছাড়াই নল সমাপ্তির প্রয়োজন হয়। এই ধরনের ফাংশন সি ইন্টারফেসে সর্বজনীন, এবং C ইন্টারফেসগুলি C ++ এ অনেকগুলি ব্যবহার করা হয়।

  2. সাবস্ক্রিপ্ট অপারেটরটি str[str.size()] অ্যাক্সেস পড়ার অনুমতি দেওয়ার জন্যও পরিবর্তন করা হয়েছে। str.data() + str.size() অ্যাক্সেস মঞ্জুরি str.data() + str.size() অসঙ্গত হবে।

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

অদ্ভুত বিবরণ: str.at(str.size()) এখনও একটি ব্যতিক্রম ছুড়ে ফেলে।

পিএস আরেকটি পরিবর্তন ছিল, যা গ্যারান্টি দেয় যে স্ট্রিংগুলিতে সামঞ্জস্যপূর্ণ স্টোরেজ রয়েছে (যার ফলে data প্রথম স্থানে সরবরাহ করা হয়)। সি ++ 11 এর আগে, বাস্তবায়নগুলি c_str স্ট্রিংগুলি ব্যবহার করতে পারে এবং c_str কল করে পুনরায় c_str । কোন বড় বাস্তবায়ন এই স্বাধীনতা (আমার জ্ঞান) শোষণ চয়ন করা হয়েছে।

পিপিএস জি-সি-এর লিবস্টডিসি ++ এর পুরানো সংস্করণ উদাহরণস্বরূপ দৃশ্যত null টারমিনেটরটি শুধুমাত্র সংস্করণ 3.4 পর্যন্ত c_str সেট করে। বিস্তারিত জানার জন্য সম্পর্কিত কমিটি দেখুন।

¹ এটির একটি উপাদান একটি সমানতা যা C ++ 11 এ ভাষা মানদণ্ডে প্রবর্তিত হয়েছিল। সমবায় অ-পারমাণবিক সংশোধন ডেটা-রেস অনির্ধারিত আচরণ, যার জন্য সি ++ কম্পাইলারদের আক্রমণাত্মকভাবে অপ্টিমাইজ করার অনুমতি দেওয়া হয় এবং নিবন্ধগুলি জিনিসগুলিতে রাখা যায়। সুতরাং সাধারণ C ++ এ লিখিত লাইব্রেরির বাস্তবায়নটি .c_str() সমকক্ষ কলগুলির জন্য .c_str()

অনুশীলনে (মন্তব্য দেখুন) একই জিনিস লেখার একাধিক থ্রেড থাকার কারণে সঠিকতা সমস্যা সৃষ্টি হবে না কারণ আসল CPU গুলির জন্য ASM UB নেই। এবং C ++ UB নিয়মগুলি বোঝায় যে একাধিক থ্রেড প্রকৃতপক্ষে std::string বস্তুটি সিঙ্ক্রোনাইজেশান ছাড়া c_str() কল ছাড়া অন্য কিছু) কম্পাইলার + লাইব্রেরি অনুমান করতে পারে এমন কিছু নয়।

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





c++03