সি এর "সত্য" ভেরিয়েবলগুলির আকার কতটা কার্যকর?


9

একটি জিনিস যা সর্বদা স্বজ্ঞাতভাবে আমাকে সি এর ইতিবাচক বৈশিষ্ট্য হিসাবে আঘাত করেছিল (ভাল, আসলে এটির বাস্তবায়ন যেমন জিসিসি, ঝনঝন, ...) এটি রানটাইমে আপনার নিজের ভেরিয়েবলের পাশে কোনও লুকানো তথ্য সংরক্ষণ করে না। এর অর্থ এই যে আপনি উদাহরণস্বরূপ যদি "uint16_t" টাইপের একটি ভেরিয়েবল "x" চান, আপনি নিশ্চিত হতে পারেন যে "x" কেবলমাত্র 2 বাইট জায়গা দখল করবে (এবং এর মতো কোনও গোপন তথ্য বহন করবে না ইত্যাদি) ।)। একইভাবে, আপনি যদি 100 পূর্ণসংখ্যার অ্যারে চেয়েছিলেন তবে আপনি নিশ্চিত হতে পারেন যে এটি 100 সংখ্যার মতো বড়।

তবে, এই বৈশিষ্ট্যটির জন্য আমি যত বেশি কংক্রিট ব্যবহারের মামলাগুলি নিয়ে আসার চেষ্টা করছি ততই আমি ভাবছি যে এটির বাস্তবিক কোনও বাস্তব সুবিধা আছে কিনা । আমি এখন পর্যন্ত কেবলমাত্র যে জিনিসটি সামনে আসতে পেরেছি তা হল এটির স্পষ্টতই কম র‌্যামের প্রয়োজন। সীমিত পরিবেশের জন্য যেমন এভিআর চিপস ইত্যাদি, এটি অবশ্যই একটি বিশাল প্লাস, তবে প্রতিদিনের ডেস্কটপ / সার্ভারের ব্যবহারের ক্ষেত্রে এটি অপ্রাসঙ্গিক বলে মনে হয়। আরেকটি সম্ভাবনার কথা যা আমি ভাবছি তা হ'ল এটি হার্ডওয়ার অ্যাক্সেসের জন্য সহায়ক / গুরুত্বপূর্ণ হতে পারে, বা মেমরি অঞ্চলগুলি ম্যাপিং (উদাহরণস্বরূপ ভিজিএ আউটপুট এবং এর মতো) ...?

আমার প্রশ্ন: এমন কোন কংক্রিট ডোমেন রয়েছে যা এই বৈশিষ্ট্যটি ব্যতীত কেবল খুব জটিলভাবেই কার্যকর করা যায় না?

পিএস দয়া করে আমাকে বলুন যদি এর জন্য আরও ভাল নাম থাকে! ;)



@ নির্গত আমি মনে করি আপনার সমস্যাটি কী তা আমি বুঝতে পারি। একারণে একাধিক উত্তর হতে পারে বলে তাই? ঠিক আছে, আমি পেয়েছি যে এই প্রশ্নটি স্ট্যাকএক্সচেঞ্জের যেভাবে কাজ করে তার জন্য উপযুক্ত নয়, তবে আমি সত্যই জানি না যে কোথায় অন্যভাবে জিজ্ঞাসা করা যায় ...
টমাস অল্টম্যান

1
@lxrec আরটিটিআই ভিটিবেলে সংরক্ষণ করা হয় এবং অবজেক্টগুলি কেবল ভিটিবেলে একটি পয়েন্টার সঞ্চয় করে। অতিরিক্তভাবে, প্রকারগুলিতে কেবলমাত্র আরটিটিআই থাকে যদি তাদের ইতিমধ্যে একটি ভিটিবেল থাকে কারণ তাদের virtualসদস্য কার্য রয়েছে। সুতরাং আরটিটিআই কখনই কোনও বস্তুর আকার বাড়ায় না, এটি কেবল ধ্রুবক দ্বারা বাইনারিকে আরও বড় করে তোলে।

3
@ থমাস ওলটম্যানn প্রতিটি বস্তুর ভার্চুয়াল পদ্ধতিতে একটি ভেটেবল পয়েন্টার প্রয়োজন। এটি ছাড়া আপনার কার্যকারিতা ভার্চুয়াল পদ্ধতি থাকতে পারে না। তদুপরি, আপনি স্পষ্টভাবে ভার্চুয়াল পদ্ধতি (এবং সুতরাং, একটি vtable) থাকার অপশন।

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

উত্তর:


5

বিভিন্ন সুবিধাগুলি রয়েছে, ফাংশন প্যারামিটারের মতো জিনিসগুলি যে মূল্যবোধগুলি পাশ করা হচ্ছে তার সাথে মেলে তা নিশ্চিত করার জন্য সুস্পষ্ট একটি সংকলনের সময়।

তবে আমি মনে করি আপনি রানটাইমে কী ঘটছে সে সম্পর্কে জিজ্ঞাসা করছেন।

মনে রাখবেন যে সংকলক একটি রানটাইম তৈরি করবে যা এটি সম্পাদন করে এমন অপারেশনগুলিতে ডেটা ধরণের জ্ঞানকে এম্বেড করে। স্মৃতিতে থাকা প্রতিটি তথ্যের পরিমাণ স্ব-বর্ণনায় নাও থাকতে পারে তবে কোডটি সহজাতভাবে জানে যে সেই ডেটাটি কী (যদি আপনি নিজের কাজটি সঠিকভাবে করে থাকেন)।

রানটাইমের জিনিসগুলি আপনার ভাবার চেয়ে কিছুটা আলাদা।

উদাহরণস্বরূপ, অনুমান করবেন না যে আপনি যখন uint16_t ঘোষণা করেন তখন কেবল দুটি বাইট ব্যবহার করা হয়। প্রসেসর এবং শব্দ প্রান্তিককরণের উপর নির্ভর করে এটি স্ট্যাকের মধ্যে 16, 32 বা 64 বিট দখল করতে পারে। আপনি দেখতে পাবেন যে আপনার শর্টসের অ্যারে আপনার প্রত্যাশার চেয়ে অনেক বেশি মেমরি গ্রাস করে।

এটি নির্দিষ্ট পরিস্থিতিতে যেখানে আপনার নির্দিষ্ট অফসেটে ডেটা রেফারেন্স করতে হবে সমস্যা হতে পারে। ওয়্যারলেস লিঙ্কের মাধ্যমে বা ফাইলের মাধ্যমে দুটি প্রসেসরের আর্কিটেকচার রয়েছে এমন দুটি সিস্টেমের মধ্যে যোগাযোগ করার সময় এটি ঘটে।

সি আপনাকে বিট স্তরের গ্র্যানুলারালিটি সহ স্ট্রাক্ট নির্দিষ্ট করতে দেয়:

struct myMessage {
  uint8_t   first_bit: 1;
  uint8_t   second_bit: 1;
  uint8_t   padding:6;
  uint16_t  somethingUseful;
}

এই কাঠামোটি তিনটি বাইট দীর্ঘ, একটি সংক্ষিপ্ত সংজ্ঞা দিয়ে বিজোড় অফসেটে শুরু করতে। আপনি যেমনটি সংজ্ঞা দিয়েছিলেন ঠিক তেমনভাবে তৈরি করতে এটিও প্যাক করা দরকার। অন্যথায় সংকলক সদস্যদের শব্দ-সারিবদ্ধ করবে।

সংকলক এই ডেটা বের করার জন্য পর্দার আড়ালে কোড তৈরি করবে এবং একটি রেজিস্টারে অনুলিপি করবে যাতে আপনি এটির সাথে দরকারী জিনিসগুলি করতে পারেন।

এখন আপনি দেখতে পাচ্ছেন যে প্রতিবার আমার প্রোগ্রামটি মাইমেসেজ স্ট্রাক্টের কোনও সদস্যকে অ্যাক্সেস করে, এটি ঠিক কীভাবে এটি নিষ্কাশন করতে এবং এটিতে কাজ করতে হয় তা তা জানতে পারবে।

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

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


2
"আপনি দেখতে পাবেন যে আপনার শর্টসের অ্যারে আপনার প্রত্যাশার চেয়ে অনেক বেশি মেমরি গ্রাস করে।" এটি সিতে ভুল: অ্যারেগুলি তাদের উপাদানগুলিকে ফাঁক-মুক্ত ফ্যাশনে রাখার গ্যারান্টিযুক্ত। হ্যাঁ, অ্যারেটিও সঠিকভাবে প্রান্তিককরণ করা দরকার, যেমন একটি একক হিসাবে short। তবে অ্যারে শুরুর জন্য এটি এক সময়ের প্রয়োজন, বাকিগুলি ক্রমাগত থাকার কারণে স্বয়ংক্রিয়ভাবে সঠিকভাবে সাজানো হয়।
সিমেস্টার

এছাড়াও, প্যাডিংয়ের সিনট্যাক্সটি ভুল, এটি uint8_t padding: 6;প্রথম দুটি বিটের মতো হওয়া উচিত । বা, আরও স্পষ্টভাবে, শুধু মন্তব্য //6 bits of padding inserted by the compiler। কাঠামো, যেমনটি আপনি এটি লিখেছেন, তার আকার কমপক্ষে নয়টি বাইট, তিনটি নয়।
মাস্টার

9

এটি কার্যকর একমাত্র কারণ হিসাবে আপনি আঘাত করেছেন: বাহ্যিক ডেটা স্ট্রাকচার ম্যাপিং। এর মধ্যে মেমরি-ম্যাপযুক্ত ভিডিও বাফার, হার্ডওয়্যার রেজিস্টার ইত্যাদি অন্তর্ভুক্ত রয়েছে এগুলিতে এএসএল শংসাপত্র, আইপি প্যাকেট, জেপিইজি চিত্র এবং প্রোগ্রামের বাইরে অবিচ্ছিন্ন জীবন যাপন করা অন্য কোনও ডেটা স্ট্রাকচারের মতো প্রোগ্রামের বাইরে অক্ষত প্রেরণ করা ডেটা অন্তর্ভুক্ত রয়েছে।


5

সি একটি নিম্ন-স্তরের ভাষা, প্রায় একটি পোর্টেবল অ্যাসেমব্লার, সুতরাং এর ডেটা স্ট্রাকচার এবং ভাষার কাঠামো ধাতুর কাছাকাছি থাকে (ডেটা স্ট্রাকচারের কোনও গোপন ব্যয় থাকে না - প্যাডিং, প্রান্তিককরণ এবং হার্ডওয়্যার এবং এবিআই দ্বারা আরোপিত আকারের সীমাবদ্ধতা বাদে )। সুতরাং সি প্রকৃতপক্ষে স্থানীয়ভাবে গতিময় টাইপিং নেই। তবে আপনার যদি এটির প্রয়োজন হয় তবে আপনি একটি কনভেনশন গ্রহণ করতে পারেন যে আপনার সমস্ত মানগুলি কিছু ধরণের তথ্য (যেমন কিছু enum...) দিয়ে শুরু করে সমষ্টি ; ব্যবহারের union-s এবং (অ্যারে-ভালো জিনিস জন্য) নমনীয় অ্যারের সদস্য মধ্যে structএছাড়াও অ্যারের আকার রয়েছে।

(সি-তে প্রোগ্রামিং করার সময়, দরকারী কনভেনশনগুলি সংজ্ঞায়িত করা, ডকুমেন্ট করা এবং অনুসরণ করা আপনার দায়িত্ব - বিশেষত প্রাক-শর্তাবলী এবং আক্রমণকারীদের; সি গতিশীল মেমরি বরাদ্দকরণের জন্য freeকিছু গতিযুক্ত mallocমেমোরি জোনটি কী উচিত সে সম্পর্কে ব্যাখ্যা সম্মেলন প্রয়োজন )

সুতরাং, মান যা বাক্সযুক্ত পূর্ণসংখ্যার, অথবা স্ট্রিং, বা কোন ধরণের হয় প্রতিনিধিত্ব করতে স্কিম -একটি প্রতীক , অথবা মূল্যবোধের ভেক্টর, আপনি ধারণার দিক থেকে একটি ব্যবহার করব বাঁধা ইউনিয়ন (পয়েন্টার একটি ইউনিয়ন হিসাবে প্রয়োগ করা) -always টাইপ ধরনের দ্বারা শুরু -, যেমন:

enum value_kind_en {V_NONE, V_INT, V_STRING, V_SYMBOL, V_VECTOR};
union value_en { // this union takes a word in memory
   const void* vptr; // generic pointer, e.g. to free it
   enum value_kind_en* vkind; // the value of *vkind decides which member to use
   struct intvalue_st* vint;
   struct strvalue_st* vstr;
   struct symbvalue_st* vsymb;
   struct vectvalue_st* vvect;
};
typedef union value_en value_t;
#define NULL_VALUE  ((value_t){NULL})
struct intvalue_st {
  enum value_kind_en kind; // always V_INT for intvalue_st
  int num;
};
struct strvalue_st {
  enum value_kind_en kind; // always V_STRING for strvalue_st
  const char*str;
};
struct symbvalue_st {
  enum value_kind_en kind; // V_SYMBOL
  struct strvalue_st* symbname;
  value_t symbvalue;
};
struct vectvalue_st {
  enum value_kind_en kind; // V_VECTOR;
  unsigned veclength;
  value_t veccomp[]; // flexible array of veclength components.
};

গতিশীল ধরণের কিছু মান পেতে

enum value_kind_en value_type(value_t v) {
  if (v.vptr != NULL) return *(v.vkind);
  else return V_NONE;
}

এখানে ভেক্টরগুলির কাছে একটি "গতিশীল কাস্ট" রয়েছে:

struct vectvalue_st* dyncast_vector (value_t v) {
   if (value_type(v) == V_VECTOR) return v->vvect;
   else return NULL;
}

এবং ভেক্টরগুলির ভিতরে একটি "নিরাপদ অ্যাকসেসর":

value_t vector_nth(value_t v, unsigned rk) {
   struct vectvalue_st* vecp = dyncast_vector(v);
   if (vecp && rk < vecp->veclength) return vecp->veccomp[rk];
   else return NULL_VALUE;
}

উপরের শর্ট ফাংশনগুলির বেশিরভাগটি আপনি সাধারণত static inlineকিছু শিরোলেখ ফাইল হিসাবে সংজ্ঞায়িত করবেন ।

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

value_t make_vector(unsigned size, ... /*value_t arguments*/) {
   struct vectvalue_st* vec = GC_MALLOC(sizeof(*vec)+size*sizeof(value));
   vec->kind = V_VECTOR;
   va_args args;
   va_start (args, size);
   for (unsigned ix=0; ix<size; ix++) 
     vec->veccomp[ix] = va_arg(args,value_t);
   va_end (args);
   return (value_t){vec};
}

এবং যদি আপনার তিনটি ভেরিয়েবল থাকে

value_t v1 = somevalue(), v2 = otherval(), v3 = NULL_VALUE;

আপনি তাদের ব্যবহার করে একটি ভেক্টর তৈরি করতে পারেন make_vector(3,v1,v2,v3)

আপনি যদি বোহমের আবর্জনা সংগ্রহকারী (বা নিজের নিজস্ব ডিজাইন) ব্যবহার করতে না চান তবে আপনারা ডেস্ট্রাক্টর সংজ্ঞায়িত করতে এবং কাকে, কীভাবে এবং কখন মেমরিটি রাখা উচিত ডকুমেন্টিংয়ের বিষয়ে খুব যত্নশীল হওয়া উচিত free; দেখতে এই উদাহরণ। সুতরাং আপনি উপরের mallocপরিবর্তে ব্যবহার করতে পারেন (তবে তার ব্যর্থতার বিরুদ্ধে পরীক্ষা করুন) GC_MALLOCতবে আপনাকে সাবধানে সংজ্ঞায়িত করতে হবে এবং কিছু ডেস্ট্রাক্টর ফাংশন ব্যবহার করতে হবেvoid destroy_value(value_t)

সি এর শক্তি হ'ল উপরের মতো কোড তৈরি করতে এবং আপনার নিজস্ব কনভেনশনগুলি (বিশেষত আপনার সফ্টওয়্যারটিতে) সংজ্ঞায়িত করার জন্য পর্যাপ্ত স্তর হ'ল।


আমি মনে করি আপনি আমার প্রশ্নটি ভুল বুঝেছেন। আমি সি তে গতিশীল টাইপিং চাই না যদি সি এর নির্দিষ্ট বৈশিষ্ট্যটি ব্যবহারিক ব্যবহারের হয় তবে আমি আগ্রহী ছিলাম।
থমাস অল্টম্যান

তবে সি এর সঠিক সম্পত্তিটি আপনি কী উল্লেখ করছেন? সি ডেটা স্ট্রাকচারগুলি
ধাতবটির


সিটি একটি নিম্ন-স্তরের ভাষা হিসাবে উদ্ভাবিত হয়েছিল, তবে যখন গ্টিসিটি যেমন নিম্ন-স্তরের বাক্য গঠন ব্যবহার করে তবে প্ল্যাটফর্ম-সরবরাহিত আচরণগত গ্যারান্টিগুলিতে নির্ভরযোগ্যভাবে নিম্ন-স্তরের অ্যাক্সেস সরবরাহ করে না এমন জিসিসি প্রসারণের মতো সংকলকগুলি যখন অপ্টিমাইজেশনগুলি চালু করা হয়। ম্যালোক এবং মেমকি ব্যবহারের জন্য একটি আকারের প্রয়োজন, তবে ফ্যানসিয়ার অ্যাড্রেস গণনার জন্য ব্যবহার "আধুনিক" সি
সুপারক্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.