স্বাক্ষরযুক্ত ইন্ট বনাম আকার_টি


492

আমি যে আধুনিক সি লক্ষ্য এবং সি ++ কোড ব্যবহার বলে মনে হয় size_tপরিবর্তে int/ unsigned intপ্রায় কাছাকাছি সর্বত্র - STL সি স্ট্রিং কাজকর্মের জন্য পরামিতি থেকে। আমি এর কারণ এবং এটি যে উপকারগুলি নিয়ে আসে সে সম্পর্কে আমি আগ্রহী।

উত্তর:


388

size_tটাইপ স্বাক্ষরবিহীন পূর্ণসংখ্যা ধরনের ফল যে sizeofঅপারেটর (এবং offsetofতাই এটি বড় যথেষ্ট সবচেয়ে বড় বস্তু আপনার সিস্টেমে সব ব্যবস্থা করতে সক্ষম (যেমন, 8 গিগাবাইট এর একটি স্ট্যাটিক অ্যারে) আকার ধারণ করে হতে নিশ্চিত করা হয়, অপারেটর)।

size_tটাইপ চেয়ে বড়, সমান, বা ছোট একটি চেয়ে হতে পারে unsigned int, এবং আপনার কম্পাইলার অপ্টিমাইজেশান জন্য এটি সম্পর্কে অনুমানের করা হতে পারে।

আপনি সি 99 স্ট্যান্ডার্ড, বিভাগ 7.17, একটি খসড়া পিডিএফ ফর্ম্যাটে অথবা সিডি 11 স্ট্যান্ডার্ড, পিডিএফ খসড়া হিসাবে উপলব্ধ সেকশন 7.19 বিভাগে উপলভ্য একটি খসড়াতে আরও সুনির্দিষ্ট তথ্য পেতে পারেন ।


50
নাঃ। বৃহত্তর (বিশাল নয়) মেমরির মডেলটির সাথে x86-16 সম্পর্কে ভাবুন: পয়েন্টারগুলি অনেক দূরে (32-বিট), তবে স্বতন্ত্র অবজেক্টগুলি 64 কে-তে সীমাবদ্ধ (সুতরাং আকার_টি 16 বিট হতে পারে)।
dan04

8
"বৃহত্তম অবজেক্টের আকার" হ'ল দুর্বল শব্দ নয়, তবে একেবারে সঠিক। কোনও বস্তুর ছয়টি অ্যাড্রেসের জায়গার চেয়ে অনেক বেশি সীমাবদ্ধ হতে পারে।
gnasher729

3
"আপনার সংকলক এটি সম্পর্কে ধারণা তৈরি করতে পারে": আমি আশা করি সংকলকটি প্রতিনিধিত্ব করতে পারে এমন মানগুলির সঠিক পরিসীমাটি জানেsize_t ! যদি তা না হয় তবে কে করে?
মার্ক ভ্যান লিউউয়েন

4
@ মার্ক: আমি মনে করি যে বিষয়টি আরও বেশি ছিল যে সংকলক সেই জ্ঞানের সাথে কিছু করতে সক্ষম হবে ।

8
আমি কেবল চাই যে এই ক্রমবর্ধমান জনপ্রিয় ধরণের জন্য একটি হেডার ফাইল অন্তর্ভুক্তির প্রয়োজন হবে না।
ব্যবহারকারী 2023370

98

ক্লাসিক সি (দ্য সি প্রোগ্রামিং ল্যাঙ্গুয়েজ, প্রিন্টাইস-হল, 1978-তে ব্রায়ান কর্নিগান এবং ডেনিস রিচি দ্বারা বর্ণিত সি এর প্রাথমিক উপভাষা) সরবরাহ করেনি size_tsize_tএকটি বহনযোগ্যতা সমস্যা দূর করতে সি স্ট্যান্ডার্ড কমিটি চালু করেছে

এম্বেডডটকম এ বিস্তারিত ব্যাখ্যা করা হয়েছে (খুব ভাল উদাহরণ সহ)


6
সাইজ_টি এবং পিটার্ডিফ_টি উভয়ই ব্যাখ্যা করে আরেকটি দুর্দান্ত নিবন্ধ: viva64.com/en/a/0050
ইহোর কাহারলিচেনকো

73

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

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

সুতরাং, আপনি জিজ্ঞাসা করুন, কেন শুধু একটি ব্যবহার করবেন না unsigned int? এটি যথেষ্ট পরিমাণে ধরে রাখতে সক্ষম নাও হতে পারে। একটি বাস্তবায়নে যেখানে unsigned int32 বিট হয়, এটি উপস্থাপন করতে পারে এমন বৃহত্তম সংখ্যা 4294967295। আইপি 16 এল 32 এর মতো কিছু প্রসেসর বাইটসের চেয়ে বড় অবজেক্টগুলিকে অনুলিপি করতে পারে 4294967295

সুতরাং, আপনি জিজ্ঞাসা, কেন একটি ব্যবহার না unsigned long int? এটি কিছু প্ল্যাটফর্মে একটি পারফরম্যান্স টোল এক্সটেকস করে। স্ট্যান্ডার্ড সি এর জন্য longকমপক্ষে 32 বিট থাকা উচিত। একটি আইপি 16 এল 32 প্ল্যাটফর্ম প্রতিটি 32-বিট দীর্ঘ 16-বিট শব্দের জোড় হিসাবে প্রয়োগ করে। এই প্ল্যাটফর্মগুলিতে প্রায় সমস্ত 32-বিট অপারেটরদের দুটি নির্দেশাবলীর প্রয়োজন, আরও বেশি না, কারণ তারা দুটি 16 বিট খণ্ডে 32 বিটের সাথে কাজ করে। উদাহরণস্বরূপ, 32-বিট দীর্ঘ দীর্ঘ স্থানান্তর করতে সাধারণত দুটি মেশিনের নির্দেশাবলীর প্রয়োজন হয় - প্রতিটি 16-বিট অংশ সরানো।

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


1
এত দিন পরে এ সম্পর্কে মন্তব্য করার জন্য দুঃখিত, তবে আমাকে কেবল একটি সই করা না হওয়া সবচেয়ে বড় সংখ্যাটি নিশ্চিত করতে হয়েছিল - সম্ভবত আমি আপনার পরিভাষাটি ভুল বোঝাবুঝি করছি, তবে আমি ভেবেছিলাম যে সাইন ইন না করা সবচেয়ে বড় সংখ্যাটি হ'ল 4294967295, 65356 হচ্ছে স্বাক্ষরযুক্ত স্বল্পতম সংক্ষিপ্ত।
মিচ

যদি আপনার স্বাক্ষরবিহীন অন্তর্ভুক্ত 32 টি বিট দখল করে থাকে, তবে হ্যাঁ, এটি ধারণ করতে পারে এমন বৃহত্তম সংখ্যাটি 2 ^ 32 - 1, যা 4294967295 (0xffffffff)। আপনার কি আর কোন প্রশ্ন আছে?
গোলাপ পেরোন

3
@ মিচ: সবচেয়ে বড় মান যা একটি ক্যানের মধ্যে উপস্থাপিত হতে unsigned intপারে এবং এটি এক সিস্টেম থেকে অন্য সিস্টেমে পরিবর্তিত হয়। এটি কমপক্ষে হওয়া দরকার 65536, তবে এটি সাধারণত 4294967295এবং 18446744073709551615কিছু সিস্টেমে (2 ** 64-1) হতে পারে ।
কিথ থম্পসন

1
একটি 16 বিট স্বাক্ষরযুক্ত নাটকের অন্তর্ভুক্ত থাকা বৃহত্তম মান 65535, 65536 নয় 65 65536 হিসাবে একটি ছোট তবে গুরুত্বপূর্ণ পার্থক্যটি 16 বিট স্বাক্ষরযুক্ত ইনট্রে 0 এর সমান।
সাই রেবোল্ড

1
@ gnasher729: আপনি কি সি ++ স্ট্যান্ডার্ড সম্পর্কে নিশ্চিত? কিছু সময়ের জন্য অনুসন্ধান করার পরে আমি এই ধারণাটিতে আছি যে তারা সহজেই পূর্ণসংখ্যার ব্যাপ্তি (বাদে unsigned char) সম্পর্কে সমস্ত নিখুঁত গ্যারান্টি সরিয়ে ফেলেছে । স্ট্যান্ডার্ডটিতে কোথাও '65535' বা '65536' স্ট্রিং রয়েছে বলে মনে হয় না, এবং '+32767' কেবলমাত্র (1.9: 9) একটি নোটে দেখা যায় যতটা সম্ভবত সবচেয়ে বড় পূর্ণসংখ্যার উপস্থাপনযোগ্য হয় int; কোনও গ্যারান্টি দেওয়া হয় না যে তার INT_MAXচেয়ে ছোট হতে পারে না!
মার্ক ভ্যান লিউউয়েন

51

সাইজ_টি টাইপ হ'ল মাপ অপারেটর দ্বারা প্রেরিত টাইপ। এটি একটি স্বাক্ষরবিহীন পূর্ণসংখ্যা যা হোস্ট মেশিনে সমর্থিত কোনও মেমরির পরিসরের বাইটে আকার প্রকাশ করতে সক্ষম। এটি (সাধারণত) ptrdiff_t এর সাথে সম্পর্কিত যে ptrdiff_t হল একটি স্বাক্ষরিত পূর্ণসংখ্যা মান যেমন আকার (ptrdiff_t) এবং আকারের (আকার_t) সমান।

সি কোড লেখার সময় আপনার যখনই মেমরি রেঞ্জের সাথে ডিল করা হয় সর্বদা আকার_t ব্যবহার করা উচিত ।

অন্যদিকে ইন্ট টাইপটি মূলত (স্বাক্ষরিত) পূর্ণসংখ্যা মানের আকার হিসাবে সংজ্ঞায়িত হয় যা হোস্ট মেশিনটি সবচেয়ে দক্ষতার সাথে পূর্ণসংখ্যার পাটিগণিত সম্পাদন করতে পারে। উদাহরণস্বরূপ, অনেক পুরানো পিসি টাইপ কম্পিউটারে মান আকার (সাইজ_টি) 4 (বাইট) হবে তবে আকারের (ইনট) 2 (বাইট) হবে। 16 বিট পাটিগণিত 32 বিট গাণিতিকের চেয়ে দ্রুততর ছিল, যদিও সিপিইউ 4 জিবিবি পর্যন্ত একটি (লজিকাল) মেমরি স্পেস পরিচালনা করতে পারে।

আপনি দক্ষতার বিষয়ে যত্ন নিচ্ছেন কেবল তখনই টাইপটি ব্যবহার করুন কারণ এর প্রকৃত নির্ভুলতা সংকলক বিকল্প এবং মেশিন আর্কিটেকচার উভয়ের উপরই দৃ strongly়ভাবে নির্ভর করে। বিশেষত সি স্ট্যান্ডার্ডটি নিম্নলিখিত আক্রমণকারীদের নির্দিষ্ট করে: মাপের (চর) <= সাইজফ (সংক্ষিপ্ত) <= সাইজফ (ইনট) <= সাইজফ (দীর্ঘ) প্রতিটিটির জন্য প্রোগ্রামারের কাছে উপলব্ধ নির্ভুলতার প্রকৃত উপস্থাপনার জন্য কোনও সীমাবদ্ধতা না রেখে এই আদিম ধরণের।

দ্রষ্টব্য: এটি জাভা-এর মতো নয় (যা প্রকৃতপক্ষে 'চর', 'বাইট', 'সংক্ষিপ্ত', 'আন্ত' এবং 'দীর্ঘ' প্রকারের জন্য বিট যথার্থতা নির্দিষ্ট করে)।


ইন্টের প্রকৃত সংজ্ঞাটি এটি 16 মেশিনে 16 বিট এবং আরও বড় কিছুতে 32 বিট। খুব বেশি কোড লেখা হয়েছে যা ধরে নিচ্ছে যে intটি 32 বিট প্রশস্ত, এখনই এটি পরিবর্তন করতে এবং ফলস্বরূপ লোকেরা সর্বদা আকার_ t বা use, u} int {8,16,32,64} _t ব্যবহার করতে হবে যদি তারা নির্দিষ্ট কিছু চায় - - একটি সতর্কতা হিসাবে, লোকেরা সবসময় অবিচ্ছেদ্য পূর্ণসংখ্যার ধরণের পরিবর্তে এগুলি ব্যবহার করা উচিত।
ক্লিয়ারার

3
"এটি একটি স্বাক্ষরযুক্ত স্বাক্ষর পূর্ণসংখ্যা যা হোস্ট মেশিনে সমর্থিত কোনও মেমোরি রেঞ্জের বাইটে আকারটি প্রকাশ করতে সক্ষম।" -> নং size_tকোনও একক বস্তুর আকারের প্রতিনিধিত্ব করতে সক্ষম (যেমন: সংখ্যা, অ্যারে, কাঠামো)। পুরো মেমরির পরিসীমা অতিক্রম করতে পারেsize_t
chux - মনিকা

"সি কোড লেখার সময় যখনই মেমরির ব্যাপ্তিগুলি ব্যবহার করে আপনার সর্বদা আকার_t ব্যবহার করা উচিত" " - এটি সূচিত করে যে প্রতিটি অ্যারেতে প্রতিটি সূচক হওয়া উচিত size_t- আমি আশা করি আপনি এটির অর্থটি বোঝেন নি। বেশিরভাগ সময় আমরা অ্যারেগুলির সাথে চুক্তি করি না যেখানে ঠিকানা জায়গার কার্ডিনালিটি + বহনযোগ্যতা এমনকি গুরুত্বপূর্ণ। এই ক্ষেত্রে আপনি নিতে হবে size_t। অন্য প্রতিটি ক্ষেত্রে আপনি (স্বাক্ষরিত) পূর্ণসংখ্যার বাইরে সূচকগুলি গ্রহণ করেন। কারণ স্বাক্ষরবিহীনদের নিঃসন্দেহে আন্ডারফ্লো আচরণ থেকে উদ্ভূত বিভ্রান্তি (অন্যান্য বিষয়গুলির মধ্যে বহনযোগ্য পোর্টিবিলিটি সমস্যাগুলির চেয়ে বেশি সাধারণ এবং খারাপ)।
johannes_lalala

23

টাইপ সাইজ_টি কোনও সম্ভাব্য বস্তুর আকার সঞ্চয় করতে অবশ্যই যথেষ্ট বড় হতে হবে। স্বাক্ষরবিহীন ইন্টের শর্তটি পূরণ করতে হবে না।

উদাহরণস্বরূপ 64৪ বিট সিস্টেমে ইন এবং স্বাক্ষরবিহীন ইন্টি 32 বিট প্রশস্ত হতে পারে তবে 4 জি এর চেয়ে বড় সংখ্যার সংরক্ষণের জন্য সাইজ_টি অবশ্যই যথেষ্ট বড় হতে হবে


38
"অবজেক্ট" হ'ল মানক দ্বারা ব্যবহৃত ভাষা।
আর .. গীটহাব বন্ধ করুন ICE এর

2
আমি মনে করি size_tকেবল সংস্থাপক যদি টাইপ এক্সকে গ্রহণ করতে পারে তবে আকারের (এক্স) 4 জি এর চেয়ে বড় মান পাওয়া যায়। বেশিরভাগ সংকলকগণ উদাহরণস্বরূপ প্রত্যাখ্যান করবেন typedef unsigned char foo[1000000000000LL][1000000000000LL]এবং এমনকি foo[65536][65536];এটি কোনও ডকুমেন্টেড বাস্তবায়ন-সংজ্ঞায়িত সীমা ছাড়িয়ে গেলে আইনত বাতিলও হতে পারে।
সুপারক্যাট

1
@ ম্যাটজাইনার: শব্দটি ঠিক আছে। "অবজেক্ট" মোটেই অস্পষ্ট নয়, বরং এটি "স্টোরেজের অঞ্চল" বলতে সংজ্ঞায়িত করা হয়েছে।
অরবিট

4

গ্লিবসি ম্যানুয়াল 0.02 থেকে এই অংশটি বিষয়টি গবেষণা করার সময়ও প্রাসঙ্গিক হতে পারে:

২.৪ প্রকাশের আগে জিসিসির আকার_টি টাইপ এবং সংস্করণগুলিতে একটি সম্ভাব্য সমস্যা রয়েছে। এএনএসআই সি এর জন্য প্রয়োজনীয় যে আকার_টি সর্বদা স্বাক্ষরবিহীন প্রকারের হয়। বিদ্যমান সিস্টেমগুলির শিরোলেখ ফাইলগুলির সাথে সামঞ্জস্যের জন্য, জিসিসি stddef.h' to be whatever type the system'sসাইজ / প্রকারের মধ্যে সাইজ_টাকে সংজ্ঞায়িত করে 'এটি হতে সংজ্ঞায়িত করে। বেশিরভাগ ইউনিক্স সিস্টেম যা সাইজ_টাকে `sys / প্রকারের h 'তে সংজ্ঞায়িত করে, এটি একটি স্বাক্ষরিত প্রকার হিসাবে সংজ্ঞায়িত করে। লাইব্রেরিতে কিছু কোড সাইজ_টায় একটি স্বাক্ষরবিহীন প্রকারের উপর নির্ভর করে এবং এটি স্বাক্ষরিত হলে সঠিকভাবে কাজ করবে না।

জিএনইউ সি লাইব্রেরি কোড যা সাইজ_টি স্বাক্ষরযুক্ত হওয়ার প্রত্যাশা করে তা সঠিক। একটি স্বাক্ষরিত টাইপ হিসাবে আকার_t এর সংজ্ঞাটি ভুল। আমরা পরিকল্পনা করি যে ২.৪ সংস্করণে, জিসিসি সর্বদা fixincludes' script will massage the system'sসাইজ_টাকে স্বাক্ষরবিহীন প্রকার হিসাবে এবং সিএস / প্রকার।

এর মধ্যে, আমরা GNU সি লাইব্রেরিটি সংকলন করার সময় GCC কে আকার_ t এর জন্য স্বাক্ষরযুক্ত প্রকারটি স্পষ্টভাবে বলার মাধ্যমে এই সমস্যাটি নিয়ে কাজ করি। `কনফিগার 'স্বয়ংক্রিয়ভাবে সনাক্ত করবে যে কোন ধরণের জিসিসি আকার_t এর জন্য কী প্রয়োজন তা যদি প্রয়োজন হয় তবে ওভাররাইডের ব্যবস্থা করে।


2

যদি আমার সংকলকটি 32 বিটে সেট করা থাকে তবে size_tএটি টাইপডেফ ছাড়া অন্য কিছু নয় unsigned int। যদি আমার সংকলকটি bit৪ বিটে সেট করা size_tথাকে তবে টাইপডেফ ছাড়া অন্য কিছু নয় unsigned long long


1
unsigned longকিছু OS এ উভয় ক্ষেত্রেই কেবল সংজ্ঞায়িত করা যায় ।
স্ট্যাসিগার্ল

-4

সাইজ_টি একটি পয়েন্টারের আকার।

সুতরাং 32 বিট বা সাধারণ ILP32 (পূর্ণসংখ্যা, দীর্ঘ, পয়েন্টার) মডেলের আকার_ 32 বিট। এবং b৪ বিট বা সাধারণ LP64 (দীর্ঘ, পয়েন্টার) মডেলের আকার_ size৪ বিট (পূর্ণসংখ্যা এখনও 32 বিট) are

অন্যান্য মডেল রয়েছে তবে এটি হ'ল জি ++ ব্যবহার করুন (কমপক্ষে ডিফল্ট হিসাবে)


15
size_tএটি সাধারণত পয়েন্টার হিসাবে একই আকারের নয়, যদিও এটি সাধারণত। একটি পয়েন্টার স্মৃতিতে যে কোনও অবস্থানকে নির্দেশ করতে সক্ষম হতে হবে; size_tবৃহত্তম একক বস্তুর আকারকে উপস্থাপন করতে কেবল যথেষ্ট বড় হতে হবে।
কিথ থম্পসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.