কেন একটি সংকলক দ্বারা ডেড কোড সনাক্তকরণ পুরোপুরি সমাধান করা যায় না?


192

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


91
একটি লুপ, এটা পরে করা কোড করুন, তারপরে আবেদন en.wikipedia.org/wiki/Halting_problem
zapl

48
if (isPrime(1234234234332232323423)){callSomething();}এই কোড কি কখনও কিছু কল করবে না? আরও অনেক উদাহরণ রয়েছে, যেখানে কোনও ফাংশন যাকে বলা হয় তা স্থির করে প্রোগ্রামে এটি অন্তর্ভুক্ত করার চেয়ে অনেক বেশি ব্যয়বহুল।
idclev 463035818

33
public static void main(String[] args) {int counterexample = findCollatzConjectureCounterexample(); System.out.println(counterexample);}<- প্রিন্টলন কল ডেড কোড? মানুষও এটিকে সমাধান করতে পারে না!
ব্যবহারকারী 253751

15
@ tobi303 একটি দুর্দান্ত উদাহরণ নয়, প্রাথমিক সংখ্যাগুলি ফ্যাক্ট করা সত্যিই সহজ ... কেবল তাদের তুলনামূলক দক্ষতার সাথে ফ্যাক্টর না করে। থামার সমস্যাটি এনপিতে নয়, এটি অলসযোগ্য।
en_Kight

57
@ আলফাজেরো এবং এন_কাইট - আপনি উভয়ই ভুল। isPrime একটি দুর্দান্ত উদাহরণ। আপনি একটি অনুমান করেছিলেন যে ফাংশনটি একটি প্রাইম নম্বর অনুসন্ধান করছে। হতে পারে যে নম্বরটি একটি ক্রমিক সংখ্যা ছিল এবং এটি একটি ডাটাবেস অনুসন্ধান করে ব্যবহারকারী কি আমাজন প্রাইম সদস্য কিনা তা দেখার জন্য? এটির দুর্দান্ত উদাহরণ হবার কারণ হ'ল শর্তটি স্থিতিশীল রয়েছে কি না তা জানার একমাত্র উপায়টি আসলে ইসপ্রাইম ফাংশনটি সম্পাদন করা। সুতরাং এখন যে সংকলক এছাড়াও একটি দোভাষী হতে হবে। কিন্তু এটি এখনও সেই মামলাগুলিকে সমাধান করতে পারে না যেখানে ডেটা অস্থির is
ডঙ্ক

উত্তর:


275

ডেড কোড সমস্যা হ্যালটিং সমস্যার সাথে সম্পর্কিত ।

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

এটি কীভাবে মৃত কোডের সাথে সম্পর্কিত?

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

হাল্টিং সমস্যার জন্য আপনি কীভাবে ডেড কোডের জন্য একটি অ্যালগোরিদম স্থানান্তর করবেন?

সরল: আপনি প্রোগ্রামটি শেষ হওয়ার পরে কোডটির একটি লাইন যুক্ত করুন যা আপনি থামানোর জন্য পরীক্ষা করতে চান। যদি আপনার ডেড-কোড সনাক্তকারী এই লাইনটি মারা গেছে তা সনাক্ত করে তবে আপনি জানেন যে প্রোগ্রামটি থামবে না। যদি এটি না হয়, তবে আপনি জানেন যে আপনার প্রোগ্রামটি থেমে আছে (শেষ লাইনে পৌঁছে এবং তারপরে আপনার কোডের যোগ করা লাইনে)।


সংকলকগণ সাধারণত এমন জিনিস পরীক্ষা করে যা সংকলন সময়ে মৃত হওয়ার জন্য প্রমাণিত হতে পারে। উদাহরণস্বরূপ, ব্লকগুলি যেগুলি শর্তগুলির উপর নির্ভরশীল যা সংকলন সময়ে মিথ্যা হতে পারে তা নির্ধারণ করা যেতে পারে। বা এর পরে কোনও বিবৃতি return(একই ক্ষেত্রের মধ্যে)।

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


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

50
@ ভ্যালিয়ালি -৪-বিট প্রসেসর 2 ^ 64 বাইট সম্বোধন করতে পারে। সমস্ত 256 ^ (2 ^ 64) রাজ্যে অনুসন্ধান করতে মজা করুন!
ড্যানিয়েল ওয়াগনার

82
@ ড্যানিয়েল ওয়াগনার এই সমস্যা হওয়া উচিত নয়। সন্ধানের 256^(2^64)রাজ্যগুলি O(1)তাই মৃত কোড সনাক্তকরণ বহুবারের সময়ে করা যায়।
aebabis

13
@ লেলিয়েল, এটি কটূক্তি ছিল।
পল ড্রাগন

44
@ ভার্যালিটি: বেশিরভাগ আধুনিক কম্পিউটারে ডিস্ক, ইনপুট ডিভাইস, নেটওয়ার্ক যোগাযোগ ইত্যাদি রয়েছে Any এটি কোনও ট্র্যাকটেবল সমস্যা নয়।
নাট

77

ঠিক আছে, আসুন থামানোর সমস্যার অনিশ্চয়তার শাস্ত্রীয় প্রমাণ গ্রহণ করা যাক এবং থামানো-সনাক্তকারীকে একটি ডেড-কোড সনাক্তকারী হিসাবে পরিবর্তন করতে হবে!

সি # প্রোগ্রাম

using System;
using YourVendor.Compiler;

class Program
{
    static void Main(string[] args)
    {
        string quine_text = @"using System;
using YourVendor.Compiler;

class Program
{{
    static void Main(string[] args)
    {{
        string quine_text = @{0}{1}{0};
        quine_text = string.Format(quine_text, (char)34, quine_text);

        if (YourVendor.Compiler.HasDeadCode(quine_text))
        {{
            System.Console.WriteLine({0}Dead code!{0});
        }}
    }}
}}";
        quine_text = string.Format(quine_text, (char)34, quine_text);

        if (YourVendor.Compiler.HasDeadCode(quine_text))
        {
            System.Console.WriteLine("Dead code!");
        }
    }
}

তাহলে YourVendor.Compiler.HasDeadCode(quine_text)আয় false, তারপর লাইন System.Console.WriteLn("Dead code!");কখনো মৃত্যুদন্ড কার্যকর করা হবে না, যাতে এই প্রোগ্রামটি আসলে কী মৃত কোড আছে, এবং আবিষ্কারক ভুল ছিল।

তবে যদি এটি ফিরে আসে true, তবে লাইনটি System.Console.WriteLn("Dead code!");কার্যকর করা হবে এবং যেহেতু প্রোগ্রামটিতে কোনও কোড নেই, কোনও ডেড কোড নেই, তাই আবারও আবিষ্কারকটি ভুল ছিল।

সুতরাং সেখানে আপনার এটি রয়েছে, একটি ডেড-কোড ডিটেক্টর যা কেবল "সেখানে ডেড কোড আছে" বা "কোনও ডেড কোড নেই" ফিরিয়ে দেয় কখনও কখনও ভুল উত্তর দিতে হবে।


1
যদি আমি আপনার যুক্তিটি সঠিকভাবে বুঝতে পারি, তবে প্রযুক্তিগতভাবে অন্য একটি বিকল্পটি হ'ল এটি একটি মৃত কোড সনাক্তকারী, যা বেশিরভাগ ক্ষেত্রে লেখা সম্ভব নয়, তবে সাধারণ ক্ষেত্রে একটি ডেড কোড ডিটেক্টর লেখা সম্ভব। :-)

1
গডেলিয়ান উত্তরের জন্য বৃদ্ধি।
জারেড স্মিথ

@ আবলিগ উঘ, এটি শব্দের একটি খারাপ পছন্দ ছিল। আমি আসলে নিজেই ডেড-কোড সনাক্তকারীর উত্স কোডটি খাওয়াচ্ছি না, তবে প্রোগ্রামটির উত্স কোড যা এটি ব্যবহার করে। অবশ্যই, এক পর্যায়ে সম্ভবত এটির নিজস্ব কোডটি দেখতে হবে, তবে এটি তার ব্যবসা।
জোকার_ভিডি

65

যদি থামার সমস্যাটি খুব অস্পষ্ট হয় তবে এটিকে এভাবে ভাবুন।

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

 for (BigInt n = 4; ; n+=2) {
     if (!isGoldbachsConjectureTrueFor(n)) {
         print("Conjecture is false for at least one value of n\n");
         exit(0);
     }
 }

বাস্তবায়নের isGoldbachsConjectureTrueFor()পাঠকের জন্য অনুশীলন হিসাবে রেখে দেওয়া হয়েছে তবে এই উদ্দেশ্যে কম সমস্ত প্রাইমগুলির চেয়ে কম সাধারণ পুনরাবৃত্তি হতে পারেn

এখন, যৌক্তিকভাবে উপরেরটি অবশ্যই এর সমতুল্য হতে হবে:

 for (; ;) {
 }

(অর্থাত্ একটি অসীম লুপ) বা

print("Conjecture is false for at least one value of n\n");

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

 String target = "f3c5ac5a63d50099f3b5147cabbbd81e89211513a92e3dcd2565d8c7d302ba9c";
 for (BigInt n = 0; n < 2**2048; n++) {
     String s = n.toString();
     if (sha256(s).equals(target)) {
         print("Found SHA value\n");
         exit(0);
     }
 }
 print("Not found SHA value\n");

আমরা জানি যে প্রোগ্রামটি "খুঁজে পাওয়া SHA মান" বা "পাওয়া যায়নি SHA মান" (বোনাস পয়েন্টগুলি যদি আপনি আমাকে কোনটি সত্য তা বলতে পারেন) মুদ্রণ করবে। তবে, একটি সংকলক যুক্তিসঙ্গতভাবে অপ্টিমাইজ করতে সক্ষম হবেন যা 2 ^ 2048 পুনরাবৃত্তির ক্রম গ্রহণ করবে। এটি প্রকৃতপক্ষে একটি দুর্দান্ত অপটিমাইজেশন হবে কারণ আমি পূর্বাভাস দিয়েছি যে উপরের প্রোগ্রামটি (বা হতে পারে) মহাবিশ্বের তাপের মৃত্যু পর্যন্ত অপটিমাইজেশন ছাড়াই কিছু ছাপানোর চেয়ে চলবে।


4
এটি +1
জিন

2
জিনিসগুলি কী বিশেষ আকর্ষণীয় করে তোলে তা হল লুপগুলি সমাপ্ত হবে এমনটা ধরে নিলে সি স্ট্যান্ডার্ড কী অনুমতি দেয় বা অনুমতি দেয় না সে সম্পর্কে অস্পষ্টতা। কোনও সংকলককে ধীর গণনা পিছিয়ে দেওয়ার মঞ্জুরি দেওয়ার মূল্য রয়েছে যার ফলাফলগুলি তাদের পজিশনের প্রকৃত প্রয়োজন হওয়া পয়েন্ট অবধি ব্যবহার করা যেতে পারে বা নাও পারে; এই অপটিমাইজেশন কিছু ক্ষেত্রে কার্যকর হতে পারে এমনকি সংকলক হিসাবটি শেষ করে প্রমাণ করতে না পারলেও।
supercat

2
2 ^ 2048 পুনরাবৃত্তি? এমনকি গভীর চিন্তা ছেড়ে দিতে হবে।
পিটার মর্টেনসেন

এটি খুব উচ্চ সম্ভাবনার সাথে "ফাইন্ড এসএএএ মান" মুদ্রণ করবে, এমনকি যদি লক্ষ্যটি he৪ হেক্স ডিজিটের এলোমেলো স্ট্রিং ছিল। যদি না sha256বাইট অ্যারে এবং বাইট অ্যারেগুলি আপনার ভাষায় স্ট্রিংয়ের সমান তুলনা না করে।
ব্যবহারকারী 253751

4
Implementation of isGoldbachsConjectureTrueFor() is left as an exercise for the readerএটি আমাকে ছোটাছুটি করেছে।
23:41

34

আমি জানি না সি ++ বা জাভাতে কোনও Evalটাইপ ফাংশন রয়েছে কিনা তবে অনেকগুলি ভাষা আপনাকে নাম অনুসারে কল পদ্ধতি করতে দেয় । নিম্নলিখিত (স্বীকৃত) ভিবিএ উদাহরণ বিবেচনা করুন।

Dim methodName As String

If foo Then
    methodName = "Bar"
Else
    methodName = "Qux"
End If

Application.Run(methodName)

যে পদ্ধতির নামটি বলা হবে তা রানটাইম পর্যন্ত জানা অসম্ভব। সুতরাং, সংজ্ঞা অনুসারে, সংকলক সম্পূর্ণরূপে নিশ্চিতভাবে জানতে পারে না যে কোনও নির্দিষ্ট পদ্ধতি কখনই ডাকা হয় না।

আসলে, নাম দ্বারা একটি পদ্ধতি কল করার উদাহরণ দেওয়া, শাখা যুক্তি এমনকি প্রয়োজনীয় নয়। সোজা বলছি

Application.Run("Bar")

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


2
জাভাতে (বা সি #), এটি প্রতিবিম্বের সাহায্যে করা যেতে পারে। সি ++ আপনি সম্ভবত এটি করতে ম্যাক্রোগুলি ব্যবহার করে কিছু ঘৃণ্যতা টানতে পারেন। সুন্দর হবে না, তবে সি ++ খুব কমই হয়।
ড্যারেল হফম্যান

6
@ ড্যারেলহফম্যান - সংকলককে কোড দেওয়ার আগে ম্যাক্রোগুলি প্রসারিত করা হয়েছে, সুতরাং ম্যাক্রোগুলি অবশ্যই আপনি এটি কীভাবে করবেন তা নয়। ফাংশনগুলির পয়েন্টারগুলি হ'ল আপনি এটি কীভাবে করবেন। আমি বছরগুলিতে সি ++ ব্যবহার করি নি তাই যদি আমার সঠিক টাইপের নামগুলি ভুল হয় তবে আমাকে ক্ষমা করুন তবে আপনি কেবল পয়েন্টার ফাংশনে স্ট্রিংয়ের মানচিত্র সংরক্ষণ করতে পারেন can তারপরে এমন কিছু আছে যা ব্যবহারকারীর ইনপুট থেকে স্ট্রিং গ্রহণ করে, মানচিত্রে সেই স্ট্রিংটি দেখায় এবং তারপরে চিহ্নিত ফাংশনটি কার্যকর করে।
আর্টঅফ ওয়ারফেয়ার

1
@ আর্টঅফ ওয়ারফেয়ার আমরা কীভাবে এটি সম্পন্ন হতে পারি সে সম্পর্কে কথা বলছি না। স্পষ্টতই, কোডটির শব্দার্থবিজ্ঞান বিশ্লেষণ এই পরিস্থিতিটি সন্ধান করার জন্য করা যেতে পারে, পয়েন্টটি ছিল যে সংকলকটি তা করে না । এটি হতে পারে, সম্ভবত, সম্ভবত, তবে তা হয় না।
রাবারডাক

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

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

12

উন্নত সংকলকগণ দ্বারা শর্তহীন ডেড কোড সনাক্ত এবং সরিয়ে ফেলা যায়।

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

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


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

6
@ তায়েমির তাহলে এটি নিঃশর্ত মৃত বলে জানা যাবে না, এখন কি হবে?
জাব

1
@ টেেমির আপনি "শর্তহীন" শব্দটি ভুল বুঝেছেন বলে মনে হচ্ছে। কোড ডেডনেস যদি কোনও ফাংশনের ফলাফলের উপর নির্ভর করে তবে এটি শর্তযুক্ত ডেড কোড। "শর্ত" ফাংশনের ফলাফল। "নিঃশর্ত" হওয়ার জন্য এটি কোনও ফলাফলের উপর নির্ভর করতে হবে না
কায়োটিক

12

একটি সহজ উদাহরণ:

int readValueFromPort(const unsigned int portNum);

int x = readValueFromPort(0x100); // just an example, nothing meaningful
if (x < 2)
{
    std::cout << "Hey! X < 2" << std::endl;
}
else
{
    std::cout << "X is too big!" << std::endl;
}

এখন ধরে নিন যে 0x100 বন্দরটি কেবল 0 বা 1 ফেরত দেওয়ার জন্য ডিজাইন করা হয়েছে সেই ক্ষেত্রে সংকলকটি এটি অনুমান করতে পারে না যে else ব্লকটি কখনই কার্যকর হবে না।

তবে এই প্রাথমিক উদাহরণে:

bool boolVal = /*anything boolean*/;

if (boolVal)
{
  // Do A
}
else if (!boolVal)
{
  // Do B
}
else
{
  // Do C
}

এখানে সংকলকটি elseব্লকটি নির্ধারণ করতে পারে একটি ডেড কোড। সুতরাং সংকলক কেবল মৃত কোড সম্পর্কে সতর্ক করতে পারে যদি এতে ডেড কোডটি বের করার পর্যাপ্ত ডেটা থাকে এবং প্রদত্ত ব্লকটি একটি ডেড কোড কিনা তা বের করার জন্য এটি কীভাবে সেই ডেটা প্রয়োগ করতে হবে তাও জানা উচিত।

সম্পাদনা

কখনও কখনও সংকলনের সময় ডেটা উপলব্ধ হয় না:

// File a.cpp
bool boolMethod();

bool boolVal = boolMethod();

if (boolVal)
{
  // Do A
}
else
{
  // Do B
}

//............
// File b.cpp
bool boolMethod()
{
    return true;
}

A.cpp সংকলনের সময় সংকলক জানতে পারে না যে boolMethodসর্বদা ফিরে আসে true


1
সংকলক জানে না এমন কঠোরভাবে সত্য বলে আমি মনে করি যে লিঙ্কারটি জানতে পারে কিনা তাও জিজ্ঞাসা করা প্রশ্নটির অনুপ্রেরণায় ।
ক্যাসি কুবল

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

এই উত্তরটি আমার কাছে বিভ্রান্তিকর বলে মনে হচ্ছে; আপনি দুটি উদাহরণ দিচ্ছেন যেখানে এটি সম্ভব নয় কারণ সমস্ত তথ্য উপলব্ধ নয়, তবে আপনি কি বলবেন না যে তথ্য উপস্থিত থাকলেও এটি অসম্ভব?
আন্তন গোলভ 18

অ্যান্টনগোলোভ এটি সর্বদা সত্য নয়। অনেক ক্ষেত্রে যখন তথ্য থাকে, সংকলকরা ডেড কোডটি সনাক্ত করতে পারে এবং এটি অপ্টিমাইজ করতে পারে।
অ্যালেক্স লোপ

@ কেবলমাত্র একটি ব্লকের ব্লকটি প্রয়োগ করুন। এটি অন্য কিছু হতে পারে। :)
অ্যালেক্স লোপ

4

সংকলকটিতে সর্বদা কিছু প্রাসঙ্গিক তথ্যের অভাব থাকবে। উদাহরণস্বরূপ আপনি জানেন যে, দ্বিগুণ মান কখনই 2 টি ছাড় দেয় না, কারণ এটি গাণিতিক ফাংশনের একটি বৈশিষ্ট্য, আপনি একটি লাইব্রেরি থেকে ব্যবহার করেন। সংকলকটি এমনকি লাইব্রেরিতে কোডটি দেখতে পায় না এবং এটি কখনই সমস্ত গাণিতিক ক্রিয়াকলাপের সমস্ত বৈশিষ্ট্য জানতে পারে না এবং সেগুলি প্রয়োগের সমস্ত ক্লান্ত এবং জটিল উপায় সনাক্ত করতে পারে না।


4

সংকলক অগত্যা পুরো প্রোগ্রামটি দেখতে পাবে না। আমার কাছে এমন একটি প্রোগ্রাম থাকতে পারে যা একটি ভাগ করা লাইব্রেরি কল করে, যা আমার প্রোগ্রামের কোনও ফাংশনে ফিরে আসে যা সরাসরি ডাকা হয় না।

সুতরাং একটি ফাংশন যা এর সাথে সংকলিত লাইব্রেরির সাথে সম্মতি সহকারে মরে গেছে যদি সেই লাইব্রেরি রানটাইমের সময় পরিবর্তন করা হয় become


3

যদি কোনও সংকলক সঠিকভাবে সমস্ত মৃত কোডটি অপসারণ করতে পারে, তবে তাকে দোভাষী বলা হবে ।

এই সাধারণ দৃশ্যটি বিবেচনা করুন:

if (my_func()) {
  am_i_dead();
}

my_func() যথেচ্ছ কোড থাকতে পারে এবং সংকলকটি সত্য বা মিথ্যা প্রত্যাবর্তন করে কিনা তা নির্ধারণের জন্য, কোডটি চালাতে হবে বা কোড চালনার সমতুল্য এমন কিছু করতে হবে।

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


আপনি যদি একটি ফাংশন হিসাবে কম্পাইলার বিবেচনা করে c(), যেখানে c(source)=compiled code, এবং চলমান পরিবেশ r(), যেখানে r(compiled code)=program output, যেকোনো সোর্স কোড আপনি মান গনা আছে তাদের জন্য আউটপুট নির্ধারণ করতে r(c(source code))। যদি গণনা c()করতে r(c())কোনও ইনপুটটির মান সম্পর্কে জ্ঞান প্রয়োজন হয় তবে আলাদা করার দরকার নেই r()এবং c(): আপনি কেবল সেগুলি i()থেকে কোনও ফাংশন পেতে পারেন ।c()i(source)=program output


2

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

। নেট / জাভা / জাভাস্ক্রিপ্ট এবং অন্যান্য রানটাইম চালিত পরিবেশে প্রতিবিম্বের মাধ্যমে লোড হওয়া প্রকারগুলি থামানোর কিছুই নেই। এটি নির্ভরতা ইনজেকশন ফ্রেমওয়ার্কগুলির সাথে জনপ্রিয় এবং ডিসরিয়ালাইজেশন বা গতিশীল মডিউল লোডের মুখোমুখি হওয়া যুক্তিটি আরও শক্ত।

সংকলক জানতে পারে না এই ধরণের ধরণের লোড হবে কিনা। তাদের নাম পারেরানটাইমের সময় বাহ্যিক কনফিগারেশন ফাইল থেকে আসতে ।

আপনি গাছের কাঁপুনের আশেপাশে অনুসন্ধান করতে পছন্দ করতে পারেন যা এমন সরঞ্জামগুলির জন্য একটি সাধারণ শব্দ যা কোডের অব্যবহৃত সাবগ্রাফগুলিকে নিরাপদে সরিয়ে দেওয়ার চেষ্টা করে।


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

2

একটি ফাংশন নিন

void DoSomeAction(int actnumber) 
{
    switch(actnumber) 
    {
        case 1: Action1(); break;
        case 2: Action2(); break;
        case 3: Action3(); break;
    }
}

আপনি কি প্রমাণ actnumberকরতে 2পারেন যে Action2()কখনই এমন হয় না যে কখনও বলা হয় না ...?


7
আপনি যদি ফাংশনটির কলকারীদের বিশ্লেষণ করতে পারেন তবে আপনি হ্যাঁ করতে সক্ষম হতে পারেন।

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

এটি একটি খারাপ উত্তর। অন্য উত্তরগুলি প্রমাণ করে যে এটি জানা সম্ভব নয় actnumber==2। এই উত্তরটি কেবল কোনও জটিলতার কথা উল্লেখ না করেই দাবি করে যে এটি শক্ত hard
এমসাল্টার

1

থামার সমস্যা সম্পর্কে আমি একমত নই। বাস্তবে এটি কখনই পৌঁছাবে না যদিও আমি এই জাতীয় কোডটিকে মৃত বলব না।

পরিবর্তে, বিবেচনা করা যাক:

for (int N = 3;;N++)
  for (int A = 2; A < int.MaxValue; A++)
    for (int B = 2; B < int.MaxValue; B++)
    {
      int Square = Math.Pow(A, N) + Math.Pow(B, N);
      float Test = Math.Sqrt(Square);
      if (Test == Math.Trunc(Test))
        FermatWasWrong();
    }

private void FermatWasWrong()
{
  Press.Announce("Fermat was wrong!");
  Nobel.Claim();
}

(প্রকার এবং ওভারফ্লো ত্রুটি উপেক্ষা করুন) ডেড কোড?


2
ফারম্যাট এর শেষ উপপাদ্য 1994 সালে প্রমাণিত হয়েছিল So আমি সন্দেহ করি যে আপনার প্রয়োগটি ফার্মাটওয়াসওয়ারং চালিত হবে, কারণ আপনি ভাসমান সংক্ষিপ্ততার সীমাবদ্ধতায় আঘাত করতে পারেন।
তাইমির

@ তােমির আহা! এই প্রোগ্রামটি ফার্মের শেষ উপপাদ্যকে সঠিকভাবে পরীক্ষা করে না; এটি পরীক্ষা করে যা করে তার জন্য একটি
পাল্টে নমুনা

@ মিম্বিস হ্যাঁ, আমি মিস করেছি যে এটি কোনও সমস্যা হয়ে উঠতে ভাসতে ভাসা সম্পর্কে নির্ভুলতার আগেই উপচে পড়বে।
Taemyr

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

-1

এই উদাহরণটি দেখুন:

public boolean isEven(int i){

    if(i % 2 == 0)
        return true;
    if(i % 2 == 1)
        return false;
    return false;
}

সংকলকটি জানতে পারে না যে কোনও ইন্ট কেবল সম বা বিজোড় হতে পারে। সুতরাং সংকলক অবশ্যই আপনার কোড শব্দার্থবিজ্ঞান বুঝতে সক্ষম হতে হবে। এটি কীভাবে বাস্তবায়ন করা উচিত? সংকলকটি নিশ্চিত করতে পারে না যে সর্বনিম্ন রিটার্ন কখনই কার্যকর হবে না। সুতরাং সংকলক মৃত কোড সনাক্ত করতে পারে না।


1
উম্মু, সত্যি? আমি যদি এটি সি # + র্যাশার্পারে লিখি তবে আমি বেশ কয়েকটি ইঙ্গিত পাই। তাদের অনুসরণ করে অবশেষে আমাকে কোড দেয় return i%2==0;
টমাস ওয়েলার

10
আপনার উদাহরণটি বিশ্বাসযোগ্য হতে খুব সহজ। নির্দিষ্ট ক্ষেত্রে i % 2 == 0এবং i % 2 != 0এমনকি কোনও ধ্রুবক (যা এখনও করা সহজ) এর পূর্ণসংখ্যার মান সম্পর্কে যুক্তির প্রয়োজন হয় না, এটি কেবল সাধারণ সুব্রপ্রেসন নির্মূল এবং সাধারণ নীতি (ক্যানোনিকালাইজেশন এমনকি এমনকি) প্রয়োজন যা if (cond) foo; if (!cond) bar;সহজ করা যায় if (cond) foo; else bar;। অবশ্যই "বোঝার শব্দার্থবিজ্ঞান" একটি খুব কঠিন সমস্যা, তবে এই পোস্টটি না তা দেখায় না বা দেখায় না যে এই কঠিন সমস্যাটি সমাধান করা ডেড কোড সনাক্তকরণের জন্য প্রয়োজনীয়।

5
আপনার উদাহরণে, একটি অপ্টিমাইজ করা সংকলক সাধারণ সুব্রপ এক্সারশনকে স্পট করবে i % 2এবং এটিকে একটি অস্থায়ী ভেরিয়েবলের মধ্যে টেনে আনবে । এটি তখন স্বীকৃতি দেবে যে দুটি ifবিবৃতি পারস্পরিক একচেটিয়া এবং এ হিসাবে লেখা যেতে পারে if(a==0)...else...এবং তারপরে স্পষ্ট করে যে সমস্ত কার্যকর কার্যকর দুটি পথ প্রথম দুটি returnবিবৃতি দিয়ে যায় এবং তৃতীয় returnবিবৃতিটি ডেড কোড। (একটি ভাল অনুকূলকরণ সংকলক আরও বেশি আক্রমণাত্মক: জিসিসি আমার পরীক্ষার কোডটিকে এক জোড়া বিট-ম্যানিপুলেশন অপারেশনে রূপান্তরিত করেছে)।
চিহ্নিত করুন

1
এই উদাহরণটি আমার পক্ষে ভাল। এটি কেসটির প্রতিনিধিত্ব করে যখন সংকলক কিছু বাস্তব ঘটনা সম্পর্কে জানবে না। একই জন্য যায় if (availableMemory()<0) then {dead code}
ছোট সান্তি

1
@LittleSanti: বাস্তবিক, জিসিসি যে নির্ণয় করতে পারবে সবকিছু আপনি লিখেছেন সেখানে মৃত কোড! এটি শুধু {dead code}অংশ নয়। একটি অনিবার্য স্বাক্ষরযুক্ত পূর্ণসংখ্যার ওভারফ্লো রয়েছে তা প্রমাণ করে জিসিসি এটি আবিষ্কার করে। এক্সিকিউশন গ্রাফের সেই চাপের সমস্ত কোড তাই মৃত কোড। জিসিসি শর্তসাপেক্ষ শাখাও সরিয়ে দিতে পারে যা সেই চাপকে বাড়ে।
এমএসএলটাররা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.