Uintptr_t ডেটা টাইপ কী


252

কী uintptr_tএবং এটি কী জন্য ব্যবহার করা যেতে পারে?


5
এই ধরণের পাশাপাশি অন্যান্য সম্পর্কিত ধরণের অতিরিক্ত বিবরণগুলি এখানে পাওয়া যায়: opengroup.org/onlinepubs/000095399/basedefs/stdint.h.html
অকার্যকর

en.cppreferences.com/w/cpp/tyype/integer তালিকা std::uintptr_tএবং std::intptr_tএকটি সি ++ 11 .চ্ছিক
alfC

উত্তর:


198

uintptr_tএকটি স্বাক্ষরবিহীন পূর্ণসংখ্যা টাইপ যা ডেটা পয়েন্টার সংরক্ষণের জন্য সক্ষম। যার সাধারণত অর্থ এটি পয়েন্টার হিসাবে একই আকার।

এটি সি ++ 11 এবং পরবর্তী মানেরগুলিতে optionচ্ছিকভাবে সংজ্ঞায়িত করা হয়েছে।

একটি আর্কিটেকচারের পয়েন্টার টাইপ ধরে রাখতে পারে এমন একটি পূর্ণসংখ্যার প্রকারের সাধারণ কারণ হ'ল একটি পয়েন্টারে পূর্ণসংখ্যা-নির্দিষ্ট ক্রিয়াকলাপ সম্পাদন করা, বা কোনও পূর্ণসংখ্যার "হ্যান্ডেল" হিসাবে সরবরাহ করে পয়েন্টারটির প্রকারটিকে অস্পষ্ট করে তোলা।

সম্পাদনা করুন: নোট করুন যে স্টিভ জেসপের কাছে আপনার পেডেন্টিক প্রকারের জন্য এখানে আরও একটি উত্তরে কিছু আকর্ষণীয় অতিরিক্ত বিশদ রয়েছে (যা আমি চুরি করব না) :)


53
মনে রাখবেন যে size_tবৃহত্তমতম অবজেক্টের আকার ধারণ করার জন্য কেবল পর্যাপ্ত পরিমাণের প্রয়োজন এবং এটি কোনও পয়েন্টারের চেয়ে ছোট হতে পারে। এটি 8086 (16 বিট size_t, তবে 32 বিট void*) এর মতো
বিভাগযুক্ত

3
দুটি পয়েন্টারের মধ্যে পার্থক্য উপস্থাপনের জন্য, আপনার কাছে রয়েছে ptrdiff_tuintptr_tএর জন্য নয়
জাল্ফ

3
@ জাল্ফ: পার্থক্যের জন্য, হ্যাঁ, তবে দূরত্বের জন্য আপনি একটি স্বাক্ষরবিহীন প্রকার চান।
ড্রয় ডোরম্যান

uintptr_t সংজ্ঞা দৃশ্যত বাধ্যতামূলক নয় (সুতরাং মান নয়) এমনকি সি ++ 11 তেও! cplusplus.com/references/cstdint (স্টিভ জেসোপের উত্তর থেকে আমি ইঙ্গিতটি পেয়েছি)
আন্তোনিও

2
@ মার্কাসজে unsigned intসাধারণত যথেষ্ট পরিমাণে বড় হয় না। তবে এটি যথেষ্ট বড় হতে পারে। এই ধরণেরটি সমস্ত "ধরে নেওয়া" মুছে ফেলার জন্য বিশেষভাবে বিদ্যমান ।
ড্রু ডোরম্যান

238

প্রথম জিনিস, যখন প্রশ্নটি জিজ্ঞাসা করা হয়েছিল, uintptr_tতখন সি ++ তে ছিল না। এটি সি 99 এ <stdint.h>, একটি alচ্ছিক প্রকার হিসাবে। অনেক সি ++ 03 সংকলক ফাইলটি সরবরাহ করে। এটি সি ++ এও রয়েছে <cstdint>, যেখানে আবার এটি alচ্ছিক এবং এটি সংজ্ঞাটির জন্য C99 কে বোঝায়।

C99-তে, এটি এমন সংজ্ঞা হিসাবে সংজ্ঞা দেওয়া হয় যে "সম্পত্তিটির সাথে স্বাক্ষরবিহীন পূর্ণসংখ্যা টাইপ যা কোনও বৈধ পয়েন্টারকে শূন্যে রূপান্তর করতে পারে, তারপরে আবার পয়েন্টারটিকে শূন্যে রূপান্তরিত করা যায় এবং ফলাফলটি মূল পয়েন্টারের সমান তুলনা করবে"।

এটি যা বলে তা বোঝাতে এটি নিন। এটি আকার সম্পর্কে কিছু বলে না।

uintptr_tএকটি হিসাবে একই আকার হতে পারে void*। এটি আরও বড় হতে পারে। এটি সম্ভবত ছোট হতে পারে, যদিও এই জাতীয় সি ++ বাস্তবায়ন বিকৃত হয়। উদাহরণস্বরূপ এমন কিছু অনুমানের প্ল্যাটফর্ম যেখানে void*32 বিট, তবে ভার্চুয়াল ঠিকানার স্থানের 24 বিট ব্যবহার করা হয়, আপনার 24-বিট থাকতে পারে uintptr_tযা প্রয়োজনীয়তা পূরণ করে। কোনও বাস্তবায়ন কেন এটি করবে তা আমি জানি না, তবে মানক এটির অনুমতি দেয়।


8
"<Stdint.h>" এর জন্য ধন্যবাদ। Uintptr_t ঘোষণার কারণে আমার অ্যাপ্লিকেশনটি সংকলন করে নি। তবে যখন আমি আপনার মন্তব্যটি পড়ি আমি "# অন্তর্ভুক্ত <stdint.h>" যোগ করি এবং হ্যাঁ এখন এটি কার্যকর হয়। ধন্যবাদ!
জাভাআরনার

2
উদাহরণস্বরূপ, অন্যান্য ব্যবহারের মধ্যে সারিবদ্ধ মেমরি বরাদ্দ করতে ?
কিংবদন্তি 2 কে

4
কোনও ইন্টিতে পয়েন্টার castালাইয়ের আর একটি সাধারণ ব্যবহারের ক্ষেত্রে হ'ল একটি অস্বচ্ছ হ্যান্ডেল তৈরি করা যা পয়েন্টারটি আড়াল করে। এটি আপনি যেখানে লাইব্রেরিতে অবজেক্টটি ব্যক্তিগত রাখতে এবং অ্যাপ্লিকেশনগুলিকে এর অ্যাক্সেস থেকে আটকাতে চান এমন APIs থেকে কোনও অবজেক্টের রেফারেন্স ফিরিয়ে দেওয়ার জন্য দরকারী। এর পরে অ্যাপ্লিকেশনটি
জোয়েল কানিংহাম

3
@ জোয়েলকানিংহাম: এটি কাজ করে তবে ব্যবহার করা সত্যিই আলাদা নয় void*। এটি সম্ভাব্য ভবিষ্যতের দিকনির্দেশকে প্রভাবিত করে, বিশেষত যদি আপনি এমন কোনও কিছু ব্যবহার করতে পরিবর্তন করতে চান যা সত্যিই কেবল একটি পূর্ণসংখ্যার হ্যান্ডেল হয় তবে কোনও রূপান্তরিত পয়েন্টার নয়।
স্টিভ জেসোপ

2
@ সিরোস্যান্টিলি 事件 事件 ২০১六四 六四 事件 法轮功 একটি সাধারণ ব্যবহারের ক্ষেত্রে হ'ল জেনেরিক ডেটাতে কোনও শূন্যতা প্রত্যাশা করে এমন একটি এপিআই'র কাছে কেবল একটি ইনট পাস করা। আপনাকে কীস্ট্রোক সংরক্ষণ করে typedef struct { int whyAmIDoingThis; } SeriouslyTooLong; SeriouslyTooLong whyAmNotDoneYet; whyAmINotDoneYet.whyAmIDoingThis = val; callback.dataPtr = &whyAmINotDoneYet;। পরিবর্তে: callback.dataPtr = (void*)val। অন্যদিকে, আপনি অবশ্যই পান void*এবং এটিকে আবার ফেলে দিতে হবে int
ফ্রান্সেসকো দন্ডি

19

এটি একটি স্বাক্ষরবিহীন পূর্ণসংখ্যার টাইপ হ'ল পয়েন্টারের আকার। যখনই আপনাকে কোনও পয়েন্টারের সাহায্যে অস্বাভাবিক কিছু করার দরকার পড়ে - যেমন সমস্ত বিট উল্টে দিন (কেন জিজ্ঞাসা করবেন না) আপনি এটিকে কাস্ট করেন uintptr_tএবং এটিকে একটি সাধারণ পূর্ণসংখ্যার সংখ্যা হিসাবে ম্যানিপুলেট করেন, তারপরে পিছনে ফেলে দিন।


6
অবশ্যই আপনি এটি করতে পারতেন তবে এটি অবশ্যই অপরিজ্ঞাত আচরণ হবে। আমি বিশ্বাস করি তবে uintptr_t এ কাস্টের ফলাফলের সাথে আপনি যা করতে পারেন তা হ'ল এটিকে অপরিবর্তিত রেখে এটিকে ফেরত দেওয়া - অন্য সব কিছুই ইউবি।
sleske

এমন সময় আছে যেখানে আপনাকে বিটগুলি নিয়ে খেলতে হবে এবং এটি সাধারণত সংকলক ত্রুটি তৈরি করে। একটি সাধারণ উদাহরণ নির্দিষ্ট ভিডিও এবং পারফরম্যান্স সমালোচনামূলক অ্যাপ্লিকেশনগুলির জন্য 16-বাইট প্রান্তিক মেমরি প্রয়োগ করছে। stackoverflow.com/questions/227897/…
মেঘ

3
@ সালসেক যে সত্য নয় যেসব মেশিনগুলিতে স্ব-প্রান্তিককরণ রয়েছে তাদের মধ্যে পয়েন্টারের দুটি অন্তত উল্লেখযোগ্য বিট শূন্য হতে চলেছে (কারণ ঠিকানাগুলি 4 বা 8 এর গুণক)। আমি এমন প্রোগ্রামগুলি দেখেছি যা ডেটা সংকোচনের জন্য
এটির

3
@ এসাদতামে: আমি কেবল উল্লেখ করেছি যে এটি সি স্ট্যান্ডার্ড অনুযায়ী ইউবি । এর অর্থ এই নয় যে এটি কয়েকটি সিস্টেমে সংজ্ঞায়িত করা যায় না - সংকলক এবং রানটাইমগুলি স্ট্যান্ডার্ড সি-তে ইউবি জাতীয় কোনও সুনির্দিষ্ট আচরণের জন্য নির্দ্বিধায় মুক্ত হয় তাই কোনও বিরোধ নেই :-)।
স্ল্যাসকে

2
এটি অগত্যা ঠিক কোনও পয়েন্টারের আকার নয়। সমস্ত স্ট্যান্ডার্ড গ্যারান্টি হ'ল একটি void*পয়েন্টার মানটিকে uintptr_tআবার এবং পিছনে রূপান্তর করলে এমন void*মান পাওয়া যায় যা মূল পয়েন্টারের সাথে সমান তুলনা করে। uintptr_tসাধারণত আকার হিসাবে একই আকার void*, কিন্তু এটি গ্যারান্টিযুক্ত নয়, বা এই কোনও গ্যারান্টিও নয় যে রূপান্তরিত মানের বিটগুলির কোনও বিশেষ অর্থ রয়েছে। এবং কোনও গ্যারান্টি নেই যে এটি কোনও তথ্যের ক্ষতি ছাড়াই রূপান্তরিত পয়েন্টার-টু-ফাংশন মান ধরে রাখতে পারে। অবশেষে, এটির নিশ্চয়তা নেই।
কিথ থম্পসন

15

"Uintptr_t ডেটা টাইপ কী" অংশটির ইতিমধ্যে অনেকগুলি ভাল উত্তর রয়েছে। আমি "এটি কীসের জন্য ব্যবহার করা যেতে পারে?" সম্বোধনের চেষ্টা করব? এই পোস্টে অংশ।

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

সুতরাং পয়েন্টারগুলিতে বিটওয়াইজ অপারেশন করার জন্য পয়েন্টারগুলিকে ইউনিট_প্রাইটি টাইপ করতে হবে এবং তারপরে বিটওয়াইড অপারেশন করা উচিত।

আমি এখানে একটি ক্রিয়াকলাপের উদাহরণ যা আমি কেবল বিটওয়াইজ এক্সক্লুসিভ করার জন্য লিখেছি বা একটি এক্সওআর লিঙ্কযুক্ত তালিকায় 2 পয়েন্টার সংরক্ষণ করার জন্য যাতে আমরা উভয় দিকটি দ্বিগুণ সংযুক্ত তালিকার মতো অতিক্রম করতে পারি তবে প্রতিটি নোডে 2 পয়েন্টার সংরক্ষণের দণ্ড ব্যতীত ।

 template <typename T>
 T* xor_ptrs(T* t1, T* t2)
 {
     return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(t1)^reinterpret_cast<uintptr_t>(t2));
  }

1
বিট গাণিতিক ব্যতীত অন্যটিও ভাল যদি আপনি অবজেক্টের সংখ্যার পরিবর্তে ঠিকানার উপর ভিত্তি করে শব্দার্থবিজ্ঞান রাখতে চান।
অ্যালেক্স

4

আরেকটি নেক্রোম্যান্সার ব্যাজ পাওয়ার ঝুঁকি নিয়ে, আমি uintptr_t (অথবা এমনকি ইন্ট্রিটার_ টি) এর জন্য একটি খুব ভাল ব্যবহার যুক্ত করতে চাই এবং এটি টেস্টেবল এম্বেডড কোড লিখছে। আমি বেশিরভাগ এম্বেড কোড বিভিন্ন বাহু এবং বর্তমানে টেনসিলিকা প্রসেসরে লক্ষ্য করে লিখি। এর বিভিন্ন নেটিভ বাসের প্রস্থ রয়েছে এবং টেনসিলিকা আসলে একটি হার্ভার্ড আর্কিটেকচার যা পৃথক কোড এবং ডেটা বাস যা বিভিন্ন প্রস্থ হতে পারে। আমি আমার কোডের বেশিরভাগের জন্য একটি পরীক্ষা চালিত বিকাশ শৈলী ব্যবহার করি যার অর্থ আমি যে সমস্ত কোড ইউনিট লিখি তার ইউনিট পরীক্ষা করি tests প্রকৃত টার্গেট হার্ডওয়্যারের উপর ইউনিট পরীক্ষা করা একটি ঝামেলা তাই আমি সাধারণত উইন্ডোজ বা লিনাক্সে সিডলিং এবং জিসিসি ব্যবহার করে ইন্টেল ভিত্তিক পিসিতে সবকিছু লিখি। বলা হচ্ছে, এম্বেড করা প্রচুর কোডে বিট টুইডলিং এবং অ্যাড্রেস ম্যানিপুলেশনগুলি জড়িত। আমার বেশিরভাগ ইন্টেল মেশিন 64 বিট। সুতরাং আপনি যদি ঠিকানা ম্যানিপুলেশন কোডটি পরীক্ষা করতে যাচ্ছেন আপনার গাণিতিক করার জন্য আপনার একটি সাধারণ বস্তু প্রয়োজন। সুতরাং uintptr_t আপনি হার্ডওয়ারকে লক্ষ্যবস্তু করার জন্য মোতায়েন করার আগে আপনার কোডটি ডিবাগ করার একটি মেশিনকে স্বাধীন উপায় দেয়। আরেকটি সমস্যা হ'ল কিছু মেশিন বা এমনকি কিছু সংকলকগুলির মেমরি মডেলগুলির জন্য, ফাংশন পয়েন্টার এবং ডেটা পয়েন্টারগুলি পৃথক প্রস্থ। এই মেশিনগুলিতে সংকলক এমনকি দুটি শ্রেণীর মধ্যে কাস্টিংও মঞ্জুর করতে পারে না, তবে uintptr_t উভয়ই রাখতে সক্ষম হবে।


প্রাসঙ্গিক কিনা তা নিশ্চিত নন ... আপনি কি "অস্বচ্ছ টাইপডেফস" চেষ্টা করেছেন?
ভিডিপি

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