সি ক্রিয়াকলাপ কেন নাম-ম্যাঙ্গেলড হতে পারে না?


136

আমি সম্প্রতি একটি সাক্ষাত্কার নিয়েছি এবং একটি প্রশ্ন জিজ্ঞাসা করা হয়েছিল যে extern "C"সি ++ কোডে কী ব্যবহার করা হয়। আমি জবাব দিয়েছি যে সি ++ কোডে সি ফাংশন ব্যবহার করা কারণ সি নাম-ম্যাংলিং ব্যবহার করে না। আমাকে জিজ্ঞাসা করা হয়েছিল কেন সি নাম-ম্যাংলিং ব্যবহার করে না এবং সত্যি বলতে আমি উত্তর দিতে পারিনি।

আমি বুঝতে পারি যে সি ++ সংকলক যখন ফাংশন সংকলন করে, তখন এটি ফাংশনটির একটি বিশেষ নাম দেয় কারণ মূলত আমাদের সি ++ তে একই নামের অতিরিক্ত ক্রিয়াকলাপ থাকতে পারে যা সংকলনের সময় সমাধান করতে হবে। সি-তে, ফাংশনের নামটি একই থাকবে বা সম্ভবত এটির আগে _ দিয়ে থাকবে।

আমার জিজ্ঞাসাটি হ'ল: সি ++ সংকলককেও সিঙ্গেল সি ফাংশনগুলিতে অনুমতি দেওয়ার ক্ষেত্রে কী ভুল? আমি ধরে নিয়েছিলাম যে কম্পাইলার তাদের কী নাম দেয় তাতে কিছু আসে যায় না। আমরা সি এবং সি ++ তে একই পদ্ধতিতে ফাংশনগুলি কল করি।


75
সি নামগুলি ম্যাঙ্গেল করার দরকার নেই , কারণ এতে ফাংশন ওভারলোডিং নেই।
ইওএফ

9
সি ++ সংকলক যদি ফাংশনটির নামগুলি মঙ্গল করে তবে আপনি সি লাইব্রেরিগুলিকে সি ++ কোডের সাথে কীভাবে সংযুক্ত করবেন?
মাদুর

6
"আমি উত্তর দিয়েছিলাম যে সি ++ কোডে সি ফাংশন ব্যবহার করা হয় কারণ সি নাম-ম্যাংলিং ব্যবহার করে না।" - আমি মনে করি এটি অন্যদিকে। বাহ্যিক "সি" সি সংকলকটিতে সি ++ ফাংশনগুলি ব্যবহারযোগ্য করে তোলে। উত্স
রোজিনা

3
@ ইঞ্জিনিয়ার 999: এবং আপনি যদি সি এর উপসেটটি সি ++ এর সাথেও একটি সি ++ সংকলক দিয়ে সংকলন করেন তবে ফাংশনের নামগুলি প্রকৃতপক্ষে ম্যাঙ্গেল হয়ে যাবে। তবে আপনি যদি বিভিন্ন সংকলকগুলির সাথে তৈরি বাইনারিগুলি লিঙ্ক করতে সক্ষম হতে চান তবে আপনি নাম ম্যাংলিং চান না।
ইওএফ

13
সি করে ছিন্ন করা নাম থাকবে না। সাধারণত মাংগেল করা নামটি আন্ডারস্কোরের পূর্বে ফাংশনের নাম। কখনও কখনও এটি একটি আন্ডারস্কোর দ্বারা ফাংশনটির নাম। extern "C"নামটিকে ম্যাঙ্গেল করতে একইভাবে বলে যে "" সি সংকলক চাইবে।
পিট বেকার

উত্তর:


187

এটি উপরে সাজানো উত্তর ছিল, কিন্তু আমি বিষয়গুলিকে প্রসঙ্গে রাখার চেষ্টা করব।

প্রথম, সি প্রথম এসেছিল। যেমন, সি কী করে তা হল "ডিফল্ট" sort এটি নামগুলিতে ম্যাঙ্গেল দেয় না কারণ এটি ঠিক না। একটি ফাংশন নাম একটি ফাংশন নাম। গ্লোবাল হ'ল একটি গ্লোবাল, ইত্যাদি on

তারপরে সি ++ এসেছিল। সি ++ সি হিসাবে একই লিঙ্কারটি ব্যবহার করতে সক্ষম হতে চেয়েছিল এবং সিটিতে লিখিত কোডের সাথে লিঙ্ক করতে সক্ষম হতে চেয়েছিল তবে সি ++ সি "ম্যাংলিং" (বা এর অভাবে) ছেড়ে যেতে পারেনি। নিম্নলিখিত উদাহরণটি দেখুন:

int function(int a);
int function();

সি ++ এ, স্বতন্ত্র সংস্থা সহ এটি স্বতন্ত্র ফাংশন। যদি এগুলির কোনওটিকেই ম্যাংড না করা হয়, তবে উভয়কেই "ফাংশন" (বা "_ফাংশন") বলা হবে এবং লিঙ্কারটি প্রতীকটির পুনঃনির্ধারণ সম্পর্কে অভিযোগ করবে। সি ++ সলিউশনটি ছিল ফাংশনটির নামটিতে যুক্তির ধরণগুলি ছড়িয়ে দেওয়া। সুতরাং, একটি কল করা হয় _function_intএবং _function_voidঅন্যটিকে বলা হয় (প্রকৃত ম্যাংলিং স্কিম নয়) এবং সংঘর্ষ এড়ানো যায়।

এখন আমরা একটি সমস্যা রেখে এসেছি। যদি int function(int a)কোনও সি মডিউলে সংজ্ঞায়িত করা হয় এবং আমরা কেবল সি ++ কোডে এর শিরোনাম (অর্থাত্ ঘোষণাপত্র) নিচ্ছি এবং এটি ব্যবহার করছি, সংকলকটি লিংকটিকে আমদানির জন্য একটি নির্দেশ জেনারেট করবে _function_int। যখন ফাংশনটি সংজ্ঞায়িত করা হত, তখন সি মডিউলে, তাকে বলা হত না। বলা হয়েছিল _function। এটি কোনও লিঙ্কারের ত্রুটির কারণ হবে।

ত্রুটিটি এড়াতে, ফাংশনটি ঘোষণার সময় , আমরা সংকলকটিকে বলি এটি একটি ফাংশন যা একটি সি সংকলকটির সাথে সংযুক্ত, বা সংকলন করার জন্য ডিজাইন করা হয়েছে:

extern "C" int function(int a);

সি ++ সংকলক এখন _functionবরং আমদানি করতে জানে _function_intএবং সব ঠিক আছে।


1
@ শাচারশামেশ: আমি অন্য কোথাও এটি জিজ্ঞাসা করেছি, তবে, সি ++ সংকলিত লাইব্রেরিতে লিঙ্কিংয়ের কী? সংকলকটি যখন আমার কোডটি সি ++ কম্পাইলড লাইব্রেরির একটি ফাংশনকে কল করে পদক্ষেপ এবং সংকলন করছে, তখন এটি কীভাবে জানতে পারে যে কোন নামটি মঙ্গলে বা কেবলমাত্র ঘোষণা বা ফাংশন কলটি দেখলে ফাংশনটিকে দেওয়া হয়? এটি কীভাবে জানবেন যেখানে এটি সংজ্ঞায়িত হয়েছে, এটি অন্য কোনও কিছুর সাথে নামযুক্ত? সুতরাং সি ++ এ অবশ্যই একটি মানক নাম-ম্যাঙ্গলিং পদ্ধতি থাকতে হবে?
ইঞ্জিনিয়ার

2
প্রতিটি সংকলক এটি নিজস্ব নিজস্ব উপায়ে করে। আপনি যদি একই সংকলক দিয়ে সবকিছু সংকলন করেন তবে তাতে কিছু আসে যায় না। আপনি যদি মাইক্রোসফ্টের সংকলক দিয়ে তৈরি করছেন এমন একটি প্রোগ্রাম থেকে বোরল্যান্ডের সংকলক সংকলিত একটি লাইব্রেরি ব্যবহার করার চেষ্টা করুন, তবে ... শুভকামনা; আপনার এটির প্রয়োজন হবে :)
ভিওয়াইওয়াই

6
@ ইঞ্জিনিয়ার 999 কখনও ভেবে দেখেছেন কেন পোর্টেবল সি ++ লাইব্রেরি বলে কোনও জিনিস নেই, তবে তারা হয় তবে আপনাকে কেবল কোনও সিআইপি রফতানি করার জন্য সংকলকটির (এবং স্ট্যান্ডার্ড লাইব্রেরি) ভার্সন (এবং পতাকাগুলি) নির্দিষ্ট করে? এই নাও. সি ++ হ'ল এটি সর্বনিম্নতম সর্বনিম্ন পোর্টেবল ভাষা উদ্ভাবিত, যখন সি এর বিপরীত। সে বিষয়ে প্রচেষ্টা রয়েছে, তবে আপাতত আপনি যদি এমন কিছু চান যা সত্যিই বহনযোগ্য হয় আপনি সি এর সাথে
ভু

1
@ ভু ওয়েল, তাত্ত্বিকভাবে আপনাকে কেবল স্ট্যান্ডার্ড উদাহরণ অনুসরণ করে পোর্টেবল কোড লিখতে সক্ষম হওয়া উচিত -std=c++11এবং স্ট্যান্ডার্ডের বাইরের যে কোনও কিছু ব্যবহার এড়ানো উচিত। এটি জাভা সংস্করণ ঘোষণার মতোই (যদিও নতুন জাভা সংস্করণ পশ্চাদপটে সামঞ্জস্যপূর্ণ)। লোকেরা সংকলক নির্দিষ্ট এক্সটেনশন এবং প্ল্যাটফর্ম নির্ভর কোড ব্যবহার করে এটি স্ট্যান্ডার্ড দোষ নয়। অন্যদিকে, আপনি তাদের দোষ দিতে পারবেন না, কারণ স্ট্যান্ডার্ডে প্রচুর জিনিস (উদাহরণস্বরূপ IO, অনুপস্থিত) রয়েছে। কমিটি ধীরে ধীরে এটি ধরে রাখছে বলে মনে হচ্ছে। আমি কিছু মিস করলে আমাকে সংশোধন করুন।
মুচাহো

14
@ মুচাহো: আপনি উত্স বহনযোগ্যতা / সামঞ্জস্যতার কথা বলছেন। অর্থাত্ এপিআই। ভু বাইনারি সামঞ্জস্যতা সম্পর্কে কথা বলছে , একটি পুনরায় সংকলন ছাড়াই। এটির জন্য এবিআইয়ের সামঞ্জস্যতা প্রয়োজন । সি ++ সংকলকগণ নিয়মিত সংস্করণগুলির মধ্যে তাদের এবিআই পরিবর্তন করে। (যেমন, জি ++ এমনকি স্থিতিশীল এবিআই রাখার চেষ্টা করে না I আমি ধরে নিয়েছি তারা কেবল মজা করার জন্য তারা এবিআইকে ভাঙ্গেন না, তবে কোনও পরিবর্তন করার দরকার আছে এবং অন্য কোনও ভাল উপায় নেই এমন পরিবর্তনগুলি এআইবিআই পরিবর্তনের প্রয়োজন হবে না don't এটা করতে।)।
পিটার কর্ডেস

45

এটি যে তারা "পারে না", সাধারণভাবে তা নয়

যদি আপনি সি সি লাইব্রেরিতে কোনও ফাংশন কল করতে চান foo(int x, const char *y), কেবল আপনার সি ++ সংকলক ম্যাঙ্গেলটি foo_I_cCP()(বা যা কিছু হোক না কেন, কেবলমাত্র ঘটনাস্থলে একটি ম্যাংলিং স্কিম তৈরি করা হয়েছে) কেবল তা করতে দেয় no

এই নামটি সমাধান করবে না, ফাংশনটি সিতে রয়েছে এবং এর নামটি তার যুক্তির ধরণের তালিকার উপর নির্ভর করে না। সুতরাং সি ++ সংকলকটি এটি জানতে হবে, এবং ম্যাংলিংটি এড়াতে সেটিকে সি হিসাবে চিহ্নিত করে।

মনে রাখবেন যে সি ফাংশন এমন কোনও লাইব্রেরিতে থাকতে পারে যার সোর্স কোডটি আপনার কাছে নেই, আপনার সমস্ত কিছুই প্রাক-সংকলিত বাইনারি এবং শিরোনাম। সুতরাং আপনার সি ++ সংকলক "এটি নিজস্ব জিনিস" করতে পারে না, এটি লাইব্রেরিতে যা আছে তার সব পরে পরিবর্তন করতে পারে না।


এই অংশটি আমি মিস করছি। সি ++ কম্পাইলার কেন কোনও ফাংশন নাম মঙ্গলে যখন এটি এর ঘোষণাপত্রটি ঠিক দেখায় বা ডাকবে তা দেখে। এটি বাস্তবায়ন দেখলে এটি কেবল মঙ্গলের ফাংশন নাম নয়? এটি আমার কাছে আরও বোধগম্য হবে
ইঞ্জিনিয়ার

13
@ ইঞ্জিনিয়ার 999: আপনি কীভাবে সংজ্ঞাটির একটি নাম এবং ঘোষণার জন্য আরেকটি নাম রাখতে পারেন? "ব্রায়ান নামে একটি ফাংশন রয়েছে যা আপনি কল করতে পারেন।" "ঠিক আছে আমি ব্রায়ানকে ফোন করব।" "দুঃখিত, ব্রায়ান নামে কোনও কাজ নেই।" দেখা যাচ্ছে একে গ্রাহাম বলে।
অরবিট

সি ++ সংকলিত লাইব্রেরিতে লিঙ্ক করার বিষয়ে কী? সংকলকটি যখন আমাদের কোডটি সি ++ কম্পাইলড লাইব্রেরিতে ফাংশনগুলির মধ্যে একটির কল করে পদক্ষেপ এবং সংকলন করছে, তখন এটি কীভাবে জানতে পারে যে কোন নামটি ম্যাঙ্গেল করা উচিত বা কেবলমাত্র তার ঘোষণা বা ফাংশন কলটি দেখলে ফাংশনটিকে দেওয়া হয়?
ইঞ্জিনিয়ার

1
@ ইঞ্জিনিয়ার 999 উভয়কে অবশ্যই একই ম্যাংলিংয়ে একমত হতে হবে সুতরাং তারা হেডার ফাইলটি দেখুন (মনে রাখবেন, নেটিভ ডিএলএলগুলিতে খুব কম মেটাডেটা রয়েছে - শিরোনামগুলি হ'ল মেটাডেটা) এবং "আহ, ঠিক আছে, ব্রায়ানকে অবশ্যই গ্রাহাম হওয়া উচিত"। যদি এটি কাজ না করে (উদাহরণস্বরূপ দুটি বেমানান ম্যাংলিং স্কিম সহ), আপনি একটি সঠিক লিঙ্ক পাবেন না এবং আপনার অ্যাপ্লিকেশন ব্যর্থ হতে চলেছে। সি ++ এর মতো অনেকগুলি অসম্পূর্ণতা রয়েছে। অনুশীলনে, তারপরে আপনাকে স্পষ্টভাবে ম্যাংলেড নামটি ব্যবহার করতে হবে এবং আপনার পক্ষে ম্যাংলিং নিষ্ক্রিয় করতে হবে (যেমন আপনি আপনার কোডটি গ্রাহামকে কার্যকর করার জন্য বলেছিলেন, ব্রায়ানকে নয়)। ইন প্রকৃত অনুশীলন ... extern "C":)
Luaan

1
@ ইঞ্জিনিয়ার 999 আমি ভুল হতে পারি তবে আপনার কি ভিজ্যুয়াল বেসিক, সি # বা জাভা (অথবা এমনকি কিছুটা পাস্কেল / ডেল্ফি) এর মতো ভাষা নিয়ে অভিজ্ঞতা আছে? এগুলি ইন্টারপকে অত্যন্ত সহজ মনে হয়। সি এবং বিশেষত সি ++ তে এটি কিছুই নয়। আপনার সম্মান জানাতে প্রচুর কলিং কনভেনশন রয়েছে, আপনাকে কী মেমোরির জন্য দায়ী তা জানতে হবে এবং আপনার অবশ্যই হেডার ফাইলগুলি থাকতে হবে যা আপনাকে ফাংশন ডিক্লারেশন বলে দেয়, যেহেতু ডিএলএলগুলিতে তাদের পর্যাপ্ত তথ্য থাকে না - বিশেষত ক্ষেত্রে খাঁটি সি। আপনার যদি একটি শিরোনাম ফাইল না থাকে তবে আপনার সাধারণত এটি ব্যবহার করার জন্য ডিএলএলটি ডিকম্পাইল করতে হবে।
লুয়ান

32

সি ++ সংকলককেও সিঙ্গেল সি ফাংশনগুলিতে অনুমতি দেওয়ার ক্ষেত্রে কী ভুল?

তারা আর সি ফাংশন হবে না।

একটি ফাংশন কেবল একটি স্বাক্ষর এবং সংজ্ঞা নয়; কোনও ফাংশন কীভাবে কাজ করে তা কলিং কনভেনশনের মতো উপাদানগুলির দ্বারা নির্ধারিত হয়। আপনার প্ল্যাটফর্মে ব্যবহারের জন্য নির্দিষ্ট "অ্যাপ্লিকেশন বাইনারি ইন্টারফেস" সিস্টেমগুলি একে অপরের সাথে কীভাবে কথা বলে তা বর্ণনা করে। আপনার সিস্টেমে ব্যবহৃত সি ++ এবিআই একটি নাম ম্যাঙ্গেলিং স্কিম নির্দিষ্ট করে, যাতে সেই সিস্টেমের প্রোগ্রামগুলি জানতে পারে যে কীভাবে গ্রন্থাগারগুলিতে এবং কীভাবে অন্যান্য ক্রিয়াকলাপগুলি চালিত করতে হয়। (দুর্দান্ত উদাহরণের জন্য সি ++ ইটানিয়াম এবিআই পড়ুন it's কেন এটি প্রয়োজনীয় তা আপনি খুব তাড়াতাড়ি দেখতে পাবেন))

আপনার সিস্টেমে সি এবিআইয়ের ক্ষেত্রেও এটি একই প্রযোজ্য। কিছু সি এ বি আই-র প্রকৃতপক্ষে একটি নাম ম্যাঙ্গলিং স্কিম থাকে (যেমন ভিজ্যুয়াল স্টুডিও), সুতরাং এটি নির্দিষ্ট কাজের জন্য "নাম নাম্বার ম্যাংলিং বন্ধ করে" এবং সি ++ এবিআই থেকে সি এবিআইতে স্যুইচ করা সম্পর্কে আরও কম। আমরা সি ফাংশনগুলিকে সি ফাংশন হিসাবে চিহ্নিত করি, যার প্রতি সি এবিআই (সি ++ এবিআইয়ের পরিবর্তে) প্রাসঙ্গিক। ঘোষণার অবশ্যই সংজ্ঞাটির সাথে মিল থাকতে হবে (এটি একই প্রকল্পে বা কোনও তৃতীয় পক্ষের লাইব্রেরিতে থাকুক), অন্যথায় ঘোষণাটি অর্থহীন। তা ছাড়া, আপনার সিস্টেমগুলি কীভাবে এই ফাংশনগুলি সনাক্ত করতে / প্রার্থনা করতে পারে তা সহজেই জানতে পারে না।

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


2
+int(PI/3), তবে লবণের এক দানা দিয়ে: আমি "সি ++ এবিআই" কথা বলতে খুব সতর্ক হতে পারি ... আফাইক, সি ++ এবিআই সংজ্ঞায়নের চেষ্টা করা হচ্ছে, তবে আসল ডি-ফ্যাক্টো / ডি জুর স্ট্যান্ডার্ডগুলি নেই - আইসোকেপ.অর্গ / ফাইল হিসাবে /papers/n4028.pdf বলেছে (এবং আমি আন্তরিকভাবে একমত হই), উক্তিটি গভীরভাবে বিদ্রূপজনক যে সি ++ সত্যই সবসময় একটি স্থিতিশীল বাইনারি এবিআই সহ একটি API প্রকাশ করার উপায়কে সমর্থন করে ex সি ++ এর সি সি উপসেটটি বাহ্যিক "সি এর মাধ্যমে অবলম্বন করে — "। C++ Itanium ABIশুধু যে হয় - কিছু Itanium- র জন্য সি ++ ABI- র ... যেমন আলোচনা stackoverflow.com/questions/7492180/c-abi-issues-list

3
@ ভ্যাক্সকুইস: হ্যাঁ, "সি +++ এর এবিআই" নয়, "একটি সি ++ এবিআই" একইভাবে আমার কাছে একটি "বাড়ির চাবি" রয়েছে যা প্রতিটি বাড়িতে কাজ করে না। অনুমান করুন এটি আরও পরিষ্কার হতে পারে, যদিও আমি " আপনার সিস্টেমের দ্বারা ব্যবহৃত সি ++ এবিআই" এই বাক্যটি শুরু করে এটি যথাসম্ভব পরিষ্কার করার চেষ্টা করেছি । আমি বংশবৃদ্ধির জন্য পরবর্তী কথায় স্পষ্টকটিকে বাদ দিয়েছি, তবে আমি এমন একটি সম্পাদনা গ্রহণ করব যা এখানে বিভ্রান্তি হ্রাস করে!
অরবিট

1
এআইআইআইআই সি আবির একটি প্ল্যাটফর্মের সম্পত্তি হিসাবে প্রবণতা ছিল যখন সি ++ এবিআই পৃথক সংকলকের সম্পত্তি এবং প্রায়শই একটি সংকলকের পৃথক সংস্করণের সম্পত্তিও ছিল। সুতরাং আপনি যদি বিভিন্ন বিক্রেতাদের সরঞ্জামগুলির সাথে নির্মিত মডিউলগুলির মধ্যে লিঙ্ক করতে চান তবে আপনাকে ইন্টারফেসের জন্য একটি সি আবির ব্যবহার করতে হবে।
প্লাগওয়াশ

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

@ পিটারএ.স্নাইডার: হ্যাঁ, শিরোনামের বাক্যটি অতিরঞ্জিত। উত্তর সমগ্র বাকি প্রাসঙ্গিক তথ্যসংক্রান্ত বিস্তারিত রয়েছে।
অরবিট

21

আসলে MSVC করে ছিন্ন করা সেঃ নাম, যদিও একটি সহজ ফ্যাশন। এটি কখনও কখনও সংযোজন হয় @4বা অন্য একটি ছোট সংখ্যা। এটি কলিং কনভেনশন এবং স্ট্যাক ক্লিনআপের প্রয়োজনীয়তার সাথে সম্পর্কিত।

সুতরাং ভিত্তি ঠিক ত্রুটিযুক্ত।


2
এটি আসলে ম্যাংলিংয়ের নাম নয়। এক্সিকিউটেবলদের বিভিন্ন কলিং কনভেনশন সম্বলিত ফাংশনগুলির সাথে নির্মিত ডিএলএলগুলির সাথে যুক্ত হওয়া সম্পর্কিত সমস্যাগুলি রোধ করার জন্য এটি কেবল কোনও বিক্রেতার নির্দিষ্ট নামকরণ (বা নাম অ্যাডর্নিং) কনভেনশন।
পিটার

2
একটি সঙ্গে প্রিপেন্ডিং সম্পর্কে কি _?
অরেঞ্জডগ

12
@ পিটার: আক্ষরিকভাবে একই জিনিস।
অরবিট

5
@ ফ্রেঙ্কি_সি: "কলার স্ট্যাক পরিষ্কার করে" কোনও সি স্ট্যান্ডার্ড দ্বারা সুনির্দিষ্ট করা হয় না: কলিং কনভেনশন কোনও ভাষার দৃষ্টিকোণ থেকে অন্যটির চেয়ে বেশি স্ট্যান্ডার্ড নয়।
বেন ভয়েগট

2
এবং একটি এমএসভিসি দৃষ্টিকোণ থেকে, "স্ট্যান্ডার্ড কলিং কনভেনশন" হ'ল আপনি যা পছন্দ করেন /Gd, /Gr, /Gv, /Gz। (এটি বলতে গেলে, কোনও ফাংশন ঘোষণার মাধ্যমে স্পষ্টভাবে কলিং কনভেনশন নির্দিষ্ট না করা না হলে স্ট্যান্ডার্ড কলিং কনভেনশনটিই ব্যবহৃত হয়) আপনি __cdeclযেটি ডিফল্ট স্ট্যান্ডার্ড কলিং কনভেনশন thinking
এমসাল্টাররা

13

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

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

/* Note that there are no underscores before the "pascal" keyword because
   the Toolbox was written in the early 1980s, before the Standard and its
   underscore convention were published */
pascal void LineTo(short x, short y);

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


হ্যাঁ, এটি উত্তর। এটি যদি কেবল সি এবং সি ++ হয় তবে কেন এটি করা হয় তা বোঝা মুশকিল। বুঝতে হলে আমাদের অবশ্যই স্ট্যাটিকালি লিঙ্কিংয়ের পুরানো পদ্ধতির প্রসঙ্গে জিনিস রাখতে হবে। স্ট্যাটিক লিঙ্কিংটি উইন্ডোজ প্রোগ্রামারদের কাছে আদিম বলে মনে হচ্ছে তবে এটি সি কারণগুলির নামগুলি ম্যাঙ্গেল করতে পারে না reason
ব্যবহারকারী 34660

2
@ ব্যবহারকারী 34660: কোয়েটি নয়। এ কারণেই সি এর বৈশিষ্ট্যগুলির অস্তিত্বকে নির্দেশ দিতে পারে না যার বাস্তবায়নের জন্য রফতানিযোগ্য নামগুলি মংলিংয়ের প্রয়োজন হবে, বা একাধিক পছন্দসই চিহ্নগুলির অস্তিত্বের অনুমতি দেওয়া হবে যা গৌণ বৈশিষ্ট্য দ্বারা আলাদা করা হবে।
সুপারক্যাট

আমরা কী জানি যে এই জাতীয় জিনিসগুলির "আদেশ" দেওয়ার চেষ্টা করা হয়েছিল বা এই জাতীয় জিনিসগুলি সি ++ এর আগে সিটির জন্য এক্সটেনশন উপলব্ধ ছিল?
ব্যবহারকারী 34660

@ ব্যবহারকারী 34660: পুনরায় "উইন্ডোজ প্রোগ্রামারদের কাছে স্ট্যাটিক লিঙ্কিং আদিম বলে মনে হচ্ছে ...", তবে ডায়ামিক লিঙ্কিং কখনও কখনও লিনাক্স ব্যবহারকারী লোকদের কাছে বড় পিতার মতো মনে হয়, যখন প্রোগ্রাম এক্স ইনস্টল করার সময় (সম্ভবত সি ++ তে লিখিত) অর্থ নির্দিষ্ট সংস্করণগুলি ট্র্যাক করে ইনস্টল করতে হবে means আপনার সিস্টেমে ইতিমধ্যে লাইব্রেরির বিভিন্ন সংস্করণ রয়েছে।
জামেস্কেফ

@ জামেস্কেফ, হ্যাঁ, উইন্ডোজের আগে ইউনিক্সের গতিশীল সংযোগ ছিল না। আমি ইউনিক্স / লিনাক্সে ডায়নামিক লিঙ্কিং সম্পর্কে খুব কম জানি তবে এটি মনে হয় এটি সাধারণ হিসাবে অপারেটিং সিস্টেমে যেমন নির্বিঘ্ন হয় না তেমন হয়।
ব্যবহারকারী 34660

12

আমি অন্য একটি উত্তর যুক্ত করব, সংঘটিত কিছু স্পর্শকাতর আলোচনার উদ্দেশ্যে।

সি এবিআই (অ্যাপ্লিকেশন বাইনারি ইন্টারফেস) মূলত বিপরীত ক্রমে স্ট্যাকের উপর যুক্তিগুলি পাস করার জন্য ডাকা হয়েছিল (যেমন - ডান থেকে বাম দিকে ঠেলা), যেখানে কলার স্ট্যাকের সঞ্চয়স্থানও মুক্ত করে। আধুনিক এবিআই প্রকৃত পক্ষে যুক্তিগুলি পাস করার জন্য রেজিস্টারগুলি ব্যবহার করে, তবে অনেকগুলি ম্যাংলিং বিবেচনা সেই মূল স্ট্যাক আর্গুমেন্ট পাসিংয়ে ফিরে যায়।

আসল পাস্কাল এবিআই, বিপরীতে, যুক্তিগুলি বাম থেকে ডানে ঠেলে দিয়েছে এবং কলিটিকে যুক্তিগুলি পপ করতে হয়েছিল। মূল সি এবিআই দুটি গুরুত্বপূর্ণ পয়েন্টে মূল পাস্কাল এবিআইয়ের চেয়ে উচ্চতর। আর্গুমেন্ট পুশ অর্ডারটির অর্থ হ'ল প্রথম আর্গুমেন্টের স্ট্যাক অফসেটটি সর্বদা জানা থাকে, ফাংশনগুলিতে মঞ্জুরি দেয় যার অজানা সংখ্যক যুক্তি রয়েছে, যেখানে প্রাথমিক আর্গুমেন্টগুলি নিয়ন্ত্রণ করে যে আরও কতগুলি আর্গুমেন্ট রয়েছে (আলা printf)।

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

আসল উইন্ডোজ ৩.১ এবিআই প্যাস্কেলের উপর ভিত্তি করে ছিল। যেমন, এটি প্যাসকেল এবিআই ব্যবহার করেছে (বাম থেকে ডান ক্রমে যুক্তি, কলি পপস)। যেহেতু আর্গুমেন্ট সংখ্যার কোনও অমিলের ফলে স্ট্যাক দুর্নীতির দিকে পরিচালিত হতে পারে, তাই ম্যাংলিং স্কিম তৈরি হয়েছিল। প্রতিটি ফাংশনের নামটি তার আর্গুমেন্টের আকার, বাইটে, নির্দেশ করে একটি সংখ্যার সাথে ম্যাঙ্গেল করা হয়েছিল। সুতরাং, 16 বিট মেশিনে, নিম্নলিখিত ফাংশন (সি সিনট্যাক্স):

int function(int a)

ম্যাঙ্গেলড ছিল function@2, কারণ intদুটি বাইট প্রশস্ত। এটি করা হয়েছিল যাতে ঘোষণা এবং সংজ্ঞাটি মেলে না, লিঙ্কার রান সময়ে স্ট্যাকটিকে দূষিত করার পরিবর্তে ফাংশনটি খুঁজে পেতে ব্যর্থ হবে। বিপরীতে, যদি প্রোগ্রামটি লিঙ্ক হয়, তবে আপনি নিশ্চিত হতে পারেন যে কলের শেষে স্ট্যাক থেকে সঠিক বাইটগুলি পপ করা হয়েছে।

32 বিট উইন্ডোজ এবং এর stdcallপরিবর্তে এবিআই ব্যবহার করুন। এটি পাস্কাল এবিআইয়ের মতো, ধাক্কা ক্রমান ডান থেকে বামে সি এর মতোই। পাস্কাল এবিআইয়ের মতো, ম্যাকলিং নামটি স্ট্যাক দুর্নীতি এড়াতে ফাংশনটির নামের সাথে যুক্তিগুলি বাইট আকারকে মঙ্গল করে।

এখানে অন্য কোথাও করা দাবিগুলির বিপরীতে, সি এবিআই ভিজ্যুয়াল স্টুডিওতে এমনকি ফাংশনটির নামগুলি ম্যাঙ্গেল করে না। বিপরীতে, stdcallএবিআই স্পেসিফিকেশন দিয়ে সজ্জিত ম্যাংলিং ফাংশনগুলি ভিএস-এর পক্ষে অনন্য নয় isn't লিনাক্সের জন্য সংকলন করার পরেও জিসিসি এই এবিআইকে সমর্থন করে। এটি ওয়াইন দ্বারা ব্যাপকভাবে ব্যবহৃত হয় , এটি লিনাক্স সংকলিত বাইনারিগুলির উইন্ডোজ সংকলিত ডিএলএলগুলির সাথে রান টাইম লিঙ্ক করার অনুমতি দেওয়ার জন্য তার নিজস্ব লোডার ব্যবহার করে।


9

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

সি এর প্রয়োজন হয় না কারণ এটি ফাংশনগুলির ওভারলোডিংয়ের অনুমতি দেয় না।

মনে রাখবেন যে নাম ম্যাংলিং একটি (তবে অবশ্যই একমাত্র নয়!) কারণ যে কোনও 'সি ++ এবিআই'র উপর নির্ভর করতে পারে না।


8

সি ++ এর সাথে লিঙ্ক করা সি কোডের সাথে ইন্টারঅ্যাপ করতে সক্ষম হতে চায় বা এর বিপরীতে লিঙ্ক করে।

সি অ-নাম-ম্যাংলেড ফাংশন নাম প্রত্যাশা করে।

যদি সি ++ এটি ম্যাংলড করে তবে এটি সি থেকে রফতানি করা অ-মঙ্গলেড ফাংশনগুলি খুঁজে পাবে না, বা সি সি ++ রফতানি করবে না। সি লিঙ্কারের নামটি নিজেই প্রত্যাশা করা উচিত, কারণ এটি জানে না যে এটি সি ++ থেকে আসছে বা যাচ্ছে।


3

সি ফাংশন এবং ভেরিয়েবলের নাম মাংগিং লিঙ্ক সময়ে তাদের ধরণের পরীক্ষা করতে অনুমতি দেয়। বর্তমানে, সমস্ত (?) সি বাস্তবায়ন আপনাকে একটি ফাইলের মধ্যে একটি ভেরিয়েবল সংজ্ঞায়িত করতে এবং অন্যটিতে ফাংশন হিসাবে কল করার অনুমতি দেয়। অথবা আপনি কোনও ভুল স্বাক্ষর সহ কোনও ফাংশন ঘোষণা করতে পারেন (যেমন void fopen(double)এবং তারপরে এটি কল করুন।

১৯৯১ সালে ম্যাংলিং ব্যাক ব্যবহারের মাধ্যমে সি ভেরিয়েবল এবং ফাংশনগুলির টাইপ-নিরাপদ সংযোগের জন্য আমি একটি প্রকল্পের প্রস্তাব দিয়েছিলাম scheme


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