কেন সর্বাধিক নেতিবাচক আন্ত মানটি দ্ব্যর্থক ফাংশন ওভারলোড সম্পর্কে ত্রুটি সৃষ্টি করে?


91

আমি সি ++ এ ফাংশন ওভারলোডিং সম্পর্কে শিখছি এবং এটি জুড়ে এসেছি:

void display(int a)
{
    cout << "int" << endl;
}

void display(unsigned a)
{
    cout << "unsigned" << endl;
}

int main()
{
    int i = -2147483648;
    cout << i << endl; //will display -2147483648
    display(-2147483648);
}

আমি যা বুঝতে পেরেছি সেগুলি থেকে, intপরিসরে প্রদত্ত যে কোনও মান (আমার ক্ষেত্রে int4 বাইট) কল করবে display(int)এবং এই ব্যাপ্তির বাইরের কোনও মান অস্পষ্ট হবে (যেহেতু সংকলকটি কল করতে পারে যে কোন ফাংশনটি ঠিক করতে পারে না)। intএটির সর্বনিম্ন মান বাদে মানগুলির সম্পূর্ণ পরিসরের জন্য বৈধ, -2147483648যেখানে ত্রুটির সাথে সংকলন ব্যর্থ হয়

অতিরিক্ত লোড কল display(long int)অস্পষ্ট

কিন্তু একটি একই মান গ্রহণ intএবং মান দেয় মুদ্রণ 2147483648। আমি আক্ষরিকভাবে এই আচরণের সাথে বিভ্রান্ত।

সর্বাধিক নেতিবাচক সংখ্যাটি পাস করার পরে কেন এই আচরণটি পর্যবেক্ষণ করা হয়? (আচরণ একই একটি হল shortসঙ্গে ব্যবহার করা হয় -32768- কোনো ক্ষেত্রে, আসলে যেখানে ঋণাত্মক সংখ্যা এবং ধনাত্মক সংখ্যা একই বাইনারি উপস্থাপনা আছে)

সংকলক ব্যবহৃত: জি ++ (জিসিসি) 4.8.5


4
ইন্টের ন্যূনতম মান হ'ল "একটি সংকলক ত্রুটি নিক্ষেপ করা"। কি ত্রুটি? আপনার এটিকে প্রশ্নে অন্তর্ভুক্ত করা উচিত
জাস্টিন 19

11
আমি দেখছি call of overloaded ‘display(long int)’ is ambiguous
ক্র্যাশমাস্ট্র

6
সম্পর্কিত নয়, তবে আপনার সংকলকটি আপডেট করা উচিত। ইতিমধ্যে জিসিসি 7.1 রয়েছে।
হলিব্ল্যাকগ্যাট

4
এখানে আমার অনুমান: typeof(-2147483648) != int। আক্ষরিক এটি 2147483648যা একটির পক্ষে খুব বড় int, তাই এটি একটি long, এবং এটি
জাস্টিন

4
মজার বিষয় হল, g ++ (কমপক্ষে .4.৪ এবং .1.১, কমপক্ষে) অভিযোগ করবেন না যে int j{-2147483648};এটি সংকীর্ণ রূপান্তর। প্রায় নিজের মধ্যে একটি প্রশ্ন মূল্যবান। এটি সম্ভবত (উদাহরণস্বরূপ) long longকনটেক্সটর মানগুলিকে যেমন আদিতে 2147483647LLসংকীর্ণ হওয়ার অনুমতি দেওয়ার সাথে সম্পর্কিত ।
টবি স্পিড

উত্তর:


145

এটি একটি খুব সূক্ষ্ম ত্রুটি। আপনি যা দেখছেন তা সি ++ তে নেতিবাচক পূর্ণসংখ্যার আক্ষরিক না থাকার একটি ফলাফল। যদি আমরা [লেকস. আইকন] এর দিকে লক্ষ্য করি তবে আমরা পাই যে একটি পূর্ণসংখ্যা-আক্ষরিক ,

পূর্ণসংখ্যা-আক্ষরিক
        দশমিক-আক্ষরিক পূর্ণসংখ্যা-প্রত্যয় অপ্ট
        [...]

দশমিক-আক্ষরিক হতে পারে ,

দশমিক-আক্ষরিক:
        ননজারো-অঙ্কের
        দশমিক-আক্ষরিক ' অপ্ট ডিজিট

যেখানে অঙ্ক হয় [0-9]এবং অশূন্য অঙ্ক হয় [1-9]ও প্রত্যয় সমাবস্থা এক হতে পারে u, U, l, L, ll, অথবা LL। এখানে কোথাও -এর দশমিক আক্ষরিক অংশ হিসাবে অন্তর্ভুক্ত নেই ।

.12.13.2 এ, আমাদেরও রয়েছে:

একটি পূর্ণসংখ্যা আক্ষরিক হ'ল ডিজিটের ক্রম যা এর কোনও সময়কালে বা ঘনিষ্ঠ অংশ থাকে না ,চ্ছিক পৃথক পৃথক একক উদ্ধৃতি যা এর মান নির্ধারণের সময় অগ্রাহ্য করা হয়। একটি পূর্ণসংখ্যার আক্ষরিকের একটি উপসর্গ থাকতে পারে যা এর ভিত্তি এবং তার প্রকারটি নির্দিষ্ট করে এমন একটি প্রত্যয় যুক্ত করে। অঙ্কের ক্রমটির বর্ণনামূলকভাবে প্রথম সংখ্যাটি সবচেয়ে উল্লেখযোগ্য। একটি দশমিক পূর্ণসংখ্যা আক্ষরিক (বেস দশ) 0 থেকে একটি অঙ্ক অপরের সাথে শুরু হয় এবং দশমিক সংখ্যা একটি ক্রম নিয়ে গঠিত।

(জোর আমার)

যার মানে -মধ্যে -2147483648ইউনারী হয় operator -। এর অর্থ -2147483648আসলে হিসাবে বিবেচিত হয় -1 * (2147483648)। যেহেতু 2147483648আপনার জন্য intএটি অনেকগুলি এটির জন্য প্রচারিত হয় long intএবং অস্পষ্টতাটি মিলছে না comes

আপনি যদি কোনও পোর্টেবল পদ্ধতিতে কোনও ধরণের ন্যূনতম বা সর্বাধিক মান পেতে চান তবে:

std::numeric_limits<type>::min();  // or max()

4
-2147483647 - 1নেতিবাচক আক্ষরিক অভিব্যক্তি হিসাবে সতর্কতা ছাড়াই কাজ করবে
সিউর

4
অথবা INT_MINকমপক্ষে ভার্বোজ বিকল্পের জন্য। কম জেনেরিক, যদিও।
এমসাল্টারস

@ নাথান অলিভার, আপনি কি দয়া করে আমাকে এই বিষয়টি ব্যাখ্যা করতে পারেন display(2147483649);? এই ক্ষেত্রে এটি স্বাক্ষরবিহীন ইন ফানকে কল করতে পারে না কেন? এবং কেন এটি 2147483649স্বাক্ষরযুক্ত স্বাক্ষরের পরিবর্তে দীর্ঘতর ইন্টার হিসাবে আর্গটিকে আচরণ করে ?
অসীম লুপ

4
ডেসিমাল @infiniteloop পূর্ণসংখ্যা লিটারেল থেকে যান intথেকে long intথেকে long long int। দশমিক আক্ষরিক জন্য আপনি কখনই স্বাক্ষরবিহীন প্রকার পাবেন না যদি না আপনি u/ Uপ্রত্যয়টি ব্যবহার করেন ।
নাথান অলিভার

4
এই উদাহরণে হ্যাঁ। কল করতে display(unsigned a)আপনি হয় দরকার display(1234u);বা display(static_cast<unsigned>(1234));বাunsigned foo = 1234; display(foo);
NathanOliver

36

এক্সপ্রেশনটি -2147483648আসলে -ধ্রুবকটিতে অপারেটর প্রয়োগ করে 2147483648। আপনার প্ল্যাটফর্মে, intসঞ্চয় করতে পারে না 2147483648, এটি অবশ্যই আরও বড় ধরণের দ্বারা প্রতিনিধিত্ব করতে হবে। অতএব, অভিব্যক্তিটি বৃহত্তর স্বাক্ষরিত ধরণের -2147483648হতে অনুমিত হয় না ,।signed intsigned long int

আপনি যেহেতু সংকলকটির জন্য কোনও ওভারলোড সরবরাহ করেন longনা তাই উভয়ই সমানভাবে বৈধ যে দুটি ওভারলোডের মধ্যে চয়ন করতে বাধ্য করা হয়। আপনার সংকলকটি অস্পষ্ট ওভারলোড সম্পর্কে একটি সংকলক ত্রুটি জারি করা উচিত।


4

অন্যের জবাব প্রসারিত করা


ওপি কেন বিভ্রান্ত তা স্পষ্ট করার জন্য, প্রথমে : নীচে signed intবাইনারি উপস্থাপনা বিবেচনা করুন 2147483647

বৃহত্তম সাইন ইন




এর পরে, এই নম্বরে আপনাকে একটি যোগ : অন্য দান signed intএর -2147483648(যা ওপি ব্যবহার শুভেচ্ছা) ক্ষুদ্রতম স্বাক্ষরিত



পরিশেষে: আমরা দেখতে পাচ্ছি যে কেন ও এর পরিবর্তে -2147483648একটি সংকলন করার সময় ওপি বিভ্রান্ত হয় , কারণ এটি স্পষ্টভাবে 32 বিটের মধ্যে ফিট করে।long intsigned int

কিন্তু, হিসাবে বর্তমান উত্তর উল্লেখ, ইউনারী অপারেটর ( -) প্রয়োগ করা হয় পর সমাধানে 2147483648যা হয় long intএবং 32 বিট মধ্যে মাপসই করা হবে না।

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