শুধুমাত্র একটি সদস্য নিয়ে ইউনিয়ন ব্যবহারের উদ্দেশ্য কী?


89

যখন আমি সমুদ্রের উত্স কোডটি পড়ছিলাম , তখন আমি লক্ষ্য করেছি যে একটি ইউনিয়ন কাঠামো tx_sideরয়েছে যার নাম মাত্র একটি সদস্য। এটি একটি নির্দিষ্ট সমস্যার সাথে মোকাবিলা করার জন্য কিছু হ্যাক?

এফওয়াইআই, আমি tx_sideনীচের কাঠামোটি পেস্ট করেছি :

union tx_side {
    tx_side() {}
    ~tx_side() {}
    void init() { new (&a) aa; }
    struct aa {
        std::deque<work_item*> pending_fifo;
    } a;
} _tx;


5
@ ম্যাক্সল্যাংহোফ এই প্রশ্ন এবং সম্পর্কিত উত্তরগুলিতে এই জাতীয় ইউনিয়ন কাঠামো ব্যবহারের উদ্দেশ্য সম্পর্কে উল্লেখ করা হয়নি।
daoliker

আপনি এই সদস্য ব্যবহারের জন্য একটি উদাহরণ আছে?
n314159

4
এ কারণেই আমি আমার বাঁধাই করা নিকটতম ভোটটি ব্যবহার করি নি। তবে আমি নিশ্চিত নই যে আপনি আপনার প্রশ্নের উত্তর থেকে ঠিক কী প্রত্যাশা করছেন যা সেখানে উত্তর থেকে সরাসরি অনুসরণ করে না। সম্ভবত unionপরিবর্তে ব্যবহারের উদ্দেশ্য structহ'ল উভয়ের মধ্যে এক বা একাধিক পার্থক্য। এটি একটি সুন্দর অস্পষ্ট কৌশল তাই যদি না সেই কোডটির মূল লেখক উপস্থিত না হন আমি নিশ্চিত না যে কেউ আপনাকে একটি অনুমোদিত উত্তর দিতে পারে যে তারা কোন সমস্যাটির সমাধান করার আশা করছে (যদি তা হয়))
ম্যাক্স ল্যাংফোফ

2
আমার সর্বোত্তম অনুমান যে ইউনিয়নটি হয় নির্মাণে বিলম্ব করতে ব্যবহৃত হয় (যা এই ক্ষেত্রে কিছুটা অর্থহীন) বা মীমাংসা_ফাইফোর ধ্বংস (যা স্মৃতি ফাঁসের দিকে পরিচালিত করে) প্রতিরোধ করে। তবে ব্যবহারের উদাহরণ ছাড়াই বলা শক্ত।
কনস্ট্যান্টিন স্টুপনিক

উত্তর:


82

কারণ tx_sideএকটি ইউনিয়ন, tx_side()স্বয়ংক্রিয়ভাবে আরম্ভ / নির্মাণ করে না aএবং ~tx_side()স্বয়ংক্রিয়ভাবে এটি ধ্বংস করে না। এটি প্লেসমেন্ট-নতুন এবং ম্যানুয়াল ডেস্ট্রাক্টর কলগুলির মাধ্যমে (একটি দরিদ্র ব্যক্তির ) জীবদ্দশায় aএবং সর্বোপরি সূক্ষ্ম নিয়ন্ত্রণের অনুমতি দেয় ।pending_fifostd::optional

এখানে একটি উদাহরণ:

#include <iostream>

struct A
{
    A() {std::cout << "A()\n";}
    ~A() {std::cout << "~A()\n";}
};

union B
{
    A a;
    B() {}
    ~B() {}
};

int main()
{
    B b;
}

এখানে, B b;কিছুই প্রিন্ট করে না, কারণ aএটি নির্মাণ বা ধ্বংসপ্রাপ্ত নয়।

যদি Bএকটি হয় struct, B()কল করত A(), এবং ~B()কল করত ~A(), এবং আপনি তা আটকাতে সক্ষম হবেন না।


23
@ ডলিকার অগত্যা এলোমেলো নয়, তবে আপনার দ্বারা অনুমানযোগ্য। অন্য যে কোনও অবিচ্ছিন্ন পরিবর্তনশীল হিসাবে একই S আপনি এলোমেলোভাবে ধরে নিতে পারবেন না; আপনারা সবাই জানেন যে এটি ব্যবহারকারীর পাসওয়ার্ডটি ধরে রাখতে পারে যা আপনি আগে তাদের টাইপ করতে বলেছিলেন
ব্যবহারকারী 253751

5
@ ডলিকার: পূর্ববর্তী মন্তব্যটি খুব আশাবাদী। এলোমেলো বাইটের মান 0-255 সীমাতে থাকবে তবে আপনি যদি একটি অবিচ্ছিন্ন বাইট পড়েন তবে আপনি intপেতে পারেন 0xCCCCCCCC। অনির্দেশিত ডেটা পড়া অনির্ধারিত আচরণ, এবং যা হতে পারে তা হ'ল সংকলকটি কেবল প্রচেষ্টাটি বাতিল করে দেয়। এটি কেবল তত্ত্ব নয়। দেবিয়ান এই সঠিক ভুলটি করেছিল এবং এটি তাদের ওপেনএসএসএল বাস্তবায়ন ভঙ্গ করে। তাদের কিছু বাস্তব এলোমেলো বাইট ছিল, একটি অবিচ্ছিন্ন ভেরিয়েবল যুক্ত হয়েছিল এবং সংকলকটি বলেছিল যে "ভাল ফলাফল অনির্ধারিত, সুতরাং এটি শূন্যও হতে পারে"। জিরো স্পষ্টতই আর এলোমেলো নয়।
এমসাল্টারস

1
@ এসএমএলটার্স: আপনার কাছে এই দাবির কোনও উত্স আছে? কারণ আমি যেটি সন্ধান করতে পারি তা বোঝায় যে যা ঘটেছিল তা নয়: এটি সংকলক নয় যা এটি সরিয়েছিল, কিন্তু বিকাশকারীরা। সত্যিই, কোনও সংকলক লেখক যদি এমন অবিশ্বাস্যভাবে খারাপ সিদ্ধান্ত নেন তবে আমি অবাক হয়ে যাব। (দেখুন stackoverflow.com/questions/45395435/... )
জ্যাক Aidley

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

1
@ জ্যাকএইডলি @ এমএমটাররা আমার নিজস্ব কোডে যা উল্লেখ করেছেন তার সাথে আমিও একই রকম সমস্যার মুখোমুখি হয়েছি; আমি ভ্রান্তভাবে ধরে নিয়েছিলাম যে একটি অবিচ্ছিন্ন ভেরিয়েবলটি খালি হবে, এবং যখন পরবর্তী != 0তুলনাটি সত্য হয়ে উঠবে তখন হতবাক হয়ে গেলাম । আমি আর সেই ফাঁদে পড়ে যাব না তা নিশ্চিত করার জন্য আমি অবিচ্ছিন্ন ভেরিয়েবলগুলিকে ত্রুটি হিসাবে বিবেচনা করার জন্য সংকলক পতাকাগুলি যুক্ত করেছি।
টম লিন্ট

0

সহজ কথায়, একক সদস্য ইউনিয়ন বরাদ্দকৃত স্মৃতিশক্তি আরম্ভ না করে স্পষ্টভাবে একটি মান নির্ধারিত / আরম্ভ না করা পর্যন্ত। এই কার্যকারিতাটি std:: optionalসি ++ 17 দিয়ে অর্জন করা যায়।


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