আকার (আমার_আর) [0] সংকলন এবং সমান আকারের (মাই_আর [0]) কেন?


129

এই কোডটি সংকলন করে কেন?

_Static uint32_t my_arr[2];
_Static_assert(sizeof(my_arr) == 8, "");
_Static_assert(sizeof(my_arr[0]) == 4, "");
_Static_assert(sizeof(my_arr)[0] == 4, "");

প্রথম 2 টি দৃts়ভাবে স্পষ্টতই সঠিক, তবে আমি শেষ পংক্তিটি ব্যর্থ হওয়ার প্রত্যাশা করতাম, কারণ আমার বোঝাপড়াটি হ'ল sizeof()একটি পূর্ণসংখ্যা শাব্দিককে মূল্যায়ন করা উচিত, যা অ্যারে হিসাবে বিবেচনা করা যায় না। অন্য কথায়, এটি একইভাবে ব্যর্থ হবে যেভাবে নিম্নলিখিত লাইনটি ব্যর্থ হয়:

_Static_assert(4[0] == 4, "");

মজার বিষয় হচ্ছে, নিম্নলিখিতগুলি সংকলন করতে ব্যর্থ হয়েছে (যা একই জিনিসটি করা উচিত, না?):

_Static_assert(*sizeof(my_arr) == 4, "");

ত্রুটি: আনরি'র অবৈধ প্রকারের আর্গুমেন্ট '*' ('দীর্ঘ স্বাক্ষরিত ইন্ট' রয়েছে )__ট্যাটিক_সেসার্ট (* আকারের (আমার_আর) == 4, "");

যদি এটি গুরুত্বপূর্ণ হয় তবে আমি জিসিসি 5.3.0 ব্যবহার করছি


15
আমি সন্দেহ করি ( sizeof( my_arr ) )[ 0 ]ব্যর্থ।
অ্যান্ড্রু হেনেল

সাম্প্রতিক ডুপ্লিকেটটিতে এই সিনট্যাক্স অবাক করার ক্ষেত্রে আরও একটি ভিন্নতা রয়েছে: কেন সাইজফ (এক্স) ++ সংকলন করে?
পিটার কর্ডস

উত্তর:


197

sizeofকোন কাজ নয়। এটি !বা মত একটি unary অপারেটর ~

sizeof(my_arr)[0]পার্স হিসাবে sizeof (my_arr)[0], যা কেবল sizeof my_arr[0]রিলানডেন্ট প্রথম বন্ধনীর সাথে।

এটি ঠিক যেমন !(my_arr)[0]পার্সের মতো !(my_arr[0])

সাধারণভাবে, পোস্টফিক্স অপারেটরগুলির সি sizeof *a[i]++পার্সে প্রিফিক্স অপারেটরগুলির চেয়ে বেশি অগ্রাধিকার রয়েছে sizeof (*((a[i])++))(পোস্টফিক্স অপারেটরগুলি []এবং প্রথমে ++প্রয়োগ করা হয় a, তারপরে প্রিফিক্স অপারেটর *এবং sizeof)।

(এটির এক্সপ্রেশন সংস্করণ এটি sizeof। এখানে একটি প্রকারের সংস্করণও রয়েছে, যা একটি প্রথম বন্ধনীযুক্ত টাইপের নাম নেয়: sizeof (TYPE)এই ক্ষেত্রে প্যারেনগুলি প্রয়োজন হবে এবং sizeofবাক্য গঠনটির অংশ হবে ))


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

মেল্পোমেন আকর্ষণীয় আমি কখনই sizeofইউনারি অপারেটর হওয়ার কথা ভাবিনি ।
মিউট্যান্টবোর্ড

5
মানে না "... parses as sizeof (my_arr[0])"? কেবল একটি স্থান যুক্ত করা সত্যিই কিছু পরিবর্তন করে না।
বার্নহার্ড বার্কার

আমি sizeof((my_array)[0])পরিবর্তে সুপারিশ করব
বলভ


46

sizeofদুটি "সংস্করণ" রয়েছে: sizeof(type name)এবং sizeof expression। পূর্বেরটির পক্ষে ()তার যুক্তির চারপাশে একটি জুড়ি প্রয়োজন । তবে পরেরটি - একটি আর্গুমেন্ট হিসাবে প্রকাশের সাথে - ()এর তর্কটির চারপাশে নেই । আপনি ()আর্গুমেন্টে যা ব্যবহার করেন তা আর্গুমেন্টের অভিব্যক্তির অংশ হিসাবে দেখা হয়, sizeofনিজে বাক্য গঠনের অংশ নয়।

যেহেতু my_arrসংকলকটির কাছে কোনও প্রকারের নাম নয়, কোনও বস্তুর নাম হিসাবে পরিচিত, তাই আপনার sizeof(my_arr)[0]সংকলনটি আসলে sizeofএকটি অভিব্যক্তির প্রয়োগ হিসাবে দেখা যায় : sizeof (my_arr)[0]যেখানে (my_arr)[0]আর্গুমেন্ট এক্সপ্রেশন is ()পার্শ্ববর্তী অ্যারের নাম বিশুদ্ধরূপে প্রযোজন নেই। পুরো এক্সপ্রেশন হিসাবে ব্যাখ্যা করা হয় sizeof my_arr[0]। এটি আপনার আগেরটির সমতুল্য sizeof(my_arr[0])

(এর অর্থ, বিটিডাব্লু, আপনার আগেরটিতেও sizeof(my_arr[0])অতিরিক্ত একজোড়া জুড়ে রয়েছে ()))

এটি একটি বরং বিভ্রান্ত ধারণা যা sizeofএর সিনট্যাক্সের জন্য কোনওভাবে ()তার যুক্তির চারপাশে একটি জুড়ি প্রয়োজন । এই মতামত ব্যাখ্যা করার সময় এই ভুল ধারণাটি মানুষের অন্তর্নিহিতাকে বিভ্রান্ত করে sizeof(my_arr)[0]


1
প্রথম সংস্করণটি উপস্থিত রয়েছে যাতে আপনি মেশিনে সাধারণভাবে কোনও পূর্ণসংখ্যার আকার পরীক্ষা করতে পারেন (পিছনে যখন 64৪-বিট মেশিনও ছিল না!) তবে intএটি কোনও বৈধ এক্সপ্রেশন নয়, তাই আপনি এটি ব্যবহার করতে পারবেন না এটি দিয়ে দ্বিতীয় ফর্ম।
এনএইচ।

25

[]তুলনায় একটি উচ্চতর প্রাধান্য আছে sizeof। তাই sizeof(my_arr)[0]হিসাবে একই sizeof((my_arr)[0])

এখানে একটি অগ্রাধিকার টেবিলের লিঙ্ক দেওয়া আছে।


8

আপনি sizeofঅপারেটরের সংস্করণটি ব্যবহার করছেন যা প্যারামিটার হিসাবে প্রকাশ করে। যে ধরণের ধরণ লাগে তার থেকে পৃথক , এর জন্য প্রথম বন্ধনী প্রয়োজন হয় না । অতএব, প্রথম (my_arr)[0]বন্ধনী অপ্রয়োজনীয় হওয়ায় অপারেন্ডটি সহজ ।

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