মাপ, সূচক ইত্যাদির জন্য সাইজ_টি বা ইনট


15

সি ++ এ size_t(বা আরও সঠিকভাবে T::size_typeযা "সাধারণত" হয় size_t; অর্থাত্ একটি unsignedপ্রকার) এর রিটার্ন মান হিসাবে size()যুক্তি operator[]ইত্যাদির জন্য ব্যবহৃত হয় (দেখুন std::vector, ইত্যাদি । আল)

অন্যদিকে, নেট ভাষা একই উদ্দেশ্যে int(এবং , optionচ্ছিকভাবে long) ব্যবহার করে; প্রকৃতপক্ষে, সিএলএস-অনুবর্তী ভাষা স্বাক্ষরযুক্ত প্রকারের সমর্থন করার প্রয়োজন হয় না

দেওয়া .NET সি ++ এর চেয়েও নতুন, কিছু আমাকে জানিয়েছে যে অ্যারে সূচক বা দৈর্ঘ্যের মতো নেতিবাচক হতে পারে এমন জিনিসগুলির জন্য এমনকি এমন কিছু সমস্যা ব্যবহার করতে সমস্যা হতে পারে unsigned int। সি ++ পিছনের সামঞ্জস্যের জন্য "historicalতিহাসিক নিদর্শন" পদ্ধতির? বা দুটি পদ্ধতির মধ্যে কি সত্যিকারের এবং উল্লেখযোগ্য ডিজাইনের বাণিজ্য রয়েছে?

কেন এই ব্যাপার? ভাল ... আমি সি ++ তে নতুন বহুমাত্রিক শ্রেণীর জন্য কী ব্যবহার করব; size_tবা int?

struct Foo final // e.g., image, matrix, etc.
{
    typedef int32_t /* or int64_t*/ dimension_type; // *OR* always "size_t" ?
    typedef size_t size_type; // c.f., std::vector<>

    dimension_type bar_; // maybe rows, or x
    dimension_type baz_; // e.g., columns, or y

    size_type size() const { ... } // STL-like interface
};

6
লক্ষ্যণীয়: নট ফ্রেমওয়ার্কের বেশ কয়েকটি স্থানে, -1"পাওয়া যায়নি" বা "সীমার বাইরে" ইঙ্গিত করতে কোনও সূচক ফেরত ফাংশন থেকে ফিরে আসে। এটি Compare()ফাংশন (বাস্তবায়ন IComparable) থেকেও ফিরে এসেছে । একটি 32 বিট ইনট একটি সাধারণ সংখ্যার জন্য টাইপ করতে যাওয়া হিসাবে বিবেচিত হয়, আমি আশা করি যে কারণে স্পষ্ট কারণ রয়েছে।
রবার্ট হার্ভে

উত্তর:


9

দেওয়া .NET সি ++ এর চেয়েও নতুন, কিছু আমাকে জানিয়েছে যে অ্যারে সূচক বা দৈর্ঘ্যের মতো নেতিবাচক হতে পারে এমন জিনিসগুলির জন্য এমনকি স্বাক্ষরযুক্ত ইন্ট ব্যবহার করতে সমস্যা হতে পারে।

হ্যাঁ. কিছু ধরণের অ্যাপ্লিকেশন যেমন ইমেজ প্রসেসিং বা অ্যারে প্রসেসিংয়ের জন্য, প্রায়শই বর্তমান অবস্থানের সাথে সম্পর্কিত উপাদানগুলিতে অ্যাক্সেস করা প্রয়োজন:

sum = data[k - 2] + data[k - 1] + data[k] + data[k + 1] + ...

এই ধরণের অ্যাপ্লিকেশনগুলিতে, আপনি সতর্কতার সাথে চিন্তা না করে স্বাক্ষরযুক্ত পূর্ণসংখ্যার সাথে পরিসীমা চেক করতে পারবেন না:

if (k - 2 < 0) {
    throw std::out_of_range("will never be thrown"); 
}

if (k < 2) {
    throw std::out_of_range("will be thrown"); 
}

if (k < 2uL) {
    throw std::out_of_range("will be thrown, without signedness ambiguity"); 
}

পরিবর্তে আপনি আপনার পরিসীমা চেক এক্সপ্রেশন পুনরায় সাজানো আছে । এটিই মূল পার্থক্য। প্রোগ্রামারদের অবশ্যই পূর্ণসংখ্যার রূপান্তর নিয়মগুলি মনে রাখতে হবে। কোন সন্দেহ থাকলে, পুনরায় পড়া http://en.cppreference.com/w/cpp/language/operator_arithmetic#Conversions

প্রচুর অ্যাপ্লিকেশনগুলিকে খুব বড় অ্যারে সূচকগুলি ব্যবহার করার প্রয়োজন হয় না তবে তাদের পরিসীমা পরীক্ষা করা দরকার। তদ্ব্যতীত, প্রচুর প্রোগ্রামার এই এক্সপ্রেশন পুনর্বিন্যাস জিমন্যাস্টিকগুলি করতে প্রশিক্ষিত হয় না। একটি একক মিস সুযোগ একটি শোষণের দ্বার উন্মুক্ত করে।

সি # প্রকৃতপক্ষে সেই অ্যাপ্লিকেশনগুলির জন্য ডিজাইন করা হয়েছে যা অ্যারে প্রতি 2 ^ 31 উপাদানগুলির বেশি প্রয়োজন হবে না। উদাহরণস্বরূপ, একটি স্প্রেডশীট অ্যাপ্লিকেশনটির সেই অনেকগুলি সারি, কলাম বা কক্ষগুলি মোকাবেলা করার দরকার নেই। সি # limit চ্ছিক পরীক্ষিত গাণিতিক থাকার ফলে উপরের সীমাটির সাথে ডিল করে যা সংকলক বিকল্পগুলির সাথে বিশৃঙ্খলা ছাড়াই কোনও কীওয়ার্ড সহ কোডের ব্লকের জন্য সক্ষম করা যায়। এই কারণে, সি # স্বাক্ষরিত পূর্ণসংখ্যার ব্যবহারের পক্ষে। যখন এই সিদ্ধান্তগুলি পুরোপুরি বিবেচনা করা হয়, তখন তা বোঝা যায়।

সি ++ কেবল আলাদা, এবং সঠিক কোড পাওয়া শক্ত er

"স্বল্প বিস্ময়ের নীতি" এর সম্ভাব্য লঙ্ঘন অপসারণ করার জন্য স্বাক্ষরিত গাণিতিককে অনুমতি দেওয়ার ব্যবহারিক গুরুত্ব সম্পর্কে, পয়েন্টের একটি ক্ষেত্রে ওপেনসিভি, যা ম্যাট্রিক্স উপাদান সূচক, অ্যারের আকার, পিক্সেল চ্যানেল গণনা ইত্যাদির জন্য স্বাক্ষরিত 32-বিট পূর্ণসংখ্যার ব্যবহার করে Image প্রসেসিং প্রোগ্রামিং ডোমেনের একটি উদাহরণ যা আপেক্ষিক অ্যারে সূচককে ভারী ব্যবহার করে। স্বাক্ষরবিহীন পূর্ণসংখ্যার আন্ডারফ্লো (চারপাশে মোড়ানো নেতিবাচক ফলাফল) অ্যালগরিদম বাস্তবায়নকে মারাত্মকভাবে জটিল করে তুলবে।


এটাই আমার অবস্থা; নির্দিষ্ট উদাহরণের জন্য ধন্যবাদ। (হ্যাঁ, আমি এই জানি, কিন্তু এটা cite থেকে "উচ্চ কর্তৃপক্ষ" আছে উপযোগী হতে পারে।)
Ðаn

1
@ ড্যান: আপনার যদি কিছু উদ্ধৃত করার প্রয়োজন হয় তবে এই পোস্টটি আরও ভাল।
rwong

1
@ ড্যান: জন রেগার এই সমস্যাটি প্রোগ্রামিং ভাষায় সক্রিয়ভাবে গবেষণা করছেন। Blog.regehr.org/archives/1401
রাওয়ং

বিপরীত মতামত রয়েছে: gustedt.wordpress.com/2013/07/15/…
rwong

14

এই উত্তরটি সত্যই নির্ভর করে যে আপনার কোডটি কে ব্যবহার করবে এবং তারা কোন মানদণ্ড দেখতে চায় তার উপর নির্ভর করে।

size_t একটি উদ্দেশ্য সহ একটি পূর্ণসংখ্যার আকার:

প্রকারটি size_tএকটি বাস্তবায়ন-সংজ্ঞায়িত স্বাক্ষরযুক্ত পূর্ণসংখ্যার প্রকার যা কোনও বস্তুর বাইটে আকার ধারণ করতে যথেষ্ট বড়। (সি ++ 11 নির্দিষ্টকরণ 18.2.6)

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

মনে রাখবেন যে আপনার ক্লাসটি কোনও এসটিএল ক্লাসের চেহারা এবং অনুভূতি রাখার উদ্দেশ্যে থাকলে সর্বদাsize_t আপনার ব্যবহার করা উচিত । এসটিএল ক্লাসের সমস্ত স্পেসিফিকেশন ব্যবহার করে size_t এটা তোলে বৈধ হয় typedef করতে কম্পাইলার জন্য size_tহতে unsigned int, এবং এটা বৈধ নয় জন্য এটি typedefed করা unsigned long। আপনি যদি সরাসরি intবা longসরাসরি ব্যবহার করেন তবে আপনি শেষ পর্যন্ত সংকলকগুলিতে ছুটে যাবেন যেখানে আপনার ক্লাসটি এসটিএল এর স্টাইল অনুসরণ করে বলে মনে করে এমন কোনও ব্যক্তি আটকে যায় কারণ আপনি মানটি অনুসরণ করেননি।

স্বাক্ষরিত প্রকারের ব্যবহারের জন্য কয়েকটি সুবিধা রয়েছে:

  • সংক্ষিপ্ত নাম - এটি টাইপ করা মানুষের পক্ষে সত্যই সহজ int, তবে কোডটি দিয়ে বিশৃঙ্খলা করা আরও শক্ত unsigned int
  • প্রতিটি আকারের জন্য একটি পূর্ণসংখ্যা - 32-বিটগুলির মধ্যে কেবল একটি সিএলএস অনুবর্তী পূর্ণসংখ্যা হয়, যা অন্তর্গত 32 হয়। সি ++ এ দুটি ( int32_tএবং uint32_t) রয়েছে। এটি এপিআই আন্তঃক্রিয়াশীলতা সহজতর করতে পারে

স্বাক্ষরযুক্ত ধরণের বড় অসুবিধা হ'ল স্পষ্টত: আপনি নিজের ডোমেনের অর্ধেক হারান। একটি স্বাক্ষরযুক্ত নম্বর একটি স্বাক্ষরবিহীন সংখ্যা হিসাবে উচ্চ গণনা করতে পারে। যখন C / C ++ চারপাশে আসে তখন এটি খুব গুরুত্বপূর্ণ ছিল। প্রসেসরের সম্পূর্ণ সক্ষমতা সম্বোধনের জন্য একজনকে সাইন করা এবং আপনার স্বাক্ষরবিহীন সংখ্যাগুলি ব্যবহার করার দরকার ছিল।

.NET লক্ষ্যযুক্ত অ্যাপ্লিকেশনগুলির জন্য, একটি সম্পূর্ণ-ডোমেন স্বাক্ষরযুক্ত সূচকের প্রয়োজনের মতো শক্তিশালী ছিল না। এই জাতীয় সংখ্যার জন্য অনেকগুলি উদ্দেশ্য পরিচালনা করা ভাষায় কেবল অবৈধ (মেমরি পুলিং মনে আসে)। NET বেরিয়ে আসার সাথে সাথে, 64-বিট কম্পিউটারগুলি স্পষ্টভাবে ভবিষ্যতের ছিল। আমরা একটি 64-বিট পূর্ণসংখ্যার পূর্ণ পরিসীমা প্রয়োজন থেকে অনেক দূরে রয়েছি, তাই এক বিট উত্সর্গ করা আগের মতো কষ্টদায়ক নয়। আপনার যদি সত্যই 4 বিলিয়ন সূচকের প্রয়োজন হয় তবে আপনি কেবলমাত্র 64-বিট পূর্ণসংখ্যার ব্যবহারে স্যুইচ করুন। সবচেয়ে খারাপ, আপনি এটি 32 বিট মেশিনে চালান এবং এটি কিছুটা ধীর গতিতে।

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


ধরা যাক এর বাস্তবায়ন size()ছিল return bar_ * baz_;; এটি কি এখন পূর্ণসংখ্যার ওভারফ্লো (মোড়ানো) চারপাশে কোনও সম্ভাব্য সমস্যা তৈরি করে না যে আমি ব্যবহার না করলে আমার কী হবে না size_t?
Decn

5
@ ড্যান আপনি এই জাতীয় ক্ষেত্রে তৈরি করতে পারেন যেখানে স্বাক্ষরবিহীন অন্তর্নিহিত জিনিসগুলি গুরুত্বপূর্ণ হবে এবং সেই ক্ষেত্রে এটি সমাধানের জন্য সম্পূর্ণ ভাষার বৈশিষ্ট্যগুলি ব্যবহার করা সবচেয়ে ভাল। তবে, আমি অবশ্যই বলব যে এটি এমন একটি শ্রেণীর জন্য আকর্ষণীয় নির্মাণ হবে যেখানে bar_ * baz_কোনও স্বাক্ষরিত পূর্ণসংখ্যাকে উপচে ফেলতে পারে তবে স্বাক্ষরবিহীন পূর্ণসংখ্যার পূর্ণসংখ্যায় নয়। নিজেদেরকে সি ++ তে সীমাবদ্ধ রেখে, এটি লক্ষণীয় যে স্বাক্ষরযুক্ত ওভারফ্লোটি অনুষঙ্গটিতে সংজ্ঞায়িত করা হয়েছে তবে স্বাক্ষরিত ওভারফ্লো অপরিজ্ঞাত আচরণ, সুতরাং স্বাক্ষরযুক্ত পূর্ণসংখ্যার মডুলো গাণিতিকটি যদি আকাঙ্ক্ষিত হয় তবে অবশ্যই এটি ব্যবহার করুন, কারণ এটি প্রকৃত সংজ্ঞায়িত হয়েছে!
আম্মন

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

4

আমি মনে করি উপরে রাওংয়ের উত্তর ইতিমধ্যে দুর্দান্তভাবে বিষয়গুলি হাইলাইট করেছে।

আমি আমার 002 যুক্ত করব:

  • size_t, এটি একটি আকার যা ...

    যে কোনও ধরণের তাত্ত্বিকভাবে সম্ভব বস্তুর সর্বাধিক আকার সংরক্ষণ করতে পারে (অ্যারে সহ)।

    ... কেবলমাত্র পরিসীমা সূচকগুলির জন্য প্রয়োজনীয় যখন sizeof(type)==1আপনি যদি বাইট ( char) প্রকারগুলি নিয়ে কাজ করছেন। (তবে, আমরা লক্ষ করি, এটি পিটিআর টাইপের চেয়ে ছোট হতে পারে :

  • এ হিসাবে, xxx::size_typeএটি যদি স্বাক্ষরিত আকারের আকার হয় তবেও 99.9% ক্ষেত্রে ব্যবহৃত হতে পারে। (তুলনা ssize_t)
  • আকার এবং সূচীকরণের জন্য std::vectorএবং বন্ধুরা যে স্বাক্ষরবিহীন প্রকারটি বেছে নিয়েছিল size_t, তা কেউ কেউ ডিজাইনের ত্রুটি হিসাবে বিবেচনা করে । আমি একমত. (সিরিয়াসলি, 5 মিনিট সময় নিয়ে যান এবং বজ্র আলাপ দেখুন সিপিসন 2016: জোন কালব "স্বাক্ষরযুক্ত: আরও ভাল কোডের জন্য একটি গাইডলাইন" ))
  • আপনি আজ একটি সি ++ এপিআই ডিজাইন করার সময় আপনি একটি শক্ত জায়গায় আছেন: size_tস্ট্যান্ডার্ড লাইব্রেরির সাথে সামঞ্জস্যপূর্ণ হতে ব্যবহার করুন বা ( স্বাক্ষরিত ) intptr_tবা ssize_tসহজে এবং কম বাগ প্রবণ সূচক গণনার জন্য ব্যবহার করুন।
  • ইন্ট 32 বা ইন্ট 64 ব্যবহার করবেন না - intptr_tআপনি স্বাক্ষর করতে চাইলে ব্যবহার করুন এবং মেশিন শব্দের আকার বা ব্যবহার করতে চান ssize_t

প্রশ্নের সরাসরি উত্তর দিতে, এটি পুরোপুরি একটি "historical তিহাসিক নিদর্শন " নয়, কারণ অর্ধেকেরও বেশি ("ইনডেক্সিং", বা) ঠিকানা জায়গার সম্বোধন করার তাত্ত্বিক সমস্যাটি অবশ্যই , নীচে, কোনওভাবে নিম্ন স্তরের ভাষায় সম্বোধন করা উচিত সি ++।

সংঘটনের পরে বোধোদয়, আমি, ব্যক্তিগতভাবে মনে, এটা হল একটি নকশা খুঁত স্ট্যান্ডার্ড লাইব্রেরী স্বাক্ষরবিহীন ব্যবহার size_tসব জায়গায় এমনকি যেখানে এটি একটি কাঁচা মেমরির আকার প্রতিনিধিত্ব করে না ধরে, কিন্তু টাইপ করা তথ্য একটি ক্ষমতা, সংগ্রহের মত:

  • প্রদত্ত সি ++ এর পূর্ণসংখ্যা প্রচারের নিয়ম ->
  • স্বাক্ষরবিহীন প্রকারগুলি কেবল শব্দার্থবিহীন স্বাক্ষরযুক্ত এমন আকারের মতো "সিমেন্টিক" প্রকারের জন্য ভাল প্রার্থী করে না।

আমি এখানে জনের পরামর্শগুলি পুনরাবৃত্তি করব :

  • তারা সমর্থন করে এমন ক্রিয়াকলাপগুলির জন্য প্রকারগুলি নির্বাচন করুন (মানগুলির সীমা নয়)। (* 1)
  • আপনার এপিআই-তে স্বাক্ষরবিহীন প্রকারগুলি ব্যবহার করবেন না। এটি কোনও উল্টো উপকার ছাড়াই বাগগুলি আড়াল করে।
  • পরিমাণের জন্য "স্বাক্ষরযুক্ত" ব্যবহার করবেন না ((* 2)

(* 1) অর্থাত না স্বাক্ষরিত == বিটমাস্ক, এটিতে কখনই গণিত করবেন না (এখানে প্রথম ব্যতিক্রম হিট হয়েছে - আপনার কাউন্টারের প্রয়োজন হতে পারে যা মোড়ানো হয় - এটি অবশ্যই স্বাক্ষরবিহীন প্রকারের হতে হবে))

(* 2) পরিমাণগুলি অর্থ যা আপনি গণনা করেন এবং / অথবা গণিত করেন।


"সম্পূর্ণ উপলভ্য ফ্ল্যাট মেমরি" বলতে কী বোঝ? এছাড়াও, নিশ্চিত যে আপনি চান না ssize_t, size_tপরিবর্তে স্বাক্ষরিত দুল হিসাবে সংজ্ঞায়িত intptr_t, যা কোনও (সদস্যবিহীন) পয়েন্টার সঞ্চয় করতে পারে এবং এভাবে বড় হতে পারে?
ডিসিপ্লিকেটর

@ প্রতিলিপি - ভাল আমি অনুমান করি যে আমি size_tসংজ্ঞাটি কিছুটা গণ্ডগোল করে ফেলেছি । দেখুন size_t বনাম intptr এবং en.cppreference.com/w/cpp/types/size_t নতুন আজ কিছু শিখেছি। :-) আমি মনে করি বাকি আর্গুমেন্টগুলি দাঁড়িয়ে আছে, আমি ব্যবহৃত প্রকারগুলি ঠিক করতে পারি কিনা তা আমি দেখতে পাচ্ছি।
মার্টিন বা

0

আমি কেবল যুক্ত করব যে পারফরম্যান্সের কারণে আমি সাধারণত সাইজ_টি ব্যবহার করি, যাতে নিশ্চিত হয় যে ভুলভ্রান্তিগুলি একটি ডুবো প্রবাহের কারণ হয় যার অর্থ উভয় রেঞ্জ চেক (শূন্যের নীচে এবং উপরে () এর পরিমাণ হ্রাস করা যায়:

স্বাক্ষরিত int ব্যবহার:

int32_t i = GetRandomNumberFromRange(-1000, 1000);

if (i < 0)
{
    //error
}

if (i > size())
{
    //error
}

স্বাক্ষরবিহীন ইনট ব্যবহার:

int32_t i = GetRandomNumberFromRange(-1000, 1000);

/// This will underflow any number below zero, so that it becomes a very big *positive* number instead.
uint32_t asUnsigned = static_cast<uint32_t>(i);

/// We now don't need to check for below zero, since an unsigned integer can only be positive.
if (asUnsigned > size())
{
    //error
}

1
আপনি সত্যিই আরও একটি পুরোপুরি ব্যাখ্যা করতে চান।
মার্টিন বা

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

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