সি এর ওভারল্যাপিং অবজেক্টগুলির শব্দার্থক শব্দগুলি কী কী?


25

নিম্নলিখিত কাঠামো বিবেচনা করুন:

struct s {
  int a, b;
};

সাধারণত 1 , এই স্ট্রাক্টটির আকার 8 এবং প্রান্তিককরণ 4 থাকবে।

যদি আমরা দুটি struct sঅবজেক্ট তৈরি করি (আরও সুনির্দিষ্টভাবে, আমরা বরাদ্দ স্টোরেজে দুটি যেমন দুটি বস্তু লিখি), দ্বিতীয় অবজেক্টটি প্রথমটি ওভারল্যাপ করে?

char *storage = malloc(3 * sizeof(struct s));
struct s *o1 = (struct s *)storage; // offset 0
struct s *o2 = (struct s *)(storage + alignof(struct s)); // offset 4

// now, o2 points half way into o1
*o1 = (struct s){1, 2};
*o2 = (struct s){3, 4};

printf("o2.a=%d\n", o2->a);
printf("o2.b=%d\n", o2->b);
printf("o1.a=%d\n", o1->a);
printf("o1.b=%d\n", o1->b);

এই প্রোগ্রামটি সম্পর্কে কি অপরিবর্তিত আচরণ? যদি তা হয়, তবে এটি কোথায় সংজ্ঞায়িত হবে? যদি এটি ইউবি না হয় তবে কি সর্বদা নিম্নলিখিত মুদ্রণের গ্যারান্টিযুক্ত:

o2.a=3
o2.b=4
o1.a=1
o1.b=3

বিশেষত, আমি জানতে চাই যে o1কখন o2, কোনটি এটির ওভারল্যাপ করে, কোনটি লেখা হয়েছে তার দ্বারা চিহ্নিত বস্তুর কী হয় what এখনও অব্যাহত অংশ ( o1->a) অ্যাক্সেস করার অনুমতি দেওয়া আছে ? ক্লোবারযুক্ত অংশটি অ্যাক্সেস করা কি o1->bকেবল অ্যাক্সেসের সমান o2->a?

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

দ্বিতীয় লেখাটি যদি অন্যরকমের হয় তবে কি কিছু পরিবর্তন হবে? যদি সদস্যরা বলতেন intএবং shortতার চেয়ে দু'জন int?

আপনি যদি এটির সাথে খেলতে চান তবে এখানে একটি গডবোল্ট


1 এই উত্তরটি প্ল্যাটফর্মগুলিতে প্রযোজ্য যেখানে এটিও তেমন নয়: উদাহরণস্বরূপ, কারওর আকার 4 এবং প্রান্তিককরণ 2 থাকতে পারে a অসম্ভব হও, তবে এর মতো কোনও প্ল্যাটফর্ম আছে কিনা তা সম্পর্কে আমি নিশ্চিত নই।


2
আমি নিশ্চিত এটি ইউবি, তবে আমি কোনও ভাষা আইনজীবীকে অধ্যায় এবং শ্লোক সরবরাহ করতে দেব।
বার্মার

আমি মনে করি যে পুরানো ক্রে ভেক্টর সিস্টেমে সি সংকলক একটি আইএলপি model৪ মডেল সহ প্রান্তিককরণ এবং আকার একই হতে বাধ্য করেছে এবং বাধ্যতামূলকভাবে -৪-বিট সারিবদ্ধকরণ (ঠিকানাগুলি 64৪-বিট শব্দ - কোনও বাইট অ্যাড্রেসিং নেই)। অবশ্যই এটি প্রচুর পরিমাণে অন্যান্য সমস্যা তৈরি করেছে ....
জন ডি ম্যাককাল্পিন

উত্তর:


15

মূলত এটি স্ট্যান্ডার্ডের সমস্ত ধূসর অঞ্চল; কঠোর আলিয়াজিং বিধিটি মৌলিক কেসগুলি নির্দিষ্ট করে এবং পাঠককে (এবং সংকলক বিক্রেতাদের) বিশদটি পূরণ করতে দেয়।

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

আপনার পূর্ববর্তী প্রশ্নের আমার উত্তরে যেমন উল্লেখ করা হয়েছে, সর্বাধিক প্রচলিত ব্যাখ্যার p->qঅর্থ হল (*p).qএবং কার্যকর ধরণটি সমস্ত ক্ষেত্রে প্রযোজ্য *p, যদিও আমরা পরে প্রয়োগ করতে যাই না .q

এই ব্যাখ্যা অনুযায়ী, printf("o1.a=%d\n", o1->a);অনির্ধারিত আচরণ কারণ হবে যেমন কার্যকর টাইপ অবস্থানের *o1নয় s(যেহেতু এটা অংশ মুছে ফেলা হয়েছে)।

এই ব্যাখ্যার যৌক্তিকতা একটি ফাংশনে দেখা যায়:

void f(s* s1, s* s2)
{
    s2->a = 5;
    s1->b = 6;
    printf("%d\n", s2->a);
}

এই ব্যাখ্যার সাথে শেষ পংক্তিকে অনুকূলিত করা যেতে পারে puts("5");তবে এটি ব্যতীত সংকলকটিকে বিবেচনা করতে হবে যে ফাংশন কলটি হতে পারে f(o1, o2);এবং তাই কঠোর আলিয়াজিং বিধি দ্বারা পূর্বনির্ধারিত সমস্ত সুবিধা হারাতে হবে।

একই রকম যুক্তি দুটি অবাস্তব স্ট্রাক্ট প্রকারের ক্ষেত্রে প্রযোজ্য যা উভয়েরই intবিভিন্ন অফসেটে সদস্য থাকতে পারে ।


1
সহ f(s* s1, s* s2), ছাড়া restrict, সংকলকটি ধরে নিতে পারে না s1এবং s2এটি বিভিন্ন পয়েন্টার। আমি মনে করি , আবার ছাড়া restrict, এটি ধরেও নিতে পারে না যে তারা আংশিকভাবে ওভারল্যাপ করে না। আইএসি, আমি দেখতে পাচ্ছি না যে ওপির উদ্বেগটি f()উপমা অনুসারে ভালভাবে উপস্থাপিত হয়েছে । ভাগ্য আনসনার্লিং। প্রথমার্ধের জন্য ইউভি।
chux - মনিকা

@ chux-ReinstateMonica কে সীমাবদ্ধ ছাড়াই s1 == s2অনুমতি দেওয়া হবে তবে আংশিক ওভারল্যাপ নয়। (আমার কোড উদাহরণে অপ্টিমাইজেশন এখনও করা যেতে পারে যদি s1 == s2)
এমএম

@ chux-ReinstateMonica আপনি একই intস্ট্রাক্টের পরিবর্তে (এবং সিস্টেম সহ _Alignof(int) < sizeof(int)) একই সমস্যাটি বিবেচনা করতে পারেন ।
এমএম

3
সি 2 এক্স এর জন্য কার্যকর ধরণের বিষয়ে এই ধরণের প্রশ্নের স্থিতি বেশ খোলা এবং এখনও অধ্যয়ন গোষ্ঠীতে বিতর্কের বিষয়। p->qএবং এর সমতুল্যতা দাবি করার সাথে সতর্ক থাকুন (*p).q। আপনার বক্তব্যটি টাইপ ব্যাখ্যা করার ক্ষেত্রে এটি সত্য হতে পারে, তবে এটি অপারেশনাল দৃষ্টিকোণ থেকে সত্য নয়। একই কাঠামোর একযোগে প্রবেশের জন্য এটি গুরুত্বপূর্ণ যে কোনও সদস্যের অ্যাক্সেস অন্য কোনও সদস্যের অ্যাক্সেসকে বোঝায় না।
জেনস গুষ্টেড

কঠোর আলিয়াজিং নিয়ম অ্যাক্সেস সম্পর্কে । এক্সপ্রেশনটিতে বাম দিকের এক্সপ্রেশনটি E1.E2অ্যাক্সেস সম্পাদন করে না (আমি সম্পূর্ণ E1এক্সপ্রেশনটি বোঝায় its এর কিছু subexpressions অ্যাক্সেস সম্পাদন করতে পারে e অর্থাত্ যদি E1হয় (*p), তবে মূল্যায়ন করার সময় পয়েন্টার মানটি পড়লে pঅ্যাক্সেস হয়, তবে মূল্যায়ন হয় *pবা (*p)কোনও সম্পাদন করে না এক্সেস)। অ্যাক্সেস না থাকলে ক্ষেত্রে কঠোর আলিয়াজিং বিধি প্রযোজ্য না।
ভাষা আইনজীবী
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.