অবিচ্ছিন্ন সদস্যদের সাথে স্ট্রোকগুলি অনুলিপি করা হচ্ছে


29

যাদের সদস্যদের সূচনা না করা হয়েছে তাদের মধ্যে কিছু স্ট্রাক্ট অনুলিপি করা বৈধ?

আমি সন্দেহ করি এটি অনির্ধারিত আচরণ, তবে যদি তা হয় তবে এটি কোনও অবিজ্ঞাসিত সদস্যকে কাঠামোয় রেখে দেয় (এমনকি যদি সেই সদস্যরা সরাসরি ব্যবহার না করা হয়) তবে এটি বেশ বিপজ্জনক। সুতরাং আমি আশ্চর্য হই যে মানকটিতে এমন কিছু আছে যা এটির অনুমতি দেয়।

উদাহরণস্বরূপ, এটি কি বৈধ?

struct Data {
  int a, b;
};

int main() {
  Data data;
  data.a = 5;
  Data data2 = data;
}

আমি কিছুক্ষণ আগে অনুরূপ প্রশ্ন দেখে মনে পড়েছি তবে এটি খুঁজে পাচ্ছি না। এই প্রশ্ন হিসাবে সম্পর্কযুক্ত এই এক
1201 প্রোগ্রাম অ্যালার্ম

উত্তর:


23

হ্যাঁ, অজ্ঞাতনামা সদস্য যদি স্বাক্ষরবিহীন সরু চরিত্রের প্রকার না হয় বা std::byte, তবে স্পষ্টভাবে সংজ্ঞায়িত অনুলিপি নির্ধারকের সাথে এই অনির্দিষ্ট মানযুক্ত স্ট্রাক্ট অনুলিপি করা প্রযুক্তিগতভাবে অপরিজ্ঞাত আচরণ, কারণ এটি একই ধরণের অনির্দিষ্ট মান সহ একটি ভেরিয়েবল অনুলিপি করার জন্য, কারণ এর [dcl.init] / 12

এটি এখানে প্রযোজ্য, কারণ unionপ্রত্যক্ষভাবে উত্পাদিত অনুলিপি নির্ধারক হ'ল প্রত্যক্ষভাবে- প্রত্যুত্তর দ্বারা প্রতিটি সদস্যকে স্বতন্ত্রভাবে অনুলিপি করার জন্য সংজ্ঞায়িত, [class.copy.ctor] / 4 দেখুন

এটি সক্রিয় সিডাব্লুজি ইস্যু 2264 এর বিষয়ও

আমি অনুমান করি অনুশীলনে যদিও আপনার সাথে কোনও সমস্যা হবে না, যদিও।

আপনি যদি 100% নিশ্চিত হতে চান , তবে সদস্যদের অনির্বচনীয় মূল্য থাকলেও std::memcpyটাইপটি তুচ্ছভাবে অনুলিপিযোগ্য হয় তবে সর্বদা ব্যবহারের সঠিক সংজ্ঞাযুক্ত আচরণ থাকে ।


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

struct Data {
  int a{}, b{};
};

int main() {
  Data data;
  data.a = 5;
  Data data2 = data;
}

ভাল .. যে স্ট্রাকটি কোনও পড নয় (সাধারণ পুরানো ডেটা)? তার মানে সদস্যরা ডিফল্ট মান দিয়ে আরম্ভ করা হবে? এটি একটি সন্দেহ
কেভিন কাউকেসু

এই ক্ষেত্রে এটি কি অগভীর অনুলিপি নয়? অনির্ধারিত সদস্য অনুলিপি করা কাঠামোটিতে অ্যাক্সেস না করা হলে এর সাথে কী ভুল হতে পারে?
ট্রুথসাইকার

@ কেভিনকুকেসু আমি মামলার ক্ষেত্রে একটি শর্ত জুড়েছি যেখানে একটি তুচ্ছ / পিওডি প্রকারের প্রয়োজন হয়।
আখরোট

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

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

11

সাধারণভাবে, অবিশ্রুত ডেটা অনুলিপি করা অপরিজ্ঞাত আচরণ কারণ সেই ডেটা ট্র্যাপিং অবস্থায় থাকতে পারে। এই পৃষ্ঠাটি উদ্ধৃত :

যদি কোনও বস্তুর প্রতিনিধিত্ব বস্তুর ধরণের কোনও মান উপস্থাপন না করে তবে এটি ফাঁদ উপস্থাপনা হিসাবে পরিচিত। চরিত্রের ধরণের লভ্যালু এক্সপ্রেশনটির মাধ্যমে পড়া ছাড়া অন্য কোনও উপায়ে ট্র্যাপের প্রতিনিধিত্ব অ্যাক্সেস করা অনির্ধারিত আচরণ।

সিগন্যালিং এনএএনগুলি ভাসমান পয়েন্টের ধরণের জন্য সম্ভব এবং কিছু প্ল্যাটফর্মগুলিতে পূর্ণসংখ্যার ফাঁদের উপস্থাপনা থাকতে পারে

তবে তুচ্ছভাবে অনুলিপিযোগ্য ধরণের memcpyজন্য অবজেক্টের কাঁচা উপস্থাপনা অনুলিপি করে ব্যবহার করা সম্ভব । এটি করা নিরাপদ যেহেতু বস্তুর মান ব্যাখ্যা করা হয় না এবং পরিবর্তে অবজেক্টের উপস্থাপনের কাঁচা বাইট অনুক্রম অনুলিপি করা হয়।


সমস্ত বিট নিদর্শনগুলি বৈধ মানগুলি উপস্থাপন করে এমন ধরণের ডেটা সম্পর্কে কী? (যেমন একটি -৪-বাইট স্ট্রাক্ট একটি রয়েছে unsigned char[64])? স্ট্রাক্টের বাইটগুলি অনির্ধারিত মান হিসাবে অকারণে অপ্টিমাইজেশন বাধাগ্রস্থ করতে পারে, তবে প্রোগ্রামারদের অকার্যকর মানগুলির সাথে ম্যানুয়ালি অ্যারে পপুলেট করার জন্য দক্ষতা আরও বেশি বাধা পেতে পারে।
সুপারক্যাট

ডেটা আরম্ভ করা অকেজো নয়, এটি ইউবিটিকে বাধা দেয়, তা ফাঁদ উপস্থাপনার কারণে বা পরে অনির্দেশিত ডেটা ব্যবহার করে তৈরি করা হোক। জিরোয়িং by৪ বাইট (1 বা 2 ক্যাশে লাইন) এটির মতো ব্যয়বহুল নয়। এবং আপনার যদি এটির ব্যয়বহুল বড় কাঠামো থাকে তবে সেগুলি অনুলিপি করার আগে আপনার দুবার চিন্তা করা উচিত। এবং আমি নিশ্চিত যে আপনাকে যে কোনও সময়ে এগুলি শুরু করতে হবে।
আন্দ্রে সেমাসেভ

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

-1

কিছু ক্ষেত্রে যেমন বর্ণিত হিসাবে দেখা যায়, সি ++ স্ট্যান্ডার্ড কম্পাইলাররা যে কোনও ফ্যাশনে তাদের গ্রাহকদের সবচেয়ে কার্যকর বলে মনে করে এমন আচরণের পূর্বাভাস ছাড়াই প্রয়োজনীয় নির্মাণের প্রক্রিয়া করতে দেয়। অন্য কথায়, এই ধরনের নির্মাণগুলি "অনির্ধারিত আচরণ" ডাকে। তবে এটি বোঝায় না যে এই জাতীয় নির্মাণগুলি "নিষিদ্ধ" বলে বোঝানো হয়েছে, যেহেতু সি ++ স্ট্যান্ডার্ড সুস্পষ্টভাবে তৈরি প্রোগ্রামগুলি "অনুমোদিত" হওয়ার বিষয়ে তার এখতিয়ারকে সুস্পষ্টভাবে মওকুফ করে। যদিও আমি সি ++ স্ট্যান্ডার্ডের জন্য কোনও প্রকাশিত যৌক্তিক নথি সম্পর্কে অসচেতন, যদিও এটি সি 98 এর মতো অপরিজ্ঞাত আচরণের বর্ণনা দেয় তা হ'ল বোঝানো অর্থ একইরকম বোঝায়: "অপরিজ্ঞাত আচরণ বাস্তবায়নকারীকে কিছু নির্দিষ্ট প্রোগ্রামের ত্রুটিগুলি ধরার জন্য অনুমতি দেয় না যেগুলি জটিল নির্ণয় করতে.

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

তদুপরি, কিছু পরিস্থিতি রয়েছে যেখানে অ-নিরবচ্ছিন্ন উপাত্তগুলি অ-নিরস্তকরণ পদ্ধতিতে আচরণ করা সবচেয়ে দক্ষ হতে পারে। উদাহরণস্বরূপ, প্রদত্ত:

struct q { unsigned char dat[256]; } x,y;

void test(unsigned char *arr, int n)
{
  q temp;
  for (int i=0; i<n; i++)
    temp.dat[arr[i]] = i;
  x=temp;
  y=temp;
}

যদি স্ট্রিম কোড কোনও উপাদান x.datবা y.datএর সূচকগুলিতে তালিকাভুক্ত ছিল না এর মূল্যগুলির বিষয়ে চিন্তা করে না arr, কোডটি এতে অনুকূলিত হতে পারে:

void test(unsigned char *arr, int n)
{
  q temp;
  for (int i=0; i<n; i++)
  {
    int it = arr[i];
    x.dat[index] = i;
    y.dat[index] = i;
  }
}

দক্ষতার এই উন্নতি সম্ভব হবে না যদি প্রোগ্রামাররা temp.datঅনুলিপি করার আগে, যেসব স্ট্রিম স্ট্রিমের যত্ন নেয় না সেগুলি সহ প্রতিটি উপাদান স্পষ্টভাবে লিখতে হয় ।

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

আমি যা বলতে পারি সেগুলি থেকে, সি ++ স্ট্যান্ডার্ড এটি বলার চেষ্টা করে না যে এই আচরণগুলির যথাযথতা প্রমাণ করার জন্য এই আচরণগুলির মধ্যে কোনওটি অন্যের চেয়ে যথেষ্ট কার্যকর useful হাস্যকরভাবে, নির্দিষ্টকরণের এই অভাবটি অপ্টিমাইজেশনের সুবিধার্থে উদ্দেশ্যে করা যেতে পারে তবে প্রোগ্রামাররা যদি কোনও ধরণের দুর্বল আচরণগত গ্যারান্টি ব্যবহার করতে না পারে তবে কোনও অপ্টিমাইজেশন এড়ানো হবে।


-2

যেহেতু এর সমস্ত সদস্য Dataআদিম ধরণের, তাই সমস্ত সদস্যের data2সঠিক "বিট-বাই-বিট অনুলিপি" পাবেন data। সুতরাং মান এর মান data2.bহিসাবে একই হবে data.b। যাইহোক, এর সঠিক মান data.bপূর্বাভাস দেওয়া যায় না, কারণ আপনি এটি স্পষ্টভাবে শুরু করেননি। এটি মেমরি অঞ্চলের জন্য বরাদ্দকৃত বাইটগুলির মানগুলির উপর নির্ভর করবে data


আপনি স্ট্যান্ডার্ড একটি রেফারেন্স সহ এটি সমর্থন করতে পারেন? @ ওয়ালটনের সরবরাহিত লিঙ্কগুলি বোঝায় এটি অনির্ধারিত আচরণ। স্ট্যান্ডার্ডে পিওডিদের জন্য কি ব্যতিক্রম আছে?
টোমেক সিজ্জাকা

যদিও নিম্নলিখিতটি মানের সাথে লিঙ্ক নয়, তবুও: en.cppreferences.com/w/cpp/language/… "তুচ্ছভাবে কপিযোগ্য বস্তুগুলি তাদের বস্তুর উপস্থাপনা ম্যানুয়ালি অনুলিপি করে অনুলিপি করা যেতে পারে, যেমন স্টাড :: মেমমোভ সহ All সমস্ত ডাটা টাইপ সি এর সাথে সামঞ্জস্যপূর্ণ types ভাষা (পিওডির প্রকারগুলি) তুচ্ছভাবে কপিযোগ্য ""
ivan.ukr

এক্ষেত্রে একমাত্র "অপরিজ্ঞাত আচরণ" হ'ল আমরা অবিবেশনীয় সদস্য ভেরিয়েবলের মান অনুমান করতে পারি না ut তবে কোডটি সংকলন করে সফলভাবে চলে।
ivan.ukr

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

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