আমি কেন গণ্য মানগুলিতে 0.0 নিয়োগ করতে পারি, তবে 1.0 নয়


90

কৌতূহলের বাইরে: আমি কেন একটি পরিবর্তকের পরিবর্তে ০.০ নির্ধারণ করতে পারি, তবে এটি ০.০ নয়? নিম্নলিখিত কোডটি দেখুন:

public enum Foo
{
    Bar,
    Baz
}

class Program
{
    static void Main()
    {
        Foo value1 = 0.0;
        Foo value2 = 1.0;   // This line does not compile
        Foo value3 = 4.2;   // This line does not compile
    }
}

আমি ভেবেছিলাম যে সংখ্যাগত প্রকার এবং গণনা মানগুলির মধ্যে রূপান্তরগুলি কেবলমাত্র জাতির মাধ্যমে অনুমোদিত? যে আমি ফু লিখতে পারে value2 = (Foo) 1.0;যাতে 2 লাইন 2 Mainসংকলন করতে পারেন। 0.0সি # তে মানটির ব্যতিক্রম কেন ?


17
আমার কাছে এটি আশ্চর্যের বিষয়, আপনি কাস্টম এনুমগুলিতে ডাবল আক্ষরিক 0.0 নির্ধারণ করতে পারেন । আপনি কাস্টম এনুমকে আক্ষরিক অর্পণ করতে পারবেন না এমন নয়1.0 ।
— ইলিয়া ইভানভ

4
আমার সন্দেহ হয় যে সংকলকটি এর 0পরিবর্তে এটির আচরণ করছে । আমার একবার একই ধরণের প্রশ্ন হয়েছিল এবং রাউলিং এখানে দুর্দান্ত উত্তর পোস্ট করেছেন ।
— বন্ধুত্বপূর্ণ

4
আইডিওন এটি সংকলন করে না।
— জনি এমপ্প 20'14

উত্তর:


98

এটি একটি বাগ যা আপনি 0.0 ব্যবহার করতে পারেন। সংকলক স্পষ্টত সমস্ত ধ্রুবক এক্সপ্রেশনকে শূন্যের মান হিসাবে কেবল 0 হিসাবে আচরণ করে।

এখন, কম্পাইলারের পক্ষে সি # 5 স্পেসিফিকেশনের 6.1.3 ধারা অনুযায়ী আপনার এনামে 0 টির ধ্রুবক অভিব্যক্তি থেকে অন্তর্নিহিত রূপান্তরকে মঞ্জুরি দেওয়ার জন্য এটি সঠিকint :

একটি অন্তর্নিহিত গণনা রূপান্তরটি দশমিক-পূর্ণসংখ্যা-আক্ষরিক 0 কে যে কোনও এনাম-টাইপ এবং এমন কোনও nlalaable-type এর রূপান্তর করতে অনুমতি দেয় যার অন্তর্নিহিত প্রকারটি enum-type হয়। পরবর্তী ক্ষেত্রে রূপান্তরটি অন্তর্নিহিত এনাম-টাইপে রূপান্তর করে ফলাফল মোড়ানো (.14.1.10) দ্বারা মূল্যায়ন করা হয়।

আমি এর আগে সি # টিমের সাথে কথা বলেছি: তারা 0.0 (এবং প্রকৃতপক্ষে 0.0m এবং 0.0f) থেকে এনাম মানগুলিতে দুর্ঘটনাজনিত রূপান্তর সরিয়ে ফেলতে পছন্দ করবে , তবে দুর্ভাগ্যক্রমে আমি সংগ্রহ করেছি এটি খুব বেশি কোড ভেঙেছে - যদিও এটি প্রথম স্থানে অনুমতি দেওয়া উচিত ছিল না।

মনো mcsসংকলক এই সমস্ত ভাসমান পয়েন্ট রূপান্তরগুলি নিষিদ্ধ করে, যদিও এটি এর অনুমতি দেয়:

const int Zero = 0;
...

SomeEnum x = Zero;

Zeroএটি একটি ধ্রুবক অভিব্যক্তি হলেও দশমিক-পূর্ণসংখ্যা-আক্ষরিক নয় despite

ভবিষ্যতে সি # স্পেসিফিকেশন পরিবর্তনটি দেখে 0 টির মান (অর্থাত নকল করা mcs) সহ কোনও পূর্ণসংখ্যার ধ্রুবক অভিব্যক্তিটি দেখে অবাক হবেন না , তবে আমি ভাসমান পয়েন্ট রূপান্তরগুলি সরকারীভাবে সঠিক হওয়ার আশা করবো না । (সি # এর ভবিষ্যত ভবিষ্যদ্বাণী করার আগে আমি ভুল হয়ে গিয়েছিলাম অবশ্যই ...)


4
অনুমান অনুসারে, এটি কেবল আক্ষরিক 0 হিসাবে বোঝানো হয়েছে। সুতরাং এটি প্রত্যাখ্যান করা উচিত 1-1- এর intমান সহ একটি ধ্রুবক প্রকাশ 0। আপনি যেমন পর্যবেক্ষণ করেন, সংকলকটি এখানে বর্ণনার সাথে মিলিয়ে যায় না।
— দামিয়েন_এই অবিশ্বাসী

4
it broke too much code- এই জাতীয় কোড লিখার কোনও কারণ কল্পনা করা সত্যিই শক্ত।
— ইলিয়া ইভানভ

4
@ ওবিসিডিয়ানফোনিক্স: আপনি কী বলতে চাইছেন তা আমি নিশ্চিত নই। এটা তোলে ঠিক সমতুল্য আছে: SomeEnum x = (SomeEnum) 0;। এটি একটি নামক শূন্য মান আছে কিনা তা কেস।
— জন স্কিটি

4
@ ওবিসিডিয়ানফোনিক্স: ঠিক আছে না, কারণ মানটি Test.Foo1, 0 নয় ... আবারও, এটি আপনি যেমন লিখেছিলেন ঠিক তেমনটাই Test v1 = (Test) 0;- এবং আচরণটি এমন কোনও মানকে ধরে রাখে যা এনামের নামকরণকৃত মান নয়।
— জন স্কিটি 20'14

4
@ জনস্কিট কি এটি রোজলিনে স্থির হতে চলেছে?
— সর্বাধিক

98

জনের উত্তর সঠিক is আমি এটিতে নিম্নলিখিত বিষয়গুলি যুক্ত করব।

  • আমি এই নির্বোধ এবং বিব্রতকর বাগটি ঘটিয়েছি। অনেক ক্ষমা চেয়েছি।

  • সংকলকটিতে "অভিব্যক্তি শূন্য" প্রিডিকেটের শব্দার্থবিজ্ঞানের ভুল বোঝাবুঝির কারণে বাগটি হয়েছিল; আমি বিশ্বাস করি যে এটি কেবল পূর্ণসংখ্যা শূন্য সমতার জন্য পরীক্ষা করছে, যখন আসলে এটি "এই ধরণের ডিফল্ট মান এটি?" এর ধারে আরও পরীক্ষা করে দেখছিল? আসলে, বাগের পূর্ববর্তী সংস্করণে কোনও এনামকে কোনও ধরণের ডিফল্ট মান নির্ধারণ করা সম্ভব হয়েছিল! এটি এখন কেবল সংখ্যার ডিফল্ট মান। (পাঠ: আপনার সাহায্যকারী সাবধানতার সাথে পূর্বাভাসের নাম দিন))

  • আমি যে আচরণটি ভুল করেছিলাম তা বাস্তবায়নের চেষ্টা করছিলাম তা আসলে কিছুটা ভিন্ন বাগের জন্য কাজ। আপনি এখানে পুরো ভয়ঙ্কর গল্পটি পড়তে পারেন: https://docs.microsoft.com/en-us/archive/blogs/ericlippert/the-root-of-all-evil-part-one এবং https://docs.microsoft .কম / এন-ইউএস / আর্কাইভ / ব্লগস / এরিক্লিপার্ট / দ্য-রুট-অফ-অল-অল-পার্ট টু (পাঠ: পুরাতনগুলি ঠিক করার সময় নতুন খারাপ খারাপগুলি প্রবর্তন করা খুব সহজ))

  • সি # টিম এই বগী আচরণটি সংশোধন করার পরিবর্তে এটি সংযুক্ত করার সিদ্ধান্ত নিয়েছে কারণ বাধ্যতামূলক কোনও সুবিধার জন্য বিদ্যমান কোড ভাঙার ঝুঁকি খুব বেশি ছিল না। (পাঠ: প্রথম বার এটি পান!)

  • কোড আমি Roslyn লিখেছে এই আচরণ সংরক্ষণ পদ্ধতি খুঁজে পাওয়া যেতে পারে IsConstantNumericZeroএ https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs - রোজলিনের আচরণটি কী তা সম্পর্কে আরও বিশদের জন্য এটি দেখুন। রূপান্তর ডিরেক্টরিতে আমি প্রায় সমস্ত কোড লিখেছি; মন্তব্যে স্পেসিফিকেশন থেকে সি # কীভাবে বিভক্ত হয় সে সম্পর্কে অনেক আকর্ষণীয় তথ্য আছে বলে আমি আপনাকে এটি সমস্ত পড়তে উত্সাহিত করি। তাদের সন্ধান সহজ করার জন্য আমি প্রত্যেককে স্পেক ভোলেশন দিয়ে সজ্জিত করেছি।

আরও একটি আগ্রহের বিষয়: সি # কোনও এনাম মান তার নির্গমতা নির্বিশেষে এনাম ইনিশিয়ালাইজারে ব্যবহার করার অনুমতি দেয় :

enum E { A = 1 }
enum F { B = E.A }  // ???

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


10
এটি সত্যিই দুর্দান্ত, অবশেষে আপনার লেখা কোডটি দেখতে পাচ্ছি। এটি দুর্দান্ত যে রোজলিন উত্স কোডটি ওপেন সোর্স। এখন আমি সম্পূর্ণরূপে বুঝতে পারি যে পরিবর্তনের ইতিহাস সরবরাহ না করার জন্য বৈধ কারণগুলি (প্রযুক্তিগত / আইনী) বিদ্যমান রয়েছে তবে কোডটি কীভাবে বিকশিত হয়েছে তা দেখার ইতিহাস পরিবর্তনটি দেখতে দুর্দান্ত হত।
— সমাধান

The C# team decided to enshrine this buggy behaviour rather than fixing it because the risk of breaking existing code for no compelling benefit was too high.আমি মনে করি না এমন অনেক লোক থাকবে যারা এই আচরণের উপর নির্ভর করে এবং এটি এইরকম একটি বিজোড়তা যা কেবল ঠিক করা ভাল better তবে এটি সত্যিকার অর্থে খুব বেশি ক্ষতি করে না (প্রকল্পটি বাস্তবায়নের প্রকল্প ব্যতীত)।
— এডিয়াকাপি

4
@ এডিয়াকাপি: প্রকৃতপক্ষে, ক্ষতিগ্রস্থদের সংখ্যা কম হওয়া উচিত; এটা শূন্য নয়। সি # টিম ব্রেকিং পরিবর্তনগুলি খুব গুরুত্ব সহকারে নেয়। আপনার পক্ষে বলা সহজ যে এটি ঠিক করা আরও ভাল; আপনার ক্ষুধার্ত পরিবর্তনের ফলে কোনও দিনই তাদের সিস্টেমের সংহতকরণে বিলম্বিত হওয়ার ফলে কোনও লাভ হয় না বলে অভিযোগ করার জন্য আপনার ভাইস প্রেসিডেন্টকে কল করা বিরক্ত গ্রাহকদের সাথে আপনার কোন সমস্যা নেই।
— এরিক লিপার্ট

4
এটা খুব খারাপ হচ্ছে. এই জাতীয় সমস্ত ব্রেকিং পরিবর্তনগুলি (আদর্শভাবে) মাইক্রোসফ্টের ফ্রেমওয়ার্ক মাইগ্রেশন গাইডে তালিকাভুক্ত করা হবে। এই তালিকাটি যত দীর্ঘ হবে তত বেশি দ্বিধাগ্রস্ত ব্যবহারকারীরা তাদের অ্যাপ্লিকেশনটি স্থানান্তর করতে পারবেন। সুতরাং, এমনকি একটি সামান্য বিরতি পরিবর্তন কারণ: 1. বিরতিতে অল্প সংখ্যক অ্যাপ্লিকেশন। ২. অল্প সংখ্যক ব্যবহারকারী আপগ্রেড করতে অস্বীকার করবেন (যদিও সমস্যাটি তাদের প্রভাবিত করে না)। ৩. ব্রেকিং পরিবর্তনগুলি যদি তাদের প্রভাবিত করে তবে মূল্যায়ন করার সংস্থানগুলিতে অল্প সংখ্যক ব্যবহারকারী waste ৪. # 1, # 2, এবং # 3 থেকে ব্যবহারকারীরা সকলের কাছে অভিযোগ করার জন্য।
— ব্রায়ান

@ এরিকলিপার্ট যদি "অনুমানটি কিছুটা অস্পষ্ট" থাকে তবে তা অনুমান করে আপডেট করা কি বুদ্ধিমান হবে না? (জেনুইন প্রশ্ন!)
— জেমস 20

10

সি # তে গণনাগুলি সংজ্ঞা সংবিধানের মান দ্বারা হয়। ধারাবাহিকতার জন্য সি # এই অ্যাসাইনমেন্টগুলির কোনওটিই গ্রহণ করবেন না, তবে 0.0নীরবে অবিচ্ছেদ্য হিসাবে বিবেচিত হবে 0। এটি সম্ভবত সি এর একটি হোল্ডওভার, যেখানে আক্ষরিকটি 0বিশেষভাবে চিকিত্সা করা হয়েছিল এবং প্রয়োজনীয় যে কোনও ধরণের - পূর্ণসংখ্যা, ভাসমান পয়েন্ট নম্বর, নাল পয়েন্টার নিতে পারে ... আপনি এটির নাম দিন।


4
প্রশ্ন কেন ? আপনি যদি যান IL- এটি স্ট্যাকের উপর পূর্ণসংখ্যার মানকে চাপ দিচ্ছেIL_0001: ldc.i4.0
— ইলিয়া ইভানভ

ইলিয়াআইভানভ আপডেট দেখুন। তবে সত্যি কথা বলতে, উত্তরটি হ'ল "কোনও ভাল কারণ নেই"।
— কনরাড রুডল্ফ

4
আমি মনে করি যে এটি those ক্ষেত্রেগুলির মধ্যে একটি যেখানে আপনি যদি সি # স্পিকারের দিকে তাকান তবে এটি আইনী নয়, তবে আপনি এমএস যে কোনও সি # সংকলকটি দেখেছেন তা এটি করে।
— দামিয়েন_এই অবিশ্বাসী

3

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

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


আমি জানি যে আমি সি # তে এইভাবে এনাম ব্যবহার করিনি - তবে আমি এই মস্তিষ্কের টিজারটি খুঁজে পেয়েছি এবং কেন 0.0 কাজ করছে তা জানতে চেয়েছিলাম, তবে 1.0 নয়। আমি জানতাম যে এটি সি # সংকলকের সাথে কিছু হওয়া উচিত কারণ আপনি দেখতে পাচ্ছেন যে আইএল কোড এর জন্য Foo v1 = 0.0;একই Foo v2 = Foo.Bar।
— feO2x
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.