Object 0} এর অর্থ কী যখন কোনও বস্তুর সূচনা করার সময়?


252

কখন {0}কোনও বস্তুর সূচনা করতে ব্যবহৃত হয়, এর অর্থ কী? আমি {0}কোথাও কোনও রেফারেন্স খুঁজে পাচ্ছি না , এবং কোঁকড়া ধনুর্বন্ধনী কারণগুলির জন্য গুগল অনুসন্ধানগুলি সহায়ক নয়।

উদাহরণ কোড:

SHELLEXECUTEINFO sexi = {0}; // what does this do?
sexi.cbSize = sizeof(SHELLEXECUTEINFO);
sexi.hwnd = NULL;
sexi.fMask = SEE_MASK_NOCLOSEPROCESS;
sexi.lpFile = lpFile.c_str();
sexi.lpParameters = args;
sexi.nShow = nShow;

if(ShellExecuteEx(&sexi))
{
    DWORD wait = WaitForSingleObject(sexi.hProcess, INFINITE);
    if(wait == WAIT_OBJECT_0)
        GetExitCodeProcess(sexi.hProcess, &returnCode);
}

এটি ব্যতীত উপরের কোডটি রানটাইমের সময় ক্রাশ হবে।

উত্তর:


302

এখানে যা ঘটছে তাকে সমষ্টিগত সূচনা বলে। আইএসও স্পেসের 8.5.1 বিভাগ থেকে মোটের সংক্ষিপ্ত বিবরণ এখানে দেওয়া হয়েছে:

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

এখন, এ জাতীয় {0}একটি সামগ্রিক সূচনা করতে ব্যবহার করা মূলত 0পুরো জিনিসটির কৌশল। এটি এগ্রিমেট ইনিশিয়ালেশন ব্যবহার করার সময় আপনাকে সমস্ত সদস্যকে নির্দিষ্ট করতে হবে না এবং অনুমানের প্রয়োজন হয় যে সমস্ত অনির্ধারিত সদস্যকে ডিফল্ট সূচনা করতে হবে, যার অর্থ 0সরল প্রকারের জন্য সেট ।

এখানে অনুমান থেকে প্রাসঙ্গিক উদ্ধৃতি:

সমষ্টিতে সদস্যদের তুলনায় তালিকায় যদি কম ইনিশিয়ালাইজার থাকে তবে সুস্পষ্টভাবে আরম্ভ না করা প্রতিটি সদস্যই ডিফল্ট-আরম্ভ হবে। উদাহরণ:

struct S { int a; char* b; int c; };
S ss = { 1, "asdf" };

সূচনা ss.aসঙ্গে 1, ss.bসঙ্গে "asdf", এবং ss.cফর্ম একটি অভিব্যক্তি মান int(), যে 0

আপনি এই বিষয়ে সম্পূর্ণ বৈশিষ্ট জানতে পারেন এখানে


15
দুর্দান্ত প্রতিক্রিয়া। কেবল যোগ করতে চেয়েছিলেন যে agg 0 with দিয়ে একটি সামগ্রিক সূচনাটি কেবল {} দিয়ে শুরু করার সমান} সম্ভবত প্রাক্তন এটি আরও স্পষ্ট করে তোলে যে অন্তর্নির্মিত প্রকারগুলি শূন্য হয়।
জেমস হপকিন

7
কিছু সংকলক {} তে
কমে যায়

10
পুরোপুরি নয় .. সি ++ এ, যদি প্রথম সদস্যটি শূন্য-নির্মিত না হতে পারে তবে {0 work কাজ করবে না। উদাঃ স্ট্রাক্ট এ {বি বি; int i; চর গ; }; কাঠামো বি {বি (); বি (স্ট্রিং); }; ক ক = {}; // এই বিবৃতিটি 'A a = {0}' হিসাবে আবার লেখা যায় না।
হারুন

24
@ ব্রানান, কারণ সি "{}" বৈধ নয়। সি ++ তে এটি। @ ডন.নুফেল্ড, এটি সি ++ 03 (ডিফল্ট-আরম্ভ -> মান-প্রাথমিক) এর সাথে পরিবর্তিত হয়েছে ized উদ্ধৃতিটি সি ++ 98 স্ট্যান্ডার্ডটি মনে রাখবেন।
জোহানেস স্কাউব -

3
সুতরাং, এটি কি জিরো মেমোরি () ভিসি ++ এ) ব্যবহার করার প্রয়োজনের প্রতিস্থাপন করবে?
রে

89

একটি বিষয় সচেতন হতে হবে যে এই কৌশলটি প্যাডিং বাইটগুলি শূন্যে সেট করবে না। উদাহরণ স্বরূপ:

struct foo
{
    char c;
    int  i;
};

foo a = {0};

যেমনটি হয় না:

foo a;
memset(&a,0,sizeof(a));

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


13
অবশ্যই, এটি কেবলমাত্র একটি সুরক্ষার সমস্যা হ'ল আপনি যদি (f, & a, মাপের (ক)) লিখেন, যা বিভিন্ন প্রসেসর / সংকলকগুলিতে বিভিন্ন ফাইল এনকোডিং তৈরি করতে পারে। ভাল ফর্ম্যাট আউটপুট মেমসেট ছাড়াই নিরাপদ হবে।
হারুন

3
এছাড়াও, আপনি যদি নেটওয়ার্ক জুড়ে জিনিস প্রেরণ করছেন তবে আপনি সর্বদা প্যাক করার জন্য অ্যালাইনমেন্ট সেট করবেন। এইভাবে আপনি যতটা সম্ভব অতিরিক্ত অতিরিক্ত প্যাডিং বাইট পাবেন।
মার্ক কেজেল

18
এটি লক্ষ করা উচিত যে যদিও চশমাটি প্যাডিং শুরু করার প্রয়োজন হয় না, তবে কোনও বুদ্ধিমান সংকলক হবে, কারণ এটি "আশেপাশে" আরম্ভ করতে সময় ব্যয় করে।
টমাস

4
আমি "এটি নয়" শব্দের ব্যবহার করে ইস্যুটি নিতে চাই। প্যাডিং বাইট বাস্তবায়ন সংজ্ঞায়িত করা হয়। সংকলকটি তার নিজের অবসর সময়ে foo a = {0 mem কে মেমসেটে পরিণত করতে (এবং a, 0, আকারের (ক)) মুক্ত প্যাডিং বাইটগুলি "এড়িয়ে যান" এবং কেবল foo.c এবং foo.i সেট করার প্রয়োজন হয় না (সম্ভাব্য) সুরক্ষা বাগের জন্য +1
সিকিউরিটিমেট

3
@ লুশেনকো পয়েন্ট 19 বলেছে "সমস্ত সাবওজেক্ট যা স্পষ্টরূপে আরম্ভ করা হয়নি", সুতরাং আমি 21 পয়েন্টটি (যা আপনি উদ্ধৃত করেছেন) ঝিমঝিম হয়ে ঝুঁকেছি। এটি যদি সত্যিই উদ্ভট হবে যে স্পেকটি প্যাডিংটিকে শেষ ইনিশিয়ালাইজারের মুহুর্ত পর্যন্ত অবিচ্ছিন্ন করার অনুমতি দেয়, তারপরে প্যাডিং শূন্য করতে হয়েছিল, বিশেষত বিবেচনা করে যে মনোনীত প্রারম্ভিক ব্যবহার করা হয় তখন প্রাথমিকভাবে অর্ডার থেকে বেরিয়ে আসতে পারে considering
এমএম

20

মনে রাখবেন যে একটি খালি সমষ্টিগত আরম্ভকারীও কাজ করে:

SHELLEXECUTEINFO sexi = {};
char mytext[100] = {};

11

কেন ShellExecuteEx()ক্রাশ হচ্ছে এর উত্তরে : আপনার SHELLEXECUTEINFO"সেক্সী" স্ট্রাক্টের অনেক সদস্য রয়েছে এবং আপনি কেবল তাদের মধ্যে কিছু সংখ্যক সূচনা করছেন।

উদাহরণস্বরূপ, সদস্যটি sexi.lpDirectoryযে কোনও জায়গায় পয়েন্ট করাতে পারে, তবে ShellExecuteEx()এটি ব্যবহারের চেষ্টা করবে, সুতরাং আপনি একটি মেমরি অ্যাক্সেস লঙ্ঘন পাবেন get

আপনি যখন লাইনটি অন্তর্ভুক্ত করবেন:

SHELLEXECUTEINFO sexi = {0};

আপনার স্ট্রাকচারের বাকি অংশটি সেটআপ করার আগে, আপনি যে কাঠামোতে আগ্রহী সেগুলি সূচনা করার আগে আপনি সমস্ত কাঠামোর সদস্যদের শূন্য করার জন্য কম্পাইলারকে বলছেন ShellExecuteEx()knows জানে যে যদি sexi.lpDirectoryশূন্য হয় তবে এটি এড়ানো উচিত।


7

আমি স্ট্রিংগুলি সূচনা করার জন্য এটি ব্যবহার করি use

char mytext[100] = {0};

5
যদিও, অবশ্যই, যদি মাইটেক্সট একটি স্ট্রিং ব্যবহার করা হচ্ছে, চর মাইেক্সট [100]; mytext [0] = '\ 0'; খালি স্ট্রিং দেওয়ার ক্ষেত্রে একই প্রভাব থাকবে তবে কেবলমাত্র প্রয়োগটি শূন্যের শূন্যে পরিণত করবে।
ক্রিস ইয়ং

@ ক্রিস: আমি প্রায়শই আকাঙ্ক্ষা করতাম যে আংশিক বস্তুর সূচনা করার জন্য একটি বাক্য গঠন রয়েছে। এক্সকে "ডিক্লেয়ার এবং ইনিশিয়েলাইজ" করতে সক্ষম হবেন, তারপরে y এর সাথে একইভাবে করুন, তারপরে z, x, y, এবং z ঘোষণা করার চেয়ে অনেক সুন্দর, এবং তারপর x, y, এবং z শুরু করতে হবে তবে কেবল যখন 100 বাইট শুরু করা হয় একজনের আরম্ভের প্রয়োজন আসলে অপব্যয়ী বলে মনে হয়।
সুপারক্যাট

7

{0}সি এবং সি ++ উভয় ক্ষেত্রে (সম্পূর্ণ অবজেক্ট) প্রকারের জন্য একটি বৈধ আরম্ভকারী। এটি শূন্যে কোনও বস্তুর সূচনা করার জন্য ব্যবহৃত একটি সাধারণ প্রতিচ্ছবি (এর অর্থ কী তা বোঝার জন্য পড়ুন)।

স্কেলার প্রকারের (পাটিগণিত এবং পয়েন্টার ধরণের) জন্য, ধনুর্বন্ধনীগুলি অপ্রয়োজনীয় তবে তাদের স্পষ্টরূপে অনুমতি দেওয়া হয়। আইএসও সি স্ট্যান্ডার্ডের N1570 খসড়াটি উদ্ধৃত করে , বিভাগ 6.7.9:

স্কেলারের জন্য ইনিশিয়ালাইজারটি একটি একক অভিব্যক্তি হবে optionচ্ছিকভাবে বন্ধনীগুলিতে আবদ্ধ।

এটি শূন্যে অবজেক্টটি সূচনা করে ( 0পূর্ণসংখ্যার 0.0জন্য, ভাসমান-পয়েন্টের জন্য, পয়েন্টারগুলির জন্য একটি নাল পয়েন্টার)।

অ-স্কেলার প্রকারের জন্য (স্ট্রাকচার, অ্যারে, ইউনিয়ন) {0}নির্দিষ্ট করে যে বস্তুর প্রথম উপাদানটি শূন্যে শুরু হয়। স্ট্রাকচারযুক্ত স্ট্রাকচারের জন্য, স্ট্রাকচারের অ্যারে এবং আরও অনেক কিছু, এটি পুনরাবৃত্তভাবে প্রয়োগ করা হয়, সুতরাং প্রথম স্কেলার উপাদানটি শূন্যে সেট করা হয়, টাইপের জন্য উপযুক্ত হিসাবে। যে কোনও আরম্ভকারী হিসাবে, নির্দিষ্ট না হওয়া কোনও উপাদান শূন্যতে সেট করা থাকে।

মধ্যবর্তী বন্ধনী ( {, }) বাদ দেওয়া যেতে পারে; উদাহরণস্বরূপ, এই উভয়ই বৈধ এবং সমতুল্য:

int arr[2][2] = { { 1, 2 }, {3, 4} };

int arr[2][2] = { 1, 2, 3, 4 };

এজন্য আপনাকে লিখতে হবে না, উদাহরণস্বরূপ, এমন { { 0 } }এক ধরণের জন্য যার প্রথম উপাদানটি অ-স্কেলার।

আমার স্নাতকের:

some_type obj = { 0 };

objশূন্যের সূচনা করার একটি সংক্ষিপ্ত উপায় , যার অর্থ প্রতিটি স্কেলার সাব-অবজেক্ট objসেট করা 0থাকে যদি এটি একটি পূর্ণসংখ্যা হয়, 0.0যদি এটি ভাসমান-বিন্দু হয়, বা যদি কোনও পয়েন্টার হয় তবে নাল পয়েন্টার হয়।

নিয়মগুলি সি ++ এর জন্য একই রকম।

আপনার নির্দিষ্ট ক্ষেত্রে, যেহেতু আপনি মানগুলি sexi.cbSizeনির্ধারিত করছেন এবং এর বাইরে, এটি স্পষ্ট যে SHELLEXECUTEINFOএটি একটি কাঠামো বা শ্রেণির ধরণের (বা সম্ভবত একটি ইউনিয়ন, তবে সম্ভবত নয়), সুতরাং এটি সমস্ত কিছুই প্রযোজ্য নয়, তবে যেমনটি আমি বলেছি { 0 }একটি সাধারণ আইডিয়োম যা আরও সাধারণ পরিস্থিতিতে ব্যবহার করা যেতে পারে।

এই না (অগত্যা) ব্যবহার করে সমতূল্য memsetঅল-বিট-শুন্যতে বস্তুর উপস্থাপনা সেট করতে। ফ্লোটিং-পয়েন্ট 0.0বা কোনও নাল পয়েন্টারও অগত্যা অল-বিট-শূন্য হিসাবে উপস্থাপন করা হয়, এবং একটি { 0 }প্রাথমিককরণ প্রয়োজনীয়ভাবে কোনও নির্দিষ্ট মানকে প্যাডিং বাইট সেট করে না। যদিও বেশিরভাগ সিস্টেমে এটির একই প্রভাব রয়েছে।


1
সি ++ এ {0}কোনও কনস্ট্রাক্টর গ্রহণযোগ্য কোনও বস্তুর বৈধ আরম্ভকারী নয় 0; বা এমন কোনও সামগ্রীর জন্য নয় যার প্রথম উপাদানটি এরূপ (বা কোনও উপাদান সহ একটি সমষ্টি)
এমএম

3

আমি সি / সি ++ এ কাজ করে কিছুক্ষণ হয়ে গেছে তবে আইআইআরসি, একই শর্টকাট অ্যারেগুলির জন্যও ব্যবহার করা যেতে পারে।


2

আমি সবসময় ভাবছি, কেন আপনার মতো ব্যবহার করা উচিত

struct foo bar = { 0 };

এখানে ব্যাখ্যা করার জন্য একটি পরীক্ষার কেস:

check.c

struct f {
    int x;
    char a;
} my_zero_struct;

int main(void)
{
    return my_zero_struct.x;
}

আমি সংকলন করে gcc -O2 -o check check.cতারপরে প্রতীক টেবিলটি আউটপুট করব readelf -s check | sort -k 2(এটি একটি x64 সিস্টেমে উবুন্টু 12.04.2 এ জিসিসি 4.6.3 সহ)। উদ্ধৃতাংশ:

59: 0000000000601018     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
48: 0000000000601018     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
25: 0000000000601018     0 SECTION LOCAL  DEFAULT   25 
33: 0000000000601018     1 OBJECT  LOCAL  DEFAULT   25 completed.6531
34: 0000000000601020     8 OBJECT  LOCAL  DEFAULT   25 dtor_idx.6533
62: 0000000000601028     8 OBJECT  GLOBAL DEFAULT   25 my_zero_struct
57: 0000000000601030     0 NOTYPE  GLOBAL DEFAULT  ABS _end

এখানে গুরুত্বপূর্ণ অংশটি হল, এটি my_zero_structপরে __bss_start। একটি সি প্রোগ্রামের ".bss" বিভাগটি মেমরির বিভাগ যা পূর্বে শূন্যে সেট করা হয় যা .bss এ উইকিপিডিয়াmain দেখুন বলে ।

আপনি যদি উপরের কোডটি এতে পরিবর্তন করেন:

} my_zero_struct = { 0 };

তারপরে ফলস্বরূপ "চেক" এক্সিকিউটেবল উবুন্টু 12.04.2 তে কমপক্ষে gcc 4.6.3 সংকলক সহ ঠিক একই রকম দেখাচ্ছে; my_zero_structএখনও .bssসামনে অধ্যায় এবং এইভাবে এটি স্বয়ংক্রিয়ভাবে শুন্যতে সক্রিয়া করা হবে mainবলা হয়।

মন্তব্যে ইঙ্গিতগুলি, যে কোনও memset"পূর্ণ" কাঠামো সূচনা করতে পারে তাও কোনও উন্নতি নয়, কারণ .bssবিভাগটি পুরোপুরি সাফ হয়ে গেছে যার অর্থ "পূর্ণ" কাঠামোটি শূন্যে সেট করা আছে।

এটি হতে পারে যে সি ভাষার স্ট্যান্ডার্ড এগুলির কোনও উল্লেখ না করে তবে বাস্তব বিশ্বের সি সংকলনে আমি কখনও আলাদা আচরণ দেখিনি।


গ্লোবাল এবং স্ট্যাটিক ভেরিয়েবলগুলি সর্বদা 0 বা ডিফল্ট কর্টারে ডিফল্টরূপে শুরু হয়। আপনি যদি স্থানীয়ভাবে চ এর উদাহরণ ঘোষণা করেন তবে আপনি বিভিন্ন ফলাফল পেতে পারেন।
লগম্যান

-5

{0 একটি বেনামে অ্যারে যার উপাদান 0 হিসাবে থাকে।

এটি 0 এর সাথে অ্যারের এক বা সমস্ত উপাদান সূচনা করতে ব্যবহৃত হয়

যেমন int arr [8] = {0};

এই ক্ষেত্রে আরারের সমস্ত উপাদান 0 হিসাবে শুরু করা হবে।


4
{0}নামবিহীন অ্যারে নয়। এটি এমনকি একটি অভিব্যক্তি না। এটি একটি ইনিশিয়ালাইজার।
কিথ থম্পসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.