কেন এখানে মূল 0 ফিরে আসে না?


116

আমি তখনই পড়ছিলাম

আইএসও / আইইসি 9899: 201x কমিটির খসড়া - এপ্রিল 12, 2011

যার মধ্যে আমি 5.1.2.2.3 প্রোগ্রামের সমাপ্তির আওতায় পেয়েছি

..reaching the } that terminates the main function returns a value of 0. 

এর অর্থ যদি আপনি কোনও রিটার্নের বিবৃতি নির্দিষ্ট না করেন main()এবং প্রোগ্রামটি যদি সফলভাবে চলতে থাকে তবে মূল বন্ধের ব্রেস-এ 0 ফিরে আসবে।

তবে নিম্নলিখিত কোডটিতে আমি কোনও রিটার্নের বিবৃতি নির্দিষ্ট করে দিই না, তবে এটি 0 ফেরায় না

#include<stdio.h>
int sum(int a,int b)
{
return (a + b);
}

int main()
{
    int a=10;
    int b=5;
    int ans;    
    ans=sum(a,b);
    printf("sum is %d",ans);
}

কম্পাইল

gcc test.c  
./a.out
sum is 15
echo $?
9          // here it should be 0 but it shows 9 why?

69
চশমা পড়ার ধৈর্য থাকার জন্য +1 .....
আশের

16
gccনিজেই (সংস্করণ 4.6.2 এর জন্য) খুব অনুরূপ একটি ভাষা সংকলন করে তবে সি এর মতো নয় এটি গনুসি 89 কে সংকলন করে - সি 89 এর উপর ভিত্তি করে একটি ভাষা "আলগাভাবে"।
পিএমজি

2
returnবিবৃতিতে প্রথম বন্ধনীগুলি sum()অপ্রয়োজনীয়। int main()হওয়া উচিত int main(void)
কিথ থমসন

24
বিভ্রান্তি! = টাইপ আমার কীবোর্ডে '0' এবং 'ও' এগুলি পরে সহজেই হওয়ার জন্য যথেষ্ট কাছাকাছি। ;-)
The111

2
আইএমএইচও হ'ল একটি মূর্খ স্পেসিফিকেশন, যেহেতু এটি সংকলককে "মুখ্য" ফাংশনটি একটি বিশেষ উপায়ে "অন্তর্ভুক্ত" রিটার্ন 0 "যোগ করে একটি বিশেষ উপায়ে পরিচালনা করতে বাধ্য করে। সুতরাং "মুখ্য" নামের একটি ফাংশন কিছুটা ভিন্ন উপায়ে আচরণ করে। সংকলন-সময় চেকগুলি ("কোনও একই সাথে কোনও প্রত্যাবর্তনের মান নয়") কী হবে?
জিউসেপ্প গেরিনি

উত্তর:


141

সেই নিয়মটি সি স্ট্যান্ডার্ডের 1999 সংস্করণে যুক্ত হয়েছিল। C90 এ, প্রত্যাবর্তিত স্থিতি নির্ধারিত।

আপনি এটি -std=c99সিসিতে পাস করে সক্ষম করতে পারেন ।

পার্শ্ব নোট হিসাবে, আকর্ষণীয়ভাবে 9 টি ফিরে এসেছে কারণ এটির printf9 টি অক্ষর লিখেছিল return


40
অথবা return 0;বন্ধ হওয়ার আগে আপনি যুক্ত করতে পারেন }। এটি নিরীহ এবং আপনার প্রোগ্রামটি পুরানো সংকলকগুলিতে পোর্টেবল করে তোলে।
কিথ থম্পসন

2
@ মিঃ 32: ভাল পর্যবেক্ষণ, প্রিন্টফ () স্ট্রিংয়ের দৈর্ঘ্যটি ফেরত দেয় তাই এটি 9 হয় যা মূলত "রিটার্ন" হয় (-std = c99 ব্যবহার না করে)।
হিচাম

1
@ কনিকুটার: ফাংশনগুলি সাধারণত স্ট্যাকের উপরে ছোট মানগুলি ফেরায় না - কারণ এটিতে কেবল একটি চাল এবং ফিরে আসার চেয়ে একটি পপ, একটি ধাক্কা এবং একটি লাফ অন্তর্ভুক্ত থাকে - সুতরাং এটি প্রায় অবশ্যই একটি রেজিস্টার, eaxবিশেষত x86 এ।
জন পুরী

8
হ্যাঁ, x86 এপিআই সাধারণত eaxরেজিস্টারের মাধ্যমে পূর্ণসংখ্যার মান হিসাবে ফেরত দেয় । আরও তথ্যের জন্য en.wikedia.org/wiki/X86_calling_conventions#cdecl দেখুন ।
সিলভাইন Defresne

2
বেশ কয়েকবার আমি "ইন্ট foo (শূন্য) {বার (); Several" এর মতো কোড দেখেছি যেখানে "রিটার্ন বার ()" এর উদ্দেশ্য ছিল। এই কোডটি বেশিরভাগ প্রসেসরের উপর সুস্পষ্ট বাগ সত্ত্বেও ঠিক কাজ করে।
উগোরেন

15

এটি রিটার্ন মান প্রদান করে printfযার মধ্যে সত্যিকার অর্থে মুদ্রিত অক্ষরের সংখ্যা।


প্রোগ্রামটি কার্যকর করার সময় কনসোলে কী মুদ্রিত হয় সে সম্পর্কে প্রশ্নটি আলোচনা করে না, এটি প্রোগ্রামটির রিটার্ন মান সম্পর্কে আলোচনা করে: (আপনি এটি স্কেল কমান্ডের সাহায্যে লিনাক্সে পেতে পারেন: ইকো $? এবং উইন্ডোতে: ইকো% ত্রুটিযুক্ত% )
হিচাম

1
@ ইহারভেস্ট যদিও আমি উইন্ডোজটিতে চেক করতে জানি না %errorlevel%, তবে mainলিনাক্সের প্রস্থান কোড এবং রিটার্ন মানের মধ্যে কোনও পার্থক্য রয়েছে ?
গ্রীষ্ম_মুড়_আর_আর

1
@ ইহারভেস্ট: কনসোলে কী প্রিন্ট করা হয়েছে সে সম্পর্কে উত্তরটি আলোচনা করে না। এটি এর ক্ষেত্রে 9 এর রিটার্ন মান সম্পর্কে আলোচনা করে printfযা mainনির্দিষ্ট জিসিসি সংস্করণ ব্যবহার করার পরে কোনওভাবে প্রস্থান কোড হিসাবে "প্রচারিত" হয়ে যায় ।
এএইচ

দুঃখিত। আমার ভুল. তুমি ঠিক. আমি এই উত্তরটি খুব দ্রুত পড়েছি: /
হিচাম

1
নোট যে এই হয় না নিশ্চিত। C89 / C90 সালে অবস্থা এই ক্ষেত্রে ফিরিয়ে দেওয়া হয় অনির্দিষ্ট ; এটা কিছু হতে পারে। এটি 9 ফেরত আসবে কারণ সংকলক অন্য কিছু ফেরত দেওয়ার কোনও প্রচেষ্টা করেনি। অন্যান্য সংকলক সম্ভবত আলাদাভাবে আচরণ করবে।
কিথ থমসন

6

কোনও ক্রিয়াকলাপ থেকে ফেরতের মান সাধারণত সিপিইউর ইক্স রেজিস্টারে সংরক্ষণ করা হয়, সুতরাং বিবৃতিটি "রিটার্ন 4;" সাধারণত সংকলন করতে হবে

mov eax, 4;
ret;

এবং এক্স রিটার্ন (আপনার সংকলকের উপর নির্ভর করে) এরকম কিছু হবে:

mov eax, [ebp + 4];
ret;

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

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

যদি আপনি এসেম্বলারের একটি প্রাথমিক ধারণা পেয়ে থাকেন তবে এটি বিভিন্ন সংযোজকগুলির বিযুক্তির তুলনা করার পক্ষে মূল্যবান। আপনি দেখতে পাবেন যে কিছু সংকলক নিরাপদরক্ষী হিসাবে EX রেজিস্টার সাফ করছে।


11
সংকলক এটি করতে পারে । এটি অপরিবর্তিত পরিবর্তে এটি আপনাকে একটি মুদ্রক কার্টিজ দিয়ে মাথায় গুলি করতে পছন্দ করতে পারে।
অরবিটে

@ লাইটনেসেসিনঅরবਿਟ অপরিজ্ঞাতটি অনির্দেশ্য হিসাবে একই নয়, অর্থাত্ "যদি সংকলকটি এক্স করে থাকে তবে এটি মানক হবে" এটি যৌক্তিকভাবে "সংকলকটি এক্স করতে পারে" অনুসরণ করে না
ওভেন

@ ওউইন: এটি নির্ধারণ করে মানক উত্তরণটি উদ্ধৃত করুন।
হালকা ঘোড়দৌড়

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

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