স্ট্যাক ভেরিয়েবলগুলি কি জিসিসি __ট্রিবিউট __ ((প্রান্তিককরণ (এক্স))) দ্বারা সংযুক্ত আছে?


88

আমার কাছে নিম্নলিখিত কোড রয়েছে:

এবং আমি নিম্নলিখিত আউটপুট আছে:

এর ঠিকানাটি কেন a[0]একাধিক নয় 0x1000?

ঠিক কি __attribute__((aligned(x)))করে? আমি এই ব্যাখ্যা ভুল বুঝেছি ?

আমি জিসিসি ব্যবহার করছি 4.1.2।

উত্তর:


98

আমি বিশ্বাস করি যে সমস্যাটি হ'ল আপনার অ্যারে স্ট্যাকের উপরে রয়েছে এবং আপনার সংকলক ওভার-অ্যালাইন্টেড স্ট্যাক ভেরিয়েবলগুলি সমর্থন করার জন্য খুব পুরানো। GCC 4.6 এবং পরে এই বাগটি ঠিক করেছে

C11 / C ++ 11 alignas(64) float a[4];কেবল 2 প্রান্তিককরণের যে কোনও পাওয়ারের জন্য কাজ করে। আপনি এটি ব্যবহার করছেন ঠিক
তেমনই জিএনইউ সিও __attribute__((aligned(x)))করে।

(সি 11 এ, এর #include <stdalign.h>জন্য #define alignas _Alignas: সিপিপিআরএফ )।


তবে আপনার একটি খুব বড় সারিবদ্ধকরণের ক্ষেত্রে, 4k পৃষ্ঠার সীমানায়, আপনি স্ট্যাকের মধ্যে এটি নাও চাইতে পারেন।

ফাংশন শুরু হওয়ার সাথে সাথে স্ট্যাক পয়েন্টারটি যে কোনও কিছু হতে পারে, আপনার প্রয়োজনের চেয়ে অনেক বেশি বরাদ্দ না করে এবং এডজাস্ট না করে অ্যারে সারিবদ্ধ করার কোনও উপায় নেই। ( and rsp, -4096সংকলকগণ বরাদ্দকৃত 0 থেকে 4088 বাইটগুলির মধ্যে কোনওটিই সমতুল্য এবং ব্যবহার করবেন না; সেই স্থানটি যথেষ্ট পরিমাণে বড় কিনা তা শাখা করা সম্ভব হবে তবে সম্পন্ন হয়নি কারণ অ্যারের বা অন্য স্থানীয়দের আকারের চেয়ে বিশাল প্রান্তিককরণ খুব বড় হবে) সাধারণ ঘটনা নয়।)

আপনি যদি অ্যারেরটিকে ফাংশন থেকে বাইরে নিয়ে এবং একটি বৈশ্বিক পরিবর্তনশীল হিসাবে নিয়ে যান তবে এটি কাজ করা উচিত। আপনি যা করতে পারেন তা হ'ল এটি স্থানীয় ভেরিয়েবল হিসাবে রাখা (যা খুব ভাল জিনিস), তবে এটি তৈরি করুন static। এটি স্ট্যাকের মধ্যে সংরক্ষণ হতে বাধা দেবে। সাবধান থাকুন যে এই দুটি উপায়ই থ্রেড-সেফ বা পুনরাবৃত্তি-নিরাপদ নয়, কারণ অ্যারের কেবলমাত্র একটি অনুলিপি থাকবে।

এই কোড সহ:

বুঝতে পেরেছি:

যা প্রত্যাশা করা হয় আপনার আসল কোডটি সহ, আমি আপনার মতো এলোমেলো মানগুলি পাই।


11
+1 সঠিক উত্তর। একটি বিকল্প সমাধান হ'ল স্থানীয় অ্যারে স্থির করা। স্ট্যাকের সারিবদ্ধকরণ সর্বদা একটি সমস্যা এবং এটি এড়ানোর অভ্যাসে প্রবেশ করা ভাল।
ড্যান ওলসন

ওহ হ্যাঁ, আমি এটিকে স্থির করার কথা ভাবিনি। এটি নামের সংঘর্ষকে বাধা দেয় বলে এটি একটি ভাল ধারণা। আমি আমার উত্তর সম্পাদনা করব।
জিফ্রে

4
নোট করুন যে এটিকে স্থিতিশীল করে তোলা এটিকে পুনঃপ্রেরণকারী এবং অ-থ্রেড-নিরাপদ করে তোলে।
ArchaeaSoftware

4
এছাড়াও জিসিসি 4.6+ এমনকি স্ট্যাকের মধ্যেও এটি সঠিকভাবে পরিচালনা করে।
পাঠ্যক্রম

4
এই উত্তরটি সঠিক ব্যবহৃত হত, তবে এখন তা নয়। ৪.6-এর মতো পুরানো জিসিসি, সম্ভবত এটি আরও পুরানো, কীভাবে সি 11 / সি ++ 11 সঠিকভাবে প্রয়োগ করতে alignas(64)বা স্বয়ংক্রিয় স্টোরেজ সহ যে কোনও জিনিস যা সঠিকভাবে প্রয়োগ করতে স্ট্যাক পয়েন্টারটিকে প্রান্তিককরণ করতে জানে । এবং অবশ্যই জিএনইউ সি__attribute((aligned((64)))
পিটার

41

জিসিসিতে একটি ত্রুটি ছিল যা অ্যাট্রিবিউটকে স্ট্যাক ভেরিয়েবলগুলির সাথে কাজ না করার জন্য সংযুক্ত করে তোলে । এটি নীচের সাথে সংযুক্ত প্যাচটির সাথে স্থির হয়ে গেছে বলে মনে হচ্ছে। নীচের লিঙ্কটিতেও সমস্যাটির জন্য বেশ খানিকটা আলোচনা রয়েছে।

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16660

আমি উপরে আপনার কোডটি জিসিসি-র দুটি ভিন্ন সংস্করণ দিয়ে চেষ্টা করেছি: একটি রেডহ্যাট ৫. box বাক্স থেকে ৪.১.২ এবং এটি আপনার সমস্যার সাথে একইভাবে ব্যর্থ হয়েছে (স্থানীয় অ্যারেগুলি কোনওভাবেই 0x1000 বাইট সীমানায় সারিবদ্ধ হয়নি)। আমি তখন আপনার কোডটি রেডহ্যাট .3.৩ এ জিসিসি ৪.৪..6 দিয়ে চেষ্টা করেছি এবং এটি নির্বিঘ্নে কাজ করেছে (স্থানীয় অ্যারেগুলি সারিবদ্ধ হয়েছিল)। পৌরাণিক কাহিনী টিভির লোকদের একই সমস্যা ছিল (যা উপরের জিসিসি প্যাচটি ঠিক করেছিল):

http://code.mythtv.org/trac/ticket/6535

যাইহোক, দেখে মনে হচ্ছে আপনি জিসিসি-তে একটি বাগ খুঁজে পেয়েছেন, যা পরবর্তী সংস্করণগুলিতে স্থির হয়েছে বলে মনে হচ্ছে।


4
লিঙ্কযুক্ত বাগ gcc অনুসারে 4.6 প্রথম রিলিজ ছিল এই সমস্যাটি সমস্ত স্থাপত্যের জন্য পুরোপুরি ঠিক করা হয়েছিল fixed
পাঠ্যক্রম

তার পাশেই, সিসিতে সারিবদ্ধ ভেরিয়েবল তৈরি করতে জিসিসি দ্বারা উত্পাদিত অ্যাসেম্বলি কোডটি এত ভয়াবহ এবং বিনা প্রতিরোধী। সুতরাং, কল করার পরিবর্তে স্ট্যাকের উপর বর্ধিত ভেরিয়েবলগুলি বরাদ্দ করা কি বোধগম্য memalign()?
জেরুমে পাউিলার

13

সাম্প্রতিক জিসিসি (4.5.2-8ubuntu4 দিয়ে পরীক্ষিত) সঠিকভাবে সাজানো অ্যারের সাথে প্রত্যাশা অনুযায়ী কাজ করতে দেখা যাচ্ছে।

আমি পাই:


এটি খানিকটা আশ্চর্যের বিষয়, অ্যারেগুলি স্ট্যাকের মধ্যে বরাদ্দ দেওয়া বিবেচনা করে - এটির অর্থ কি এই স্ট্যাকটি এখন গর্তে পূর্ণ?
ysap

অথবা তার স্ট্যাকটি 16-বাইট সারিবদ্ধ হয়েছে।
user7116

9

Alignement সব ধরণের জন্য কার্যকর নয়। কর্মের বৈশিষ্ট্যগুলি দেখতে আপনার কোনও কাঠামো ব্যবহার করার কথা বিবেচনা করা উচিত:

এবং তারপরে, আপনি পড়বেন:

যা আপনি প্রত্যাশা করেছিলেন।

সম্পাদনা: @ ইয়াজাপ দ্বারা ধাক্কা এবং @ কালেব কেস মন্তব্যটি অনুসরণ করে, প্রাথমিক সমস্যাটি কেবলমাত্র জিসিসি সংস্করণের কারণে । আমি জিসিসি ৩.৪..6 বনাম জিসিসি ৪.৪.১ এ পরীক্ষকের উত্স কোডের সাহায্যে পরীক্ষা করেছি:

এটি এখন সুস্পষ্ট যে পুরানো জিসিসি সংস্করণ (৪.৪.১ এর আগে কোথাও) প্রান্তিককরণ প্যাথলজিগুলি দেখায়।

নোট 1: আমার প্রস্তাবিত কোড সেই প্রশ্নের উত্তর দেয় না যা আমি "অ্যারের প্রতিটি ক্ষেত্র সারিবদ্ধ করা" হিসাবে বুঝেছিলাম।

নোট 2: স্থির অ-স্থিতিশীল একটি [] মূল () এর ভিতরে নিয়ে আসা এবং জিসিসি 3.4.6 এর সাথে সংকলন স্ট্রাকের অ্যারের প্রান্তিককরণের নির্দেশকে সরিয়ে দেয় তবে স্ট্রাক্টের মধ্যে 0x1000 দূরত্ব রাখে ... এখনও খারাপ! (কর্মক্ষেত্রের জন্য জিজিফের উত্তর দেখুন)


4
জিফরে উত্তর হিসাবে, এটি প্রকার নয়, তবে আপনি এটি আপনার সংস্করণে স্থির করেছেন।
ysap

@ সাইপ, এটি জিসিসির সংস্করণ এবং বৈশ্বিক সংজ্ঞা উভয়ই এটি কার্যকর করেছে। আপনার মন্তব্য করার জন্য ধন্যবাদ! আমি এটি ঠিক করার জন্য উত্তর সম্পাদনা করেছি। :)
লেভিফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.