`আকার_t` এর জন্য আমার কোন শিরোনাম অন্তর্ভুক্ত করা উচিত?


98

Cppreferences.com অনুসারে size_tবেশ কয়েকটি শিরোনামে সংজ্ঞায়িত করা হয়, যথা

<cstddef>
<cstdio>
<cstring>
<ctime>

এবং, সি ++ 11 এর পরেও

<cstdlib>
<cwchar> 

সবার আগে আমি ভাবছি কেন এই ঘটনা? এটি কি ডিআরওয়াই নীতির বিপরীতে নয় ? তবে, আমার প্রশ্নটি হ'ল:

উপরের কোনটি শিরোনাম ব্যবহার করা উচিত size_t? এটা কি আদৌ কিছু যায় আসে?


4
সংশ্লিষ্ট হেডার ফাইলগুলি খুলুন এবং সংজ্ঞাটি সন্ধান করুন।
আই 486

35
@ i486 - ভঙ্গুর নন-পোর্টেবল কোড লেখার এটি দুর্দান্ত উপায়!
শান

4
@ পানাগিওটিসকানাভস সি শিরোনামগুলি যা সি ++ স্ট্যান্ডার্ড লাইব্রেরির অংশ এবং সম্ভবত আপনার কোনও সত্য 'সি সি ++' শিরোনামে নকল করা হয়নি। আপনার বক্তব্য ঠিক কি ছিল?
আন্ডারস্কোর_

14
আমি সবসময় ব্যবহার করা <cstddef>জন্যstd::size_t
Boiethios

4
@ পানাগিওটিসকানাভোস নিশ্চিত, সাধারণত এটি ভাল পরামর্শ, তবে এই ক্ষেত্রে এটি প্রাসঙ্গিক বলে মনে হচ্ছে না - কারণ এর জন্য কোনও সি ++ প্রতিস্থাপন নেই std::size_t, এবং ওপি লিগ্যাসি সি ফাংশনগুলি ব্যবহার করার পক্ষে পরামর্শ দিচ্ছিল না, কেবল টাইপিডেফ ভাগ করে নেওয়ার বিষয়ে উক্তিটি পর্যবেক্ষণ করেছিল। আমি সন্দেহ করি যে এই থ্রেডটি পড়ছেন এমন কারও কারণে উত্তরাধিকারের ধরণ / ফাংশনগুলি ব্যবহার করে বিভ্রান্ত করা হবে তবে আপনি যদি নিশ্চিত হন যে তারা তা না করেন তবে যথেষ্ট ন্যায্য!
আন্ডারস্কোর_

উত্তর:


94

ধরে নিচ্ছি যে আমি যে ফাংশন এবং প্রকারগুলি আমদানি করছি তা হ্রাস করতে চাইছিলাম কারণ আমি cstddefএটি দিয়ে যাচ্ছি কারণ এটি কোনও ফাংশন এবং কেবল declare প্রকারের ঘোষণা দেয় না। অন্যরা নির্দিষ্ট ডোমেনগুলিতে মনোযোগ দেয় (স্ট্রিং, সময়, আইও) যা আপনার পক্ষে গুরুত্বপূর্ণ নয়।

নোট করুন যে cstddefকেবলমাত্র সংজ্ঞা দেওয়ার জন্য গ্যারান্টি দেয় std::size_t, অর্থাত্ size_tনেমস্পেসের সংজ্ঞা দেওয়া std, যদিও এটি এই নামটি বিশ্বব্যাপী নেমস্পেসেও প্রদান করতে পারে (কার্যকরভাবে, সমতল size_t)।

বিপরীতে, stddef.h(যা সি তে একটি শিরোনামও উপলব্ধ) size_tগ্লোবাল নেমস্পেসে সংজ্ঞায়িত করার গ্যারান্টি দেয় এবং এটি সরবরাহও করতে পারে std::size_t


4
এর কি কোনও গ্যারান্টি আছে যে size_tকাছ থেকে cstddefএকই এবং সর্বদা অন্যদের মতো একই থাকবে? দেখে মনে হচ্ছে সাধারণ সংজ্ঞা সহ একটি সাধারণ শিরোনাম ফাইল থাকা উচিত size_t...
স্নেকডোক

4
@ স্নেকডোক এবং যাদু দ্বারা, অন্য একটি উত্তর ইতিমধ্যে 'অভ্যন্তরীণ' শিরোনামের মাধ্যমে ঠিক এমনটি ঘটেছে তা পর্যবেক্ষণ করেছে।
আন্ডারস্কোর_

4
@ স্নেকডোক হ্যাঁ, এবং এটি শিরোনাম cstddef
ব্যবহারকারী 253751

4
@ স্নেকডোক, কে বলেছেন যে তারা তাদের নিজস্ব সংজ্ঞা দিয়েছে? সমস্ত স্ট্যান্ডার্ড বলছে যে এটি শিরোনামগুলি অন্তর্ভুক্ত করার পরে এটি সংজ্ঞায়িত করা হবে, এটি তাদের সমস্তকে এটি নতুন করে সংজ্ঞায়িত করতে হবে না। এগুলি সমস্ত অন্তর্ভুক্ত থাকতে পারে <cstddef>, বা তারা সকলেই কিছু অভ্যন্তরীণ শিরোনাম অন্তর্ভুক্ত করতে পারে যা কেবলমাত্র সংজ্ঞায়িত করে size_t
জোনাথন ওয়েকেলি

4
csttddefউত্তরে কি টাইপো আছে? হতে পারে cstddefমানে?
এরিক সিজিল্যান্ড

47

প্রকৃতপক্ষে বেশ কয়েকটি শিরোনামের সংশ্লেষ (সি ++ স্ট্যান্ডার্ডের অন্তর্ভুক্ত) নির্দিষ্টভাবে অন্তর্ভুক্ত size_tকরার সাথে সাথে আরও শিরোনামগুলি প্রকারটিকে সংজ্ঞায়িত করে size_t( শিরোনামের ভিত্তিতে <cX>শিরোনাম কেবলমাত্র আইএসও সি <X.h>হেডার যেখানে উল্লেখযোগ্য পরিবর্তন রয়েছে যেখানে অপসারণ size_tনির্দেশিত নয়)।

C ++ স্ট্যান্ডার্ডের তবে বোঝায় <cstddef>সংজ্ঞা জন্যstd::size_t

  • মধ্যে 18.2 প্রকারভেদ ,
  • মধ্যে 5.3.3 Sizeof হয় ,
  • মধ্যে 3.7.4.2 deallocation ফাংশন (যা 18.2 বোঝায়) এবং
  • মধ্যে 3.7.4.1 বরাদ্দ ফাংশন (এছাড়াও 18.2 বোঝায়)।

সুতরাং এবং <cstddef>কেবল যে প্রকার এবং কোনও কার্যকারিতা প্রবর্তন করে না তাই আমি এই শিরোনামটি উপলব্ধ রাখতে প্রস্তুত থাকি std::size_t


কয়েকটি জিনিস নোট করুন:

  1. প্রকারটি শিরোনাম না দিয়ে std::size_tব্যবহারযোগ্যdecltype

    আপনি যদি যাইহোক আপনার কোডে টাইপডেফ প্রবর্তন করার পরিকল্পনা করছেন (যেমন আপনি একটি ধারক লেখেন এবং টাইপেফ সরবরাহ size_typeকরতে চান ) তবে আপনি বিশ্বব্যাপী sizeof, sizeof...বা alignofঅপারেটরগুলি কোনও প্রকারের শিরোনাম ছাড়াই আপনার প্রকারটি সংজ্ঞায়িত করতে ব্যবহার করতে পারেন যেহেতু থিস অপারেটরগুলি std::size_tপ্রতি ফিরে আসে মানক সংজ্ঞা এবং আপনি decltypeসেগুলি ব্যবহার করতে পারেন :

    using size_type = decltype(alignof(char));
    
  2. std::size_tstd::size_tযুক্তিযুক্ত ফাংশন থাকলেও বিশ্বব্যাপী দৃশ্যমান হয় না ।

    সুস্পষ্টভাবে ঘোষিত বিশ্বব্যাপী বরাদ্দ এবং বিলোপ কার্যকারিতা

    void* operator new(std::size_t);
    void* operator new[](std::size_t);
    void operator delete(void*);
    void operator delete[](void*);
    

    পরিচয় করিয়ে দেবেন না size_t, stdবা std::size_tএবং

    যথাযথ শিরোনামকে অন্তর্ভুক্ত করে নাম ঘোষণা না করা হলে উল্লেখ করা stdবা std::size_tঅসুস্থ হওয়া।

  3. ব্যবহারকারীর পুনরায় সংজ্ঞা দিতে না std::size_tপারলেও একই নামস্থানে একই ধরণের উল্লেখ করা একাধিক টাইপিডফ থাকতে পারে।

    যদিও, এর size_tমধ্যে একাধিক সংজ্ঞা সংঘটন 7.১.৩ / 3std অনুযায়ী পুরোপুরি বৈধ , এটি 17,6.2.2.1 / 1 অনুযায়ী কোনও ঘোষণা যুক্ত করার অনুমতি দেয় না :namespace std

    যদি C ++ প্রোগ্রামের আচরণটি অপরিজ্ঞাত হয় তবে যদি এটি নামফলন স্টাডিতে বিবৃতি বা সংজ্ঞা যুক্ত করে থাকে বা অন্যথায় নির্দিষ্ট না করা হয় তবে নেমস্পেসের std এর মধ্যে একটি নেমস্পেসের সাথে নাম বা স্থান যুক্ত করে।

    size_tনেমস্পেসের জন্য উপযুক্ত টাইপডেফ যোগ করা 7.১.৩ লঙ্ঘন করে না তবে এটি ১.6..6.৪.২.১ লঙ্ঘন করে এবং অনির্ধারিত আচরণের দিকে পরিচালিত করে।

    স্পষ্টকরণ: .1.১.৩ এর ভুল ব্যাখ্যা না দেওয়ার চেষ্টা করুন এবং এর সাথে কোনও ঘোষণা বা সংজ্ঞা সংযোজন করবেন না std(কয়েকটি টেম্পলেট বিশেষায়নের ক্ষেত্রে যেখানে টাইপডেফ কোনও টেম্পলেট বিশেষীকরণ নয়)। প্রসারিত হচ্ছেnamespace std


4
আপনি সত্যটি মিস করেছেন যে কোনও সদৃশ টাইপইডেফ কোনও নতুন প্রকারের পরিচয় দেয় না। এটি কেবল একটি সদৃশ টাইপইডেফ যুক্ত করে, যা পুরোপুরি বৈধ।
ম্যাক্সিম এগারুশকিন

@ ম্যাক্সিম এগারোশকিন: আমি দাবি করি না যে একটি নতুন সংজ্ঞা টাইপএফকে যুক্ত stdকরা অবৈধ কারণ নকল টাইপিডেফগুলি অবৈধ। আমি বলেছি যে এটি অবৈধ কারণ আপনি কেবলমাত্র সংজ্ঞাগুলি যোগ করতে পারেন না namespace std- সেগুলি আইনী হবে কিনা তা বিবেচনা করুন।
পিক্সেল কেমিস্ট

এই সমস্ত স্ট্যান্ডার্ড উক্তি থেকে আমরা জানি সমস্ত কি দেওয়া সম্ভব?
ম্যাক্সিম এগারুশকিন

12
@ ম্যাক্সিমএগরোশকিন: যে কোনও কিছু। অপরিবর্তিত আচরণটি এটাই, তাই না? বিন্দুর সাহায্যে পারে কাজ বা এমনকি বিন্দু এটি নেই কোনো অবাধ কম্পাইলার বিরতি না প্রোগ্রাম মানক অনুযায়ী সংজ্ঞায়িত আচরণ দেখা যায় না। বা 'ফ্রেডওভারফ্লো' হিসাবে এটি এখানে সুন্দরভাবে রেখেছেন : "সি ++ স্ট্যান্ডার্ডের একমাত্র ভোট, সময়কাল।"
পিক্সেল কেমিস্ট

আমি চাই আপনি আপনার সমালোচনামূলক চিন্তাভাবনাটি ব্যবহার করুন। সম্ভাব্যভাবে কি ভাঙ্গতে পারে?
ম্যাক্সিম এগারুশকিন

9

সমস্ত স্ট্যান্ডার্ড লাইব্রেরির শিরোনাম ফাইলগুলির একই সংজ্ঞা রয়েছে; আপনি নিজের কোডে কোনটিকে অন্তর্ভুক্ত করবেন তা বিবেচ্য নয়। আমার কম্পিউটারে, আমার কাছে নিম্নলিখিত ঘোষণা আছে _stddef.h। আপনার তালিকাভুক্ত প্রতিটি ফাইল এই ফাইলটি অন্তর্ভুক্ত করে।

/*
   Define the size_t type in the std namespace if in C++ or globally if in C.
   If we're in C++, make the _SIZE_T macro expand to std::size_t
*/

#if !defined(_SIZE_T) && !defined(_SIZE_T_DEFINED)
#  define _SIZE_T_DEFINED
#if defined(_WIN64)
   typedef unsigned __int64 size_t;
#else
   typedef unsigned int size_t;
#endif
#  if defined(__cplusplus)
#    define _SIZE_T std::size_t
#  else
#    define _SIZE_T size_t
#  endif
#endif

4
নিশ্চিত নয়, তবে আমি মনে করি এটি সংকলনের সময়টির জন্য গুরুত্বপূর্ণ, না?
idclev 463035818

@ tobi303 এই নির্দিষ্ট প্রশ্নের জন্য নয়। হ্যাঁ, আপনি প্রয়োজনের তুলনায় আরও বড় শিরোনাম যুক্ত করতে পারেন তবে আপনি ইতিমধ্যে সি ++ প্রকল্পে একটি সি হেডার যুক্ত করেছেন head আপনার size_tপ্রথম স্থানে কেন দরকার ?
পানাগিওটিস কানভোস

সংজ্ঞায়িত করতে ওএস ম্যাক্রো স্নিফিং ব্যবহার করা ভাল ধারণা নয় size_t। আপনি এটি আরও বহনযোগ্য হিসাবে সংজ্ঞায়িত করতে পারেন using size_t = decltype( sizeof( 42 ) )। তবে কোনও প্রয়োজন নেই, যেহেতু <stddef.h>প্রায় শূন্যের দাম রয়েছে।
চিয়ার্স এবং এইচটিএইচ - আলফ

4

আপনি শিরোনাম ছাড়া করতে পারেন:

using size_t = decltype(sizeof(int));
using size_t = decltype(sizeof 1); //  The shortest is my favourite.
using size_t = decltype(sizeof "anything");

এটি কারণ সি ++ স্ট্যান্ডার্ডের প্রয়োজন:

ফলাফল sizeofএবং sizeof...ধরণের ধ্রুবক std::size_t। [দ্রষ্টব্য: std::size_tমানক শিরোনামে <cstddef>(18.2) সংজ্ঞায়িত করা হয়েছে । - শেষ নোট]

অন্য কথায়, মানটির প্রয়োজন:

static_assert(std::is_same<decltype(sizeof(int)), std::size_t>::value,
              "This never fails.");

এছাড়াও মনে রাখবেন, typedefবিশ্বব্যাপী এবং stdনেমস্পেসে এই ঘোষণাটি করা পুরোপুরি ঠিক আছে , যতক্ষণ না typedefএটি একই টাইপডেফ-নামের অন্যান্য সমস্ত ঘোষণার সাথে মেলে না ( মিলনীয় ঘোষণার ক্ষেত্রে একটি সংকলক ত্রুটি জারি করা হয়)।

এই কারণ:

  • §§.১.৩.১ একটি টাইপিডেফ -নাম কোনও শ্রেণির ঘোষণা (9.1) বা এনাম ডিকোলেমেনশন করার উপায়ে নতুন ধরণের পরিচয় দেয় না।

  • §§.১.৩.৩ একটি প্রদত্ত অ-শ্রেণীর স্কোপে একটি typedefস্পেসিফায়ার সেই সুযোগে ঘোষিত যে কোনও প্রকারের নামটি এরই মধ্যে উল্লেখ করে যা এটি ইতিমধ্যে উল্লেখ করে rede


সন্দিহানরা এই কথাটি বলে যে এটি নেমস্পেসে একটি নতুন ধরণের সংযোজন গঠন করে std, এবং এই জাতীয় আইনটি স্ট্যান্ডার্ড দ্বারা স্পষ্টভাবে নিষিদ্ধ করা হয়, এবং এটি ইউবি এবং এটি এখানে রয়েছে; আমার বলতে হবে যে এই মনোভাবটি অন্তর্নিহিত বিষয়গুলির গভীর বোঝাকে উপেক্ষা করা এবং অস্বীকার করার সমান।

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

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

... পূর্ববর্তী ক্ষেত্রে, এখন যে প্রযুক্তিটি আরও ভালভাবে বোঝা গেছে, সেই সিদ্ধান্তটি এখনও মূলত সঠিক বলে মনে হচ্ছে। হ্যাঁ, কিছু ক্ষেত্রে স্ট্যান্ডার্ড পাত্রে কিছু কার্যকর করা সম্ভব হয় যাতে সেগুলি অসম্পূর্ণ প্রকারের সাথে ইনস্ট্যান্ট করা যায় - তবে এটি আরও স্পষ্ট যে অন্যান্য ক্ষেত্রে এটি কঠিন বা অসম্ভব হতে পারে। এটি বেশিরভাগই সুযোগ ছিল যে আমরা যে প্রথম পরীক্ষাটি ব্যবহার করে চেষ্টা করেছিলাম std::vectorতা সহজ ঘটনাগুলির একটি হয়ে থাকে।

প্রদত্ত যে ভাষার নিয়মগুলি std::size_tহুবহু হওয়া দরকার decltype(sizeof(int)), করানো namespace std { using size_t = decltype(sizeof(int)); }সেই জিনিসগুলির মধ্যে একটি যা কোনও কিছুতেই ভাঙে না।

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

সি ++ 11 এ এখন স্ট্যান্ডার্ডের সেই সঠিক প্রয়োজনীয়তাটিকে একটি সাধারণ ঘোষণা হিসাবে লেখার উপায় রয়েছে।


6
@ শিয়ান আপনি যা লিখেছেন তা কোনও অর্থবোধ করে না।
ম্যাক্সিম এগারুশকিন

15
@ ম্যাক্সিমএগরোশকিন তাদের মধ্যে অর্ধেক এই কোডটি বুঝতে পারেন নি ... এটি পুরোপুরি কার্যকর হয়। তবে, আমি এইভাবে পছন্দ করি না: ইমো, একটি শিরোনাম অন্তর্ভুক্ত করা এবং মানটিকে এটি সংজ্ঞায়িত করা ভাল better
বোয়াইটিওস

9
ছেলেরা, পুরোপুরি সঠিক উত্তরগুলিকে নিম্নমুখী করার আগে কমপক্ষে কার্যকর ভাষাটি শিখুন।
ফ্রেডেরিক হামিদি

11
টম বলেছিলেন, "একই জিনিস সংজ্ঞায়িত করার জন্য 6 টি স্ট্যান্ডার্ড লাইব্রেরি শিরোনাম রয়েছে! এটি উন্মাদ! আমাদের একটির এবং কেবল একটির সংজ্ঞা দরকার size_t!" এক মিনিট পরে মেরি বললেন, "ওএমজি! size_tপ্রমিত লাইব্রেরি শিরোনামের 7 টি সংজ্ঞা রয়েছে এবং একটি প্রকল্প শিরোনাম টম সম্পাদনা করছে! তৃতীয় পক্ষের লাইব্রেরিতে সম্ভবত আরও কিছু রয়েছে!" xkcd.com/927

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