কেন এটি (নাল ||! ট্রাইপার্স) শর্তসাপেক্ষে "নিযুক্ত স্বাক্ষরিত স্থানীয় ভেরিয়েবলের ব্যবহার" ফলাফল দেয়?


98

নিম্নলিখিত কোডের অ-স্বাক্ষরিত স্থানীয় ভেরিয়েবল "সংখ্যাঅফগ্রুপ" ব্যবহারের ফলাফল :

int numberOfGroups;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
    numberOfGroups = 10;
}

তবে, এই কোডটি ঠিকঠাকভাবে কাজ করে (যদিও, রিশার্পার বলছেন এটি = 10অপ্রয়োজনীয়):

int numberOfGroups = 10;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
    numberOfGroups = 10;
}

আমি কি কিছু মিস করছি, বা সংকলকটি আমার পছন্দ করছে না ||?

আমি এগুলি সমস্যার dynamicকারণে সংকুচিত করেছি ( optionsআমার উপরের কোডটিতে একটি গতিশীল পরিবর্তনশীল ছিল)। প্রশ্নটি এখনও রয়ে গেছে, আমি কেন এটি করতে পারি না ?

এই কোডটি সংকলন করে না :

internal class Program
{
    #region Static Methods

    private static void Main(string[] args)
    {
        dynamic myString = args[0];

        int myInt;
        if(myString == null || !int.TryParse(myString, out myInt))
        {
            myInt = 10;
        }

        Console.WriteLine(myInt);
    }

    #endregion
}

তবে এই কোডটি করে :

internal class Program
{
    #region Static Methods

    private static void Main(string[] args)
    {
        var myString = args[0]; // var would be string

        int myInt;
        if(myString == null || !int.TryParse(myString, out myInt))
        {
            myInt = 10;
        }

        Console.WriteLine(myInt);
    }

    #endregion
}

আমি বুঝতে পারি নি dynamicযে এটির একটি কারণ হবে।



4
এখানে প্রদত্ত কোড বর্ণিত আচরণ প্রদর্শন করে না; এটা ঠিক কাজ করে। দয়া করে কোড পোস্ট করুন যা আপনি যে আচরণটি বর্ণনা করছেন তা বাস্তবে প্রদর্শিত হয় যা আমরা নিজেরাই সংকলন করতে পারি। আমাদের পুরো ফাইলটি দিন।
এরিক লিপার্ট

8
আহ, এখন আমাদের কিছু আকর্ষণীয় আছে!
এরিক লিপার্ট

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

4
প্রথম নজরে এটি বাগের মতো দেখতে নিশ্চিত।
এরিক লিপার্ট

উত্তর:


73

আমি নিশ্চিত যে এটি একটি সংকলক বাগ। ভাল লাগছে!

সম্পাদনা করুন: এটি কোনও বাগ নয়, যেমন কোয়ার্টারমিস্টার দেখায়; গতিশীল একটি অদ্ভুত trueঅপারেটর প্রয়োগ করতে পারে যার কারণ হতে পারেy কখনও কখনও আরম্ভ না করার ।

এখানে একটি ন্যূনতম তিরস্কার:

class Program
{
    static bool M(out int x) 
    { 
        x = 123; 
        return true; 
    }
    static int N(dynamic d)
    {
        int y;
        if(d || M(out y))
            y = 10;
        return y; 
    }
}

কেন এটি অবৈধ হওয়া উচিত তার কোনও কারণ আমি দেখছি না; আপনি যদি বুলের সাথে ডায়নামিক প্রতিস্থাপন করেন তবে এটি ঠিক আছে।

আমি আসলে সি # টিমের সাথে আগামীকাল বৈঠক করছি; আমি তাদের কাছে এটি উল্লেখ করব। ত্রুটির জন্য ক্ষমা চাইছি!


6
আমি পাগল হয়ে যাচ্ছি না তা জানতে পেরে আমি খুব আনন্দিত :) আমি তখন থেকে কেবলমাত্র ট্রিপপার্সের উপর নির্ভর করার জন্য আমার কোড আপডেট করেছি, তাই আমি এখনই সেট করছি। আপনার অন্তর্দৃষ্টি জন্য ধন্যবাদ!
ব্র্যান্ডন মার্টিনেজ

4
@ নমনসিম: ধরুন রানটাইম বিশ্লেষণ ব্যর্থ হয়েছে: তবে স্থানীয় পড়ার আগে একটি ব্যতিক্রম ছুঁড়ে দেওয়া হবে। ধরা যাক রানটাইম বিশ্লেষণ সফল হয়: তবে রানটাইমের সময় হয় ডি সত্য এবং y সেট করা হয়, বা ডি মিথ্যা এবং এম সেট করে y। যেভাবেই হোক, y সেট করা আছে। রানটাইম না হওয়া পর্যন্ত বিশ্লেষণ স্থগিত হয়ে গেছে এ বিষয়টি যে কোনও কিছুই পরিবর্তন করে না।
এরিক লিপার্ট

4
কারও কৌতূহলের ক্ষেত্রে: আমি কেবল পরীক্ষা করেছি এবং মনো সংকলকটি এটি সঠিকভাবে পেয়েছে। imgur.com/g47oquT
ড্যান টাও

17
আমি মনে করি সংকলক আচরণটি আসলে সঠিক, যেহেতু dএকটি ওভারলোডেড trueঅপারেটরের সাথে মানটি কোনও ধরণের হতে পারে । আমি একটি উদাহরণ দিয়ে উত্তর পোস্ট করেছি যেখানে কোন শাখা নেওয়া হয় না।
কোয়ার্টারমিস্টার

4
@ কোয়ার্টারমিস্টার যে ক্ষেত্রে মনো
সংকলকটি

52

গতিশীল এক্সপ্রেশনটির মান যদি ওভারলোডেড trueঅপারেটর সহ কোনও ধরণের হয় তবে ভেরিয়েবলটি আনসাইন করা সম্ভব হয় ।

||অপারেটর ডাকা হবে trueডানদিকে মূল্যায়ন করা হবে কিনা তা সিদ্ধান্ত নিতে অপারেটর, এবং তারপর ifবিবৃতি ডাকা হবে trueতার শরীর মূল্যায়ন করা হবে কিনা তা সিদ্ধান্ত নিতে অপারেটর। একটি সাধারণ ক্ষেত্রে bool, এগুলি সর্বদা একই ফলাফলটি ফিরে আসবে এবং ঠিক একইভাবে একটি মূল্যায়ন করা হবে, তবে একজন ব্যবহারকারী-সংজ্ঞায়িত অপারেটরের পক্ষে এরকম কোনও গ্যারান্টি নেই!

এরিক লিপার্টের তিরস্কার বন্ধ করে দেওয়ার জন্য, এখানে একটি সংক্ষিপ্ত এবং সম্পূর্ণ প্রোগ্রাম রয়েছে যা এমন একটি ঘটনা দেখায় যেখানে দুটি পাথ কার্যকর করা হয় না এবং ভেরিয়েবলটির প্রাথমিক মান থাকে:

using System;

class Program
{
    static bool M(out int x)
    {
        x = 123;
        return true;
    }

    static int N(dynamic d)
    {
        int y = 3;
        if (d || M(out y))
            y = 10;
        return y;
    }

    static void Main(string[] args)
    {
        var result = N(new EvilBool());
        // Prints 3!
        Console.WriteLine(result);
    }
}

class EvilBool
{
    private bool value;

    public static bool operator true(EvilBool b)
    {
        // Return true the first time this is called
        // and false the second time
        b.value = !b.value;
        return b.value;
    }

    public static bool operator false(EvilBool b)
    {
        throw new NotImplementedException();
    }
}

8
এখানে দুর্দান্ত কাজ। আমি এটি সি # পরীক্ষা এবং ডিজাইন দলগুলিতে পাশ করেছি; আগামীকাল আমি যখন তাদের দেখব তখন তাদের বিষয়ে কোনও মন্তব্য আছে কিনা তা আমি দেখতে পাব।
এরিক লিপার্ট

4
এটি আমার কাছে খুব অদ্ভুত। কেন dদুবার মূল্যায়ন করা উচিত ? (আমি বিরোধপূর্ণ করছি না এটি স্পষ্টভাবে হয় , আপনি দেখিয়েছেন।) আমি হবে মূল্যায়ন ফলাফলের আশা করা true(প্রথম অপারেটর আবাহন থেকে দ্বারা কারণ ||) এর "বরাবর পাস" করা ifবিবৃতি। এটি অবশ্যই ঘটবে যদি আপনি সেখানে কোনও ফাংশন কল রাখেন, উদাহরণস্বরূপ।
ড্যান টাও

4
@ ড্যান্টাও: dআপনার প্রত্যাশা অনুসারে অভিব্যক্তিটি একবারে মূল্যায়ন করা হয়। এটি trueঅপারেটর যা একবার, একবার ||এবং একবার দুবার আহ্বান করা হচ্ছে if
কোয়ার্টারমিস্টার

4
@ ড্যানটাও: যদি আমরা তাদের আলাদা বিবৃতিতে রাখি তবে এটি আরও স্পষ্ট হতে পারে var cond = d || M(out y); if (cond) { ... }। প্রথমে আমরা dকোনও EvilBoolঅবজেক্ট রেফারেন্স পেতে মূল্যায়ন করি । মূল্যায়ন করতে ||, আমরা প্রথমে EvilBool.trueসেই রেফারেন্সের সাথে অনুরোধ করি। এটি সত্য প্রত্যাবর্তন করে, তাই আমরা সংক্ষিপ্ত-সার্কিট করি এবং অনুরোধ করি না M, এবং তারপরে রেফারেন্স নির্ধারণ করি cond। তারপরে, আমরা ifবিবৃতিতে এগিয়ে যাই । ifবিবৃতি কল করে তার অবস্থা মূল্যায়ন করে EvilBool.true
কোয়ার্টারমিস্টার

4
এখন এটি সত্যিই দুর্দান্ত। আমি সত্য বা মিথ্যা অপারেটর আছে কোন ধারণা ছিল না।
IllidanS4

7

এমএসডিএন (জোর দেওয়া খনি) থেকে:

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

টাইপ ডায়নামিক বেশিরভাগ পরিস্থিতিতে টাইপ অবজেক্টের মতো আচরণ করে। যাইহোক, গতিশীল টাইপের এক্সপ্রেশন থাকা অপারেশনগুলি সমাধান করা হয় না বা সংকলক দ্বারা পরীক্ষা করা টাইপ হয়।

যেহেতু সংকলক গতিশীল টাইপের এক্সপ্রেশন ধারণ করে এমন কোনও ক্রিয়াকলাপ চেক বা সমাধান করে না, এটি নিশ্চিত করতে পারে না যে চলকটি ব্যবহারের মাধ্যমে নির্ধারিত হবে TryParse()


প্রথম শর্তটি পূরণ হলে, numberGroupsনির্ধারিত হয় ( if trueব্লকে), না থাকলে, দ্বিতীয় শর্তটি অ্যাসাইনমেন্টের (মাধ্যমে out) গ্যারান্টি দেয় ।
লেপি

4
এটি একটি আকর্ষণীয় চিন্তাভাবনা, তবে কোডটি myString == null(কেবলমাত্র নির্ভর করে TryParse) ছাড়াই সূক্ষ্ম সংকলন করে ।
ব্র্যান্ডন মার্টিনেজ

4
@ লেপ্পি কথাটি হ'ল যেহেতু প্রথম শর্তটিতে (প্রকৃতপক্ষে পুরো প্রকাশটি) ifএকটি dynamicপরিবর্তনশীল জড়িত তাই এটি সঙ্কলনের সময় সমাধান করা হয় না (সংকলক অতএব এই ধারনাগুলি তৈরি করতে পারে না)।
নমনসিম

@ নোমিনসিম: আমি আপনার বক্তব্যটি দেখছি :) +1 সংকলক (সি # নিয়ম ভঙ্গ) থেকে উত্সর্গ হতে পারে তবে অন্যান্য পরামর্শগুলি একটি বাগ বোঝায়। এরিকের স্নিপেট দেখায় এটি একটি বলি নয়, একটি বাগ।
লেপি

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