আমি কীভাবে অসীম ফাঁকা লুপ তৈরি করব যা অপ্টিমাইজ হবে না?


131

সি 11 স্ট্যান্ডার্ডটি বোঝায় যে ধ্রুবক নিয়ন্ত্রণকারী এক্সপ্রেশন সহ পুনরাবৃত্তি বিবৃতিগুলি অপ্টিমাইজ করা উচিত নয়। আমি এই উত্তরটি থেকে আমার পরামর্শ নিচ্ছি , যা খসড়া মানক থেকে section.৮.৫ বিশেষভাবে উদ্ধৃত করেছে:

একটি পুনরাবৃত্তির বিবৃতি যার নিয়ন্ত্রণকরণের অভিব্যক্তিটি একটি ধ্রুবক প্রকাশ নয় ... এটি বাস্তবায়নের মাধ্যমে অবসান হতে পারে বলে ধরে নেওয়া যেতে পারে।

এই উত্তরে এটি উল্লেখ করেছে যে একটি লুপটি while(1) ;অপ্টিমাইজেশনের বিষয় হওয়া উচিত নয়।

সুতরাং ... কেন ঝাঁকুনি / এলএলভিএম নীচের লুপটি (এর সাথে সংকলিত cc -O2 -std=c11 test.c -o test) অপ্টিমাইজ করবে ?

#include <stdio.h>

static void die() {
    while(1)
        ;
}

int main() {
    printf("begin\n");
    die();
    printf("unreachable\n");
}

আমার মেশিনে, এটি মুদ্রণ করে begin, তারপরে একটি অবৈধ নির্দেশের উপর ক্র্যাশ হয় (একটি ud2ফাঁদ পরে রাখা হয় die())। গডবোল্টে , আমরা দেখতে পাচ্ছি যে কল করার পরে কিছুই উত্পন্ন হয় না puts

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

#include <stdio.h>

static void die() {
    while(1)
        ;
}

int main() {
    printf("begin\n");
    volatile int x = 1;
    if(x)
        die();
    printf("unreachable\n");
}

... ঝনঝন প্রিন্টগুলি beginঅনুসরণ করে unreachableযেন অসীম লুপের অস্তিত্ব নেই।

আপনি কীভাবে অপ্টিমাইজেশান চালু করে কোনও সঠিক, নো-মেমরি অ্যাক্সেস অসীম লুপ আউটপুট দিতে ঝাঁকুনি পাবেন?


3
মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
Bhargav রাও

2
কোনও বহনযোগ্য সমাধান নেই যা কোনও পার্শ্ব প্রতিক্রিয়া জড়িত না। আপনি যদি কোনও স্মৃতি অ্যাক্সেস না চান, আপনার সেরা আশাটি অস্থায়ী স্বাক্ষরযুক্ত চর নিবন্ধিত হবে; তবে রেজিস্টার সি ++ 17 এ চলে যায়।
স্কট এম

25
হতে পারে এটি প্রশ্নের আওতায় নেই, তবে কেন আপনি এটি করতে চান তা জানতে আগ্রহী। আপনার আসল কাজটি সম্পাদনের জন্য অবশ্যই অন্য কোনও উপায় রয়েছে। নাকি এ কি প্রকৃতির একাডেমিক?
ক্রাঙ্কার

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

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

উত্তর:


77

সি 11 মানকটি এটি বলেছে, 6.8.5 / 6:

একটি পুনরাবৃত্তির বিবৃতি যার নিয়ন্ত্রণ নিয়ন্ত্রণটি একটি ধ্রুবক অভিব্যক্তি নয়, 156) যা কোনও ইনপুট / আউটপুট ক্রিয়াকলাপ সম্পাদন করে না, অস্থির বস্তুগুলিতে অ্যাক্সেস করে না এবং তার দেহে কোনও সমন্বয় বা পারমাণবিক ক্রিয়াকলাপ সম্পাদন করে না, এক্সপ্রেশন নিয়ন্ত্রণ করে, বা (এর ক্ষেত্রে ক্ষেত্রে) বিবৃতি) এর এক্সপ্রেশন -3, সমাপ্তকরণ বাস্তবায়ন দ্বারা ধরে নেওয়া যেতে পারে। 157)

দুটি পাদদেশের নোটগুলি আদর্শিক নয় তবে দরকারী তথ্য সরবরাহ করে:

156) একটি বাদ দেওয়া নিয়ন্ত্রক এক্সপ্রেশন একটি ননজারো ধ্রুবক দ্বারা প্রতিস্থাপিত হয়, যা একটি ধ্রুবক অভিব্যক্তি।

157) সমাপ্তি প্রমাণিত না হওয়া সত্ত্বেও খালি লুপগুলি অপসারণের মতো সংকলক রূপান্তরগুলিকে অনুমতি দেওয়ার উদ্দেশ্যে এটি করা হয়েছে।

আপনার ক্ষেত্রে, while(1)একটি টলটলে ধ্রুবক অভিব্যক্তি, তাই এটি হতে পারে না বাস্তবায়ন দ্বারা অনুমান করা বিনষ্ট। এই ধরনের বাস্তবায়ন আশাহীনভাবে ভেঙে যাবে, যেহেতু "সর্বদা" লুপগুলি একটি সাধারণ প্রোগ্রামিং নির্মাণ const

লুফের পরে "অ্যাক্সেসযোগ্য কোড" এর কি হবে তবে আমি যতদূর জানি, ভালভাবে সংজ্ঞায়িত হয়নি। তবে ঝাঁকুনি প্রকৃতপক্ষে খুব অদ্ভুত আচরণ করে। জিসিসি (x86) এর সাথে মেশিন কোডের তুলনা করা:

জিসিসি 9.2 -O3 -std=c11 -pedantic-errors

.LC0:
        .string "begin"
main:
        sub     rsp, 8
        mov     edi, OFFSET FLAT:.LC0
        call    puts
.L2:
        jmp     .L2

ঝনঝন 9.0.0 -O3 -std=c11 -pedantic-errors

main:                                   # @main
        push    rax
        mov     edi, offset .Lstr
        call    puts
.Lstr:
        .asciz  "begin"

জিসিসি লুপটি জেনার করে, ঝনঝনানো কেবল দাবানলে চলে যায় এবং ত্রুটি 255 দিয়ে প্রস্থান করে।

আমি ঝাঁকুনির এইভাবে অনুপযুক্ত আচরণের দিকে ঝুঁকছি। কারণ আমি আপনার উদাহরণটি আরও এভাবে প্রসারিত করার চেষ্টা করেছি:

#include <stdio.h>
#include <setjmp.h>

static _Noreturn void die() {
    while(1)
        ;
}

int main(void) {
    jmp_buf buf;
    _Bool first = !setjmp(buf);

    printf("begin\n");
    if(first)
    {
      die();
      longjmp(buf, 1);
    }
    printf("unreachable\n");
}

আমি সি 11 যুক্ত করেছি _Noreturn আরও বরাবর সাহায্য করার প্রয়াসে । এটি পরিষ্কার হওয়া উচিত যে এই ক্রিয়াকলাপটি কেবলমাত্র সেই কীওয়ার্ড থেকেই স্তব্ধ হয়ে যাবে।

setjmpপ্রথম মৃত্যুদন্ড কার্যকর হওয়ার পরে 0 ফিরে আসবে, সুতরাং এই প্রোগ্রামটি কেবল ধাক্কা মেরে while(1)সেখানে থামানো উচিত, কেবল "প্রারম্ভিক" মুদ্রণ করা (ধরে নেওয়া \ n ফ্ল্যাশ স্টাডাউট)। এটি জিসিসির সাথে ঘটে।

যদি লুপটি সরানো হয় তবে এটি "আর্ট" 2 বার মুদ্রণ করা উচিত তারপরে "অপ্রচারযোগ্য" মুদ্রণ করা উচিত। ঝাঁকুনিতে তবে ( গডবোল্ট) ), এটি প্রস্থান কোড 1 ফিরে আসার আগে 1 বার "শুরু" এবং তারপরে " " প্রিন্ট করে That's এটি আপনি যেভাবেই রাখুন না কেন এটি ঠিক স্পষ্ট ভুল।

আমি এখানে অপরিজ্ঞাত আচরণের দাবি করার জন্য কোনও মামলা খুঁজে পাচ্ছি না, তাই আমার মতে এটি ঝাঁকুনির মধ্যে একটি বাগ। যে কোনও হারে, এম্বেড থাকা সিস্টেমগুলির মতো প্রোগ্রামগুলির জন্য এই আচরণটি 100% অকেজো হয়ে যায়, যেখানে আপনাকে কেবল প্রোগ্রামটি ঝুলন্ত চিরন্তন লুপগুলির উপর নির্ভর করতে সক্ষম হতে হবে (একটি ওয়াচডগ ইত্যাদির জন্য অপেক্ষা করার সময়)।


15
"এটি একটি স্ফটিক স্বচ্ছ ধ্রুবক অভিব্যক্তি সম্পর্কে আমি একমত নই , সুতরাং এটি বাস্তবায়ন দ্বারা সমাপ্তিটি ধরে নেওয়া যায় না" । এটি সত্যিই নিট-পিক ল্যাঙ্গুয়েজ আইনশৃঙ্খলায় পরিণত হয়েছে, তবে যদি (এইগুলি)6.8.5/6 আকারে থাকে তবে আপনি ধরে নিতে পারেন (এটি) । এর অর্থ এই নয় যে যদি না (এইগুলি) আপনি ধরে নাও নিতে পারেন (এটি) । এটি শুধুমাত্র যখন শর্তগুলি পূরণ হয় তার জন্য একটি স্পেসিফিকেশন, যখন তারা মান না করে যেখানে আপনি মানগুলি সহ যা করতে পারেন তা করতে পারেন না। এবং যদি কোন পর্যবেক্ষণযোগ্য না থাকে ...
কাবানুস

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

2
আমি সম্মত, তবে আপনাকে উপস্থাপন করা হবে না যে সমাবেশে int z=3; int y=2; int x=1; printf("%d %d\n", x, z);কোনও উপস্থিতি নেই 2, তাই খালি অকেজো অর্থে পরে অপ্টিমাইজেশনের কারণে xবরাদ্দ দেওয়া হয়নি। সুতরাং আপনার শেষ বাক্যটি থেকে আমরা নিয়মিত নিয়মগুলি অনুসরণ করি, অনুমান করি কিছুক্ষণের জন্য থামানো হয়েছে (কারণ আমরা আরও ভালভাবে বাধা ছিল না), এবং চূড়ান্তটিতে "অ্যাক্সেসযোগ্য" প্রিন্টে রেখেছি। এখন, আমরা সেই অকেজো বিবৃতিটি অপ্টিমাইজ করি (কারণ আমরা এর চেয়ে ভাল জানি না)। yz
কাবানুস

2
@ সলটার্স আমার একটি মন্তব্য মুছে ফেলা হয়েছে, তবে ইনপুটটির জন্য ধন্যবাদ - এবং আমি সম্মত। আমার মন্তব্যটি যা বলেছিল তা হ'ল আমি মনে করি এটি বিতর্কের কেন্দ্রবিন্দু - আমাদের কী শব্দার্থবিজ্ঞানের উত্স অবধি অপরিবর্তিত থাকতে পারে তার পরিপ্রেক্ষিতে এটি while(1);একটি int y = 2;বিবৃতি হিসাবে সমান । এন 1528 থেকে আমি এই ধারণাটি ছিল যে তারা একই হতে পারে তবে যেহেতু লোকেরা আমার চেয়ে অভিজ্ঞ ব্যক্তিরা অন্যভাবে তর্ক করছেন এবং এটি একটি অফিসিয়াল বাগ হিসাবে স্পষ্টতই প্রমাণিত হয়েছে তবে স্ট্যান্ডার্ডে শব্দটি সুস্পষ্ট কিনা তা নিয়ে দার্শনিক বিতর্কের বাইরেও , আর্গুমেন্টটি মোট রেন্ডার হয়।
কাবানুস

2
"এ জাতীয় বাস্তবায়ন হতাশাজনকভাবে ভেঙে যাবে, যেহেতু 'সর্বকালের' লুপগুলি একটি সাধারণ প্রোগ্রামিং নির্মাণ।" - আমি অনুভূতিটি বুঝতে পারি কিন্তু তর্কটি ত্রুটিযুক্ত কারণ এটি সি ++ তে একইভাবে প্রয়োগ করা যেতে পারে, তবুও একটি সি ++ সংকলক যা এই লুপটিকে অপ্টিমাইজ করেছে, এটি ভাঙ্গা হবে না তবে উপযুক্ত হবে।
কনরাড রুডল্ফ

52

আপনাকে এমন একটি ভাব প্রবেশ করাতে হবে যা পার্শ্ব-প্রতিক্রিয়া সৃষ্টি করতে পারে।

সহজ সমাধান:

static void die() {
    while(1)
       __asm("");
}

গডবোল্ট লিঙ্ক


21
তবে ঝনঝনানি কেন অভিনয় করছে তা ব্যাখ্যা করে না।
লন্ডিন

4
যদিও "এটি ঝাঁকুনিতে বাগ আছে" বলাই যথেষ্ট। "বাগ" চেঁচানোর আগে আমি প্রথমে এখানে কয়েকটি জিনিস চেষ্টা করতে চাই।
লন্ডিন

3
@ লন্ডিন আমি জানি না এটি কোনও বাগ কিনা। মানক এই ক্ষেত্রে প্রযুক্তিগতভাবে নির্ভুল নয়
P__J__

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

3
@ থমাসওয়েলার: জিসিসি ডিভস এমন প্যাচ গ্রহণ করবে না যা এই লুপটিকে অপ্টিমাইজ করে; এটি নথিভুক্ত = গ্যারান্টিযুক্ত আচরণ লঙ্ঘন করবে। আমার পূর্ববর্তী মন্তব্যটি দেখুন: asm("")নিখুঁতভাবে asm volatile("");এবং সুতরাং এসএমএস বিবৃতিটি অ্যাবস্ট্রাক্ট মেশিনে যতবার চালাতে হবে তা gcc.gnu.org/onlinesocs/gcc/Basic-Asm.html । (মনে রাখবেন যে এর কোনও পার্শ্ব প্রতিক্রিয়া কোনও মেমরি বা রেজিস্টার অন্তর্ভুক্ত করার জন্য এটি নিরাপদ নয় ; আপনি "memory"যদি সি থেকে কখনও মেমরিটি অ্যাক্সেস করতে চান বা মেমরিটি পড়তে চান বা ক্লোবারের সাথে আপনার বর্ধিত এসএমের প্রয়োজন তবে কেবল স্টাফের মতোই নিরাপদ asm("mfence")বা cli।)
পিটার কর্ডেস

50

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

উদাহরণস্বরূপ, মরিচা প্রোগ্রামিং ল্যাঙ্গুয়েজ অসীম লুপগুলিকে মঞ্জুরি দেয় এবং ব্যাকএন্ড হিসাবে এলএলভিএম ব্যবহার করে এবং এতে এটি একই সমস্যা রয়েছে।

স্বল্পমেয়াদে, এটি উপস্থিত হয় যে এলএলভিএম ধরে নিতে থাকবে যে "পার্শ্ব-প্রতিক্রিয়াবিহীন সমস্ত লুপগুলি অবশ্যই শেষ করতে হবে"। যে কোনও ভাষার জন্য যা অসীম লুপগুলিকে মঞ্জুরি দেয়, এলএলভিএম আশা করে যে প্রথম llvm.sideeffectদিকের প্রান্তটি এ জাতীয় লুপগুলিতে অপকডগুলি সন্নিবেশ করবে । জাস্ট এটিই করার পরিকল্পনা করছে, সুতরাং কলং (সি কোড সংকলন করার সময়) সম্ভবত এটিও করতে হবে।


5
এক দশকেরও বেশি পুরানো বাগের গন্ধের মতো কিছুই নয় ... একাধিক প্রস্তাবিত ফিক্স এবং প্যাচ সহ ... এখনও ঠিক করা হয়নি।
ইয়ান কেম্প

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

4
এটি LLVM যুক্ত করা অর্থে "স্থির" করা হয়েছে sideeffect (2017 সালে) এবং প্রত্যাশা করে যে সামনে-প্রান্তগুলি তাদের বিবেচনার ভিত্তিতে লুপগুলিতে সন্নিবেশ করিয়ে দেয়। লুপগুলির জন্য এলএলভিএমকে কিছু ডিফল্ট বাছাই করতে হয়েছিল এবং এটি ইচ্ছাকৃতভাবে বা অন্যথায় সি ++ এর আচরণের সাথে সামঞ্জস্য করা একটি বেছে নিতে হয়েছিল। অবশ্যই, এখনও কিছু অপ্টিমাইজেশন কাজ করা বাকি আছে, যেমন sideeffectএকের পর এক বিকল্পকে একীভূত করতে। (এটি যা মরচে সামনের প্রান্তটি এটি ব্যবহার করে আটকাচ্ছে।) সুতরাং সেই ভিত্তিতে, বাগটি সামনের প্রান্তে (ঝনঝন) থাকে যা লুপগুলিতে অপশনটি সন্নিবেশ করে না।
আর্নভিওন

@ অরভায়িয়ন: ফলাফলগুলি ব্যবহার না করা বা অবধি অপারেশন স্থগিত করা যেতে পারে কি না তা বোঝানোর কোনও উপায় আছে, তবে যদি ডেটা যদি কোনও প্রোগ্রামকে অবিরাম লুপ করে তোলে, অতীতের ডেটা নির্ভরতাগুলি এগিয়ে যাওয়ার চেষ্টা করা প্রোগ্রামটিকে অকেজো থেকে আরও খারাপ করে তুলবে ? অজস্র পার্শ্ব-প্রতিক্রিয়া যুক্ত করা যা পূর্ববর্তী দরকারী অপ্টিমাইজেশানকে বাজেয়াপ্ত করতে অপ্টিমাইজারকে কর্মহীনতার চেয়ে খারাপ প্রোগ্রাম তৈরি করা থেকে বিরত রাখে দক্ষতার জন্য কোনও রেসিপি বলে মনে হয় না।
30:43

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

32

এটি একটি কলঙ্ক বাগ

... যখন অসীম লুপযুক্ত ফাংশনটি ইনলাইন করা হয়। while(1);সরাসরি প্রদর্শিত হয় যখন আচরণটি পৃথক , যা আমার খুব গন্ধযুক্ত গন্ধ।

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


শিরোনাম প্রশ্নের উত্তর দেওয়ার জন্য: আমি কীভাবে এমন একটি অসীম ফাঁকা লুপ তৈরি করব যা অপ্টিমাইজ হবে না? ? -
করা die()একটি ম্যাক্রো, না একটি ফাংশন এই বাগটি ক্ল্যাং ৩.৯ এবং এর পরে কাজ করার জন্য । (পূর্ববর্তী ঝনঝন সংস্করণগুলি হয় লুপটি রাখে বাcall অসীম লুপের সাথে ফাংশনের একটি অন-ইনলাইন সংস্করণে print;while(1);print;প্রেরণ করে )) ফাংশনটি তার কলারের সাথে ইনলাইন করে নিলে এটি নিরাপদ বলে মনে হয় ( গডবোল্ট) )) ) সাথে । -std=gnu11বনাম -std=gnu99কিছু পরিবর্তন করে না।

যদি আপনি কেবল জিএনইউ সি সম্পর্কে চিন্তা করেন তবে লুপের ভিতরে পি__জে__ এর__asm__(""); কাজও কাজ করে এবং এটি বোঝে এমন কোনও সংকলকগুলির জন্য আশেপাশের কোনও কোডের অপ্টিমাইজেশনের ক্ষতি করা উচিত নয়। জিএনইউ সি বেসিক asm স্টেটমেন্টগুলি পরোক্ষভাবেvolatile , তাই একটি দৃশ্যমান পার্শ্ব প্রতিক্রিয়া যেমন সি বিমূর্ত মেশিনে would অনেকবার হিসাবে "চালানো" আছে যা এই গন্য। (এবং হ্যাঁ, ক্ল্যাং জিসিসি ম্যানুয়াল দ্বারা নথিভুক্ত হিসাবে সি এর জিএনইউ উপভাষা প্রয়োগ করে))


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

(এটি ক্ল্যাং ++ এর জন্য মান-সম্মতিযুক্ত হবে (তবে এখনও খুব কার্যকর নয়); কোনও পার্শ্ব প্রতিক্রিয়া ছাড়াই অসীম লুপগুলি সি ++ তে ইউবি হয়, তবে সি নয় C.
হয় ( ) যখন রয়েছে; ইউবি সংকলকটি মূলত নির্গত করতে দেয় মৃত্যুদন্ড কার্যকর করার পথে কোডের জন্য যা অবশ্যই ইউবির মুখোমুখি হবে asmthe লুপের একটি বিবৃতি সি ++ এর জন্য এই ইউবিটিকে এড়িয়ে চলবে But তবে অনুশীলন হিসাবে, সি ++ হিসাবে ক্ল্যাং সংকলন ধ্রুবক-এক্সপ্রেশন অসীম খালি লুপগুলি সরিয়ে রাখবে না যখন ইনলাইনিংয়ের সময়, একইভাবে সি হিসাবে সংকলন)


ম্যানুয়ালি ইনলাইনিং while(1); পরিবর্তন করে যে কীভাবে ক্ল্যাং এটি সংকলন করে: অসমের মধ্যে অসীম লুপ উপস্থিত। আমরা কোনও নিয়ম-আইনজীবী পিওভের কাছ থেকে এটি প্রত্যাশা করব।

#include <stdio.h>
int main() {
    printf("begin\n");
    while(1);
    //infloop_nonconst(1);
    //infloop();
    printf("unreachable\n");
}

গডবোল্ট সংকলক এক্সপ্লোরারটিতে , -xcx86-64 এর জন্য সি ( ) হিসাবে সংকলন 9.0 -O3 ক্ল্যাং :

main:                                   # @main
        push    rax                       # re-align the stack by 16
        mov     edi, offset .Lstr         # non-PIE executable can use 32-bit absolute addresses
        call    puts
.LBB3_1:                                # =>This Inner Loop Header: Depth=1
        jmp     .LBB3_1                   # infinite loop


.section .rodata
 ...
.Lstr:
        .asciz  "begin"

একই বিকল্পগুলির সাথে একই সংকলক একটি সংকলন করে main যা infloop() { while(1); }প্রথমে একই সাথে কল করে puts, কিন্তু তারপরে কেবল mainসেই বিন্দুর পরে নির্গমন নির্দেশগুলি থামিয়ে দেয় । সুতরাং আমি যেমন বলেছি, মৃত্যুদন্ড কার্যকর হ'ল ফাংশনটির সমাপ্তি, পরবর্তী যে কোনও ফাংশনে (তবে ফাংশন এন্ট্রির জন্য স্ট্যাকের সাথে ভুল চিহ্নযুক্ত যাতে এটি কোনও বৈধ টেলকলও নয়)।

বৈধ বিকল্পগুলি হবে

  • label: jmp labelঅসীম লুপ নির্গত করুন
  • বা (যদি আমরা স্বীকার করি যে অসীম লুপটি সরানো যেতে পারে) ২ য় স্ট্রিং মুদ্রণের জন্য অন্য কলটি প্রেরণ করে এবং এর return 0থেকে main

"অ্যাক্সেসযোগ্য" মুদ্রণ না করে ক্রাশ করা বা অন্যথায় চালিয়ে যাওয়া কোনও সি 11 বাস্তবায়নের জন্য স্পষ্টতই ঠিক নয়, যদি না ইউবি থাকে যা আমি লক্ষ্য করি না।


পাদটীকা 1:

রেকর্ডের জন্য, আমি @ লন্ডিনের উত্তরটির সাথে সম্মত যা মানকে উদ্ধৃত করে প্রমাণের জন্য যে সি 11 খালি থাকার পরেও ধ্রুবক-এক্সপ্রেশন অসীম লুপগুলিকে সমাপ্তির অনুমানের অনুমতি দেয় না (আই / ও, অস্থির, সিঙ্ক্রোনাইজেশন বা অন্য কোনও নয়) দৃশ্যমান পার্শ্ব প্রতিক্রিয়া)।

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

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

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

এটি বিরল যে আপনি কেবল পরবর্তী বাধা না দেওয়া পর্যন্ত স্পিন করতে চান, তবে আপনি যদি সিতে লিখেন তবে অবশ্যই এটি ঘটবে বলে আপনি প্রত্যাশা করেছেন। (এবং কি করে জিসিসি এবং ঝনঝন ঘটতে, ঝনঝন শব্দ জন্য ব্যতীত অসীম লুপ একটি লেফাফা ফাংশন ভিতরে)।

উদাহরণস্বরূপ, একটি আদিম ওএস কার্নেলের মধ্যে, যখন শিডিয়ুলারের চালানোর কোনও কাজ না থাকে এটি নিষ্ক্রিয় টাস্কটি চালাতে পারে। এটির প্রথম প্রয়োগ হতে পারে while(1);

বা কোনও পাওয়ার-সেভিং নিষ্ক্রিয় বৈশিষ্ট্য ছাড়াই হার্ডওয়্যারের জন্য, এটিই কেবলমাত্র বাস্তবায়ন হতে পারে। (2000 এর দশকের গোড়া পর্যন্ত, আমি মনে করি এটি x86 এ বিরল নয়। যদিও hltনির্দেশনাটি বিদ্যমান ছিল, আইডি কে এটি সিপিইউগুলিকে স্বল্প-শক্তি নিষ্কলনের অবস্থা শুরু না হওয়া পর্যন্ত অর্থবহ পরিমাণ শক্তি সঞ্চয় করে))


1
কৌতূহলের বাইরে, কেউ কি এম্বেড থাকা সিস্টেমের জন্য ঝাঁকুনি ব্যবহার করছে? আমি এটি কখনও দেখিনি এবং এম্বেড সহ একচেটিয়াভাবে কাজ করি। জিসিই কেবল "সম্প্রতি" (10 বছর আগে) এমবেডড মার্কেটে প্রবেশ করেছে এবং আমি সেটিকে সংবেদনশীলভাবে, কম অপটিমাইজেশন এবং সর্বদা সাথে ব্যবহার করি -ffreestanding -fno-strict-aliasing। এটি এআরএম এবং সম্ভবত উত্তরাধিকার এভিআরের সাথে দুর্দান্ত কাজ করে।
লুন্ডিন

1
@ লন্ডিন: এম্বেড থাকা সম্পর্কে IDK, তবে হ্যাঁ লোকে কমপক্ষে কখনও কখনও লিনাক্স দ্বারা ঝাঁকুনির সাহায্যে কার্নেল তৈরি করে। সম্ভবত ম্যাকওএসের পক্ষে ডারউইনও।
পিটার কর্ডেস

2
bugs.llvm.org/show_bug.cgi?id=965 এই বাগটি প্রাসঙ্গিক বলে মনে হচ্ছে, তবে আমি নিশ্চিত নই যে আমরা এখানে যা দেখছি তা এটি is
ব্র্যাককো 23

1
@ লন্ডিন - আমি বেশ নিশ্চিত যে আমরা জিটিসি (এবং প্রচুর অন্যান্য সরঞ্জামকিট) 90 এর দশক জুড়ে আরটিএসের মতো ভক্স ওয়ার্কস এবং পিএসওএস সহ এম্বেড করা কাজের জন্য ব্যবহার করেছি। আপনি কেন জিসিসি কেবল এমবেডড মার্কেটে প্রবেশ করেছেন তা আমি বুঝতে পারছি না।
জেফ লারম্যান

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

14

কেবল রেকর্ডের জন্য, কলং এর সাথেও খারাপ ব্যবহার করে goto:

static void die() {
nasty:
    goto nasty;
}

int main() {
    int x; printf("begin\n");
    die();
    printf("unreachable\n");
}

এটি প্রশ্নের মতো একই আউটপুট উত্পাদন করে, যেমন:

main: # @main
  push rax
  mov edi, offset .Lstr
  call puts
.Lstr:
  .asciz "begin"

আমি দেখতে পাচ্ছি যে এটি সি 11 তে অনুমোদিত হিসাবে এটি পড়ার কোনও উপায় দেখেনি, যা কেবলমাত্র বলে:

8.৮..6.১ (২) একটি gotoবিবৃতি এনকোলেসিং ফাংশনটিতে নামযুক্ত লেবেলের দ্বারা উপস্থাপিত বিবৃতিতে একটি শর্তহীন লাফ দেয়।

যেমন gotoএকটি "পুনরাবৃত্তি বিবৃতি" নয় (6.8.5 তালিকাগুলি while, doএবংfor ) বিশেষ সম্পর্কে কিছুই "পরিসমাপ্তি-অধিকৃত" indulgences আবেদন, যদি আপনি ওদের পড়তে চাই।

প্রতি আসল প্রশ্নের গডবোল্ট লিঙ্ক সংকলকটি x86-64 ঝনঝন 9.0.0 এবং পতাকাগুলি -g -o output.s -mllvm --x86-asm-syntax=intel -S --gcc-toolchain=/opt/compiler-explorer/gcc-9.2.0 -fcolor-diagnostics -fno-crash-diagnostics -O2 -std=c11 example.c

X86-64 GCC 9.2 এর মতো অন্যদের সাথে আপনি বেশ সুন্দরভাবে নিখুঁত হন:

.LC0:
  .string "begin"
main:
  sub rsp, 8
  mov edi, OFFSET FLAT:.LC0
  call puts
.L2:
  jmp .L2

পতাকা: -g -o output.s -masm=intel -S -fdiagnostics-color=always -O2 -std=c11 example.c


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

2
@ সুপারকার্ট মন্তব্যের জন্য ধন্যবাদ ... কেন অনুবাদ সীমা অতিক্রম করে অনুবাদ পর্যায়ে ব্যর্থ হওয়া এবং সম্পাদন করতে অস্বীকার করা ছাড়া অন্য কিছু করা হবে? এছাড়াও: " 5.1.1.3 ডায়াগনস্টিকস একটি মেনে চলা বাস্তবায়ন ... ডায়গনিস্টিক বার্তা আনবে ... যদি একটি প্রিপ্রোসেসিং অনুবাদ ইউনিট বা অনুবাদ ইউনিটে কোনও সিনট্যাক্স নিয়ম বা সীমাবদ্ধতার লঙ্ঘন থাকে ..."। আমি দেখতে পাচ্ছি না ফাঁসি কার্যকর পর্যায়ে ভ্রান্ত আচরণ কখনই মেনে চলতে পারে।
জোনাথঞ্জো

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

1
আমি "অনুবাদ সীমা" সম্পর্কে আপনার মন্তব্যের জবাব দিচ্ছিলাম। অবশ্যই মৃত্যুদণ্ড কার্যকর করার সীমাও রয়েছে, আমি স্বীকার করি আমি বুঝতে পারি না আপনি কেন তাদের অনুবাদ সীমাতে নষ্ট করা উচিত বা আপনি কেন এটি প্রয়োজনীয় বলেছিলেন suggest nasty: goto nastyব্যবহারকারী বা রিসোর্স ক্লান্তি হস্তক্ষেপ না করা পর্যন্ত আমি কেবল সিপু (গুলি) মেনে চলার কথা বলে কোনও কারণ দেখতে পাচ্ছি না ।
জোনাথঞ্জো

1
স্ট্যান্ডার্ডটি "কার্যকর করা সীমা" সম্পর্কে কোনও রেফারেন্স দেয় না যা আমি খুঁজে পেতে পারি। ফাংশন কল পাখির মত থিংস সাধারণত স্ট্যাক বরাদ্দ দ্বারা পরিচালনা করা হয়, কিন্তু একটি অনুসারী বাস্তবায়ন সীমাবদ্ধ 16 গভীরতায় প্রতি ফাংশন 16 কপি নির্মান করতে পারে কল ফাংশন, এবং একটি কল আছে bar()মধ্যে foo()থেকে একটি কল প্রক্রিয়া করা __1fooথেকে __2bar, থেকে __2fooথেকে __3bar, ইত্যাদি থেকে __16fooথেকে __launch_nasal_demons, যা সব স্বয়ংক্রিয় বস্তু স্ট্যাটিক্যালি বরাদ্দ করা হবে, এবং কি করতে হবে সম্ভব হবে সাধারণত একটি অনুবাদ সীমা মধ্যে একটি "চালান টাইম" সীমা।
সুপারক্যাট

5

আমি শয়তানের উকিল খেলব এবং যুক্তি দেব যে মানক স্পষ্টতই একটি সংকলককে অসীম লুপটি অনুকূলিতকরণ থেকে নিষেধ করে না।

একটি পুনরাবৃত্তির বিবৃতি যার নিয়ন্ত্রণ নিয়ন্ত্রণটি একটি ধ্রুবক অভিব্যক্তি নয়, 156) যা কোনও ইনপুট / আউটপুট ক্রিয়াকলাপ সম্পাদন করে না, অস্থির বস্তুগুলিতে অ্যাক্সেস করে না এবং তার দেহে কোনও সমন্বয় বা পারমাণবিক ক্রিয়াকলাপ সম্পাদন করে না, এক্সপ্রেশন নিয়ন্ত্রণ করে, বা (এর ক্ষেত্রে ক্ষেত্রে) বিবৃতি) এর এক্সপ্রেশন -3, বাস্তবায়ন দ্বারা অনুমান করা যেতে পারে 157 সমাপ্ত করার জন্য)

এর পার্স করা যাক। একটি পুনরাবৃত্তি বিবৃতি যা নির্দিষ্ট মানদণ্ডকে সন্তুষ্ট করে তা সমাপ্তি হিসাবে ধরে নেওয়া যেতে পারে:

if (satisfiesCriteriaForTerminatingEh(a_loop)) 
    if (whatever_reason_or_just_because_you_feel_like_it)
         assumeTerminates(a_loop);

মানদণ্ডটি সন্তুষ্ট না হলে এবং লুপটি বন্ধ হয়ে যেতে পারে এমন ধারনা না করে কী ঘটে যায় সে সম্পর্কে এটি কিছুই বলবে না যতক্ষণ মানের অন্যান্য নিয়ম পালন করা হয় ততক্ষণ স্পষ্টভাবে নিষিদ্ধ করা হয় না।

do { } while(0)বা while(0){}সমস্ত পুনরাবৃত্তির বিবৃতি (লুপস) এর পরে রয়েছে যা মাপসই পূরণ করে না যা একটি সংকলককে কেবল যে সমাপ্তির মতো ঝাঁকুনির ধারণা দেয় এবং তবুও তারা স্পষ্টতই সমাপ্ত করে।

তবে সংকলকটি কি কেবল অপ্টিমাইজ করতে while(1){}পারে?

5.1.2.3p4 বলেছেন:

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

এটি বিবৃতি নয়, বিবৃতিগুলিতে উল্লেখ করেছে, সুতরাং এটি 100% বিশ্বাসযোগ্য নয়, তবে এটি অবশ্যই এই জাতীয় কলগুলিকে অনুমতি দেয়:

void loop(void){ loop(); }

int main()
{
    loop();
}

এড়িয়ে যেতে হবে। মজার বিষয় হল, ঝনঝন এটি এড়িয়ে যায় না, এবং জিসিসিও তা করে না


"মানদণ্ডটি সন্তুষ্ট না হলে কী হয় সে সম্পর্কে এটি কিছুই বলে না" তবে এটি করে, 8.৮.৫.১ বিস্তৃত বিবৃতি: "লুপ বডিটির প্রতিটি সম্পাদনের আগে নিয়ন্ত্রণকারী অভিব্যক্তির মূল্যায়ন হয়" " এটাই. এটি একটি মান গণনা (একটি ধ্রুবক অভিব্যক্তির), এটি অ্যাবস্ট্রাক্ট মেশিনের 5.1.2.3 ব্যবস্থার অধীনে আসে যা মূল্যায়ন শব্দটিকে সংজ্ঞায়িত করে: " সাধারণভাবে একটি অভিব্যক্তির মূল্যায়ণে মান গণনা এবং পার্শ্ব প্রতিক্রিয়াগুলির সূচনা উভয়ই অন্তর্ভুক্ত থাকে।" এবং একই অধ্যায় অনুসারে, এই জাতীয় সমস্ত মূল্যায়নগুলি শব্দার্থবিজ্ঞানের দ্বারা নির্দিষ্ট হিসাবে ক্রমযুক্ত এবং মূল্যায়ন করা হয়।
লন্ডিন

1
@ লন্ডিন তাই মূল্যায়নের সাথে জড়িত মূল্যায়নের while(1){}এক অসীম অনুক্রম , তবে কোথায় এই মানদণ্ডে বলা হয় যে এই মূল্যায়নের ননজারো সময় নেওয়া দরকার ? জিসিসি আচরণটি আরও কার্যকর, আমার ধারণা, আপনি ভাষার বাইরে মেমরির অ্যাক্সেস যুক্ত কৌশলগুলি বা কৌশল ব্যবহার করতে হবে না uz তবে আমি বিশ্বাস করি না যে স্ট্যান্ডার্ড ঝাঁকুনিতে এই অপ্টিমাইজেশনটিকে নিষিদ্ধ করে। যদি নন-অপটিমাইজযোগ্য তৈরি করার উদ্দেশ্য হয়, তবে স্ট্যান্ডার্ডটি এটি সম্পর্কে স্পষ্ট হওয়া উচিত এবং অসীম লুপিংটি 5.1.2.3p2 এ পর্যবেক্ষণযোগ্য পার্শ্ব প্রতিক্রিয়া হিসাবে তালিকাভুক্ত করা উচিত। 1{}while(1){}
পিএসকোকিক

1
আমি মনে করি এটি নির্দিষ্ট করা আছে, যদি আপনি শর্তটিকে 1মান গণনা হিসাবে বিবেচনা করেন । সঞ্চালনের সময় কোন ব্যাপার না - আসলে একটি কি while(A){} B;হতে পারে না দূরে সম্পূর্ণভাবে অপ্টিমাইজ করা, এর অপ্টিমাইজ করা B;এবং না পুনরায় সিকোয়েন্স B; while(A){}। C11 বিমূর্ত মেশিন, জোর খনি উদ্ধৃত করা: "এক্সপ্রেশন A এবং B মূল্যায়ন মধ্যে একটা ক্রম বিন্দু উপস্থিতিতে যে বোঝা যে মান গণনার এবং পার্শ্ব প্রতিক্রিয়া একটি সঙ্গে যুক্ত প্রত্যেক মান গণনার আগে সিকোয়েন্স করা হয় এবং পার্শ্ব প্রতিক্রিয়া বি সঙ্গে যুক্ত ।" এর মানটি Aস্পষ্টভাবে ব্যবহৃত হয় (লুপ দ্বারা)।
লন্ডিন

2
+1 যদিও আমার কাছে মনে হয় "কোনও আউটপুট ছাড়াই অনির্দিষ্টকালের জন্য ফাঁসি কার্যকর করা" "পার্শ্ব-প্রতিক্রিয়া" এর কোনও সংজ্ঞায় একটি "পার্শ্ব-প্রতিক্রিয়া" যা বোধগম্য হয় এবং শূন্যতার মধ্যে কেবলমাত্র মানকে ছাড়াই দরকারী, এটি ব্যাখ্যা করতে সহায়তা করে যে মানসিকতা থেকে এটি কারও কাছে উপলব্ধি করতে পারে।
mtraceur

1
কাছাকাছি "একটি অসীম লুপটি অপ্টিমাইজ করা" : এটি সম্পূর্ণরূপে পরিষ্কার নয় যে "এটি" স্ট্যান্ডার্ড বা সংকলককে বোঝায় - সম্ভবত পুনরায়? প্রদত্ত "যদিও এটা সম্ভবত উচিত" এবং "যদিও এটা সম্ভবত উচিত না" , তাহলে সম্ভবত মান যে "এটা" বোঝায়।
পিটার মর্টেনসেন

2

আমি নিশ্চিত হয়েছি এটি কেবল একটি সরল পুরানো বাগ। আমি আমার পরীক্ষাগুলি নীচে রেখেছি এবং বিশেষত আমার আগে কিছু যুক্তির কারণে স্ট্যান্ডার্ড কমিটিতে আলোচনার রেফারেন্স।


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

আচরণটি অতিরিক্ত অদ্ভুত - এটি চূড়ান্ত মুদ্রণটি সরিয়ে দেয়, তাই অসীম লুপটিকে "দেখায়", তবে তারপরে লুপ থেকেও মুক্তি পাওয়া যায়।

যতদূর আমি বলতে পারি এটি আরও খারাপ। আমরা প্রাপ্ত ইনলাইনটি সরিয়ে দিচ্ছি:

die: # @die
.LBB0_1: # =>This Inner Loop Header: Depth=1
  jmp .LBB0_1
main: # @main
  push rax
  mov edi, offset .Lstr
  call puts
.Lstr:
  .asciz "begin"

সুতরাং ফাংশনটি তৈরি হয় এবং কলটি অনুকূলিত হয়। এটি প্রত্যাশার চেয়ে আরও বেশি স্থিতিস্থাপক:

#include <stdio.h>

void die(int x) {
    while(x);
}

int main() {
    printf("begin\n");
    die(1);
    printf("unreachable\n");
}

ফাংশনের জন্য খুব অ-অনুকূল সমাবেশে ফলাফল, তবে ফাংশন কলটি আবার অনুকূলিত হয়েছে! আরো খারাপ:

void die(x) {
    while(x++);
}

int main() {
    printf("begin\n");
    die(1);
    printf("unreachable\n");
}

আমি স্থানীয় ভেরিয়েবল যুক্ত করে এটিকে বাড়িয়ে, পয়েন্টারটি পাস করে, একটি gotoইত্যাদি ব্যবহার করে আরও একগুচ্ছ পরীক্ষা করেছি ... এই মুহুর্তে আমি হাল ছেড়ে দেব। আপনি অবশ্যই ঝাঁকুনি ব্যবহার করা উচিত

static void die() {
    int volatile x = 1;
    while(x);
}

কাজ করে এটি অপ্টিমাইজ করা (স্পষ্টতই) সাফল্য অর্জন করে এবং অতিরিক্ত কাজের ফাইনালে চলে যায় printf। কমপক্ষে প্রোগ্রামটি থামবে না। জিসিসির পরে কি সব হতে পারে?

অভিযোজ্য বস্তু

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

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

এটি করার জন্য একটি বড় সমস্যা হ'ল এটি কোডটি একটি সম্ভাব্য অ-টার্মিনেটিং লুপের ওপারে সরে যাওয়ার অনুমতি দেয়

এখান থেকে আমি মনে করি এটি কেবল যা অনুমোদিত তা পরিবর্তে আমরা কী চাই (প্রত্যাশিত?) এর আলোচনায় রূপান্তর করতে পারি ।


মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
Bhargav রাও

পুনরায় "প্লেইন অল বাগ" : আপনি কি " প্লেইন পুরাতন বাগ" বলতে চান ?
পিটার মর্টেনসেন

@ পিটারমোরটেনসেন "ওলে" আমার সাথেও ঠিক আছে।
কাবানুস

2

দেখে মনে হচ্ছে এটি ক্ল্যাং সংকলকের একটি বাগ is die()স্থিতিশীল ফাংশন হতে যদি কোনও বাধ্যবাধকতা না হয় তবে staticতা বন্ধ করে করুনinline :

#include <stdio.h>

inline void die(void) {
    while(1)
        ;
}

int main(void) {
    printf("begin\n");
    die();
    printf("unreachable\n");
}

ক্ল্যাং সংকলকটি সংকলিত হওয়ার সময় এটি প্রত্যাশা অনুযায়ী কাজ করছে এবং এটি বহনযোগ্যও।

সংকলক এক্সপ্লোরার (Godbolt.org) - ঝাঁকুনি 9.0.0-O3 -std=c11 -pedantic-errors

main:                                   # @main
        push    rax
        mov     edi, offset .Lstr
        call    puts
.LBB0_1:                                # =>This Inner Loop Header: Depth=1
        jmp     .LBB0_1
.Lstr:
        .asciz  "begin"

কি হবে static inline?
এসএস অ্যান

1

নিম্নলিখিতটি আমার পক্ষে কাজ করে বলে মনে হচ্ছে:

#include <stdio.h>

__attribute__ ((optnone))
static void die(void) {
    while (1) ;
}

int main(void) {
    printf("begin\n");
    die();
    printf("unreachable\n");
}

godbolt

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

volatile int x = 0;
if (x == 0)
    die();

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


1
printfলুপটি যদি চিরতরে চলে যায় তবে দ্বিতীয়টি উত্পন্ন করার জন্য এটি প্রয়োজনীয় নয় কারণ সেক্ষেত্রে দ্বিতীয়টি printfসত্যিই অ্যাক্সেসযোগ্য এবং তাই মোছা যায়। (কল্যাংয়ের ত্রুটিটি অদম্য শনাক্তকরণ সনাক্তকরণ এবং তারপরে অদৃশ্যযোগ্য কোডটি পৌঁছেছে এমন লুপটি মুছতে উভয় ক্ষেত্রেই)।
nneonneo

জিসিসি নথি __attribute__ ((optimize(1))), কিন্তু ঝোলা এটি অসমর্থিত হিসাবে উপেক্ষা করে: Godbolt.org/z/4ba2HMgcc.gnu.org/onlinesocs/gcc/Common-Function-Aribributes.html
পিটার

0

একটি বাস্তবায়ন কার্যকরকরণ এবং অনেকগুলি ব্যবহারিক প্রয়োগগুলি, কতক্ষণ একটি প্রোগ্রাম কার্যকর করতে পারে বা কতগুলি নির্দেশনা কার্যকর করে তার উপর স্বেচ্ছাসেবক সীমাবদ্ধতা আরোপ করতে পারে এবং যদি সীমাবদ্ধতা লঙ্ঘিত হয় বা - "হিসাবে যদি" ​​বিধি অনুসারে নির্বিচারে ফ্যাশন আচরণ করে - যদি এটি নির্ধারণ করে যে তারা অনিবার্যভাবে লঙ্ঘিত হবে। প্রদত্ত যে কোনও বাস্তবায়ন কমপক্ষে একটি প্রোগ্রাম সফলভাবে প্রক্রিয়া করতে পারে যা N1570 5.2.4.1 এ তালিকাভুক্ত সমস্ত সীমাবদ্ধতার ব্যয় করে কোনও অনুবাদ সীমা, সীমা অস্তিত্ব, যে পরিমাণে নথিভুক্ত করা হয় না এবং এগুলি অতিক্রম করে তার প্রভাবগুলি হ'ল স্ট্যান্ডার্ডের এখতিয়ারের বাইরে বাস্তবায়নের সমস্ত মানের বিষয়।

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


-2

লুপটির কোনও পার্শ্ব-প্রতিক্রিয়া নেই এবং তাই অপ্টিমাইজ করা যায়। লুপটি কার্যকরভাবে কাজের শূন্য ইউনিটের পুনরাবৃত্তির একটি সংখ্যা is এটি গণিত এবং যুক্তিতে অপরিজ্ঞাত এবং মানকটি বলে না যে প্রতিটি জিনিস শূন্য সময়ে করা যেতে পারে যদি একটি বাস্তবায়ন অসীম সংখ্যা সম্পূর্ণ করতে অনুমোদিত হয় কিনা। কলং এর ব্যাখ্যা অনন্তের চেয়ে শূন্য হিসাবে অনন্ত সময়ের শূন্য হিসাবে চিকিত্সা করার ক্ষেত্রে পুরোপুরি যুক্তিসঙ্গত। স্ট্যান্ডার্ডটি বলে না যে লুপগুলিতে সমস্ত কাজ বাস্তবে শেষ হলে অসীম লুপটি শেষ হতে পারে কি না।

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

এমনকি ঝাঁকুনি কোডটি অনায়াসে অনুবাদ করেও, আপনি এমন একটি অনুকূলিত সিপিইউ কল্পনা করতে পারেন যা পূর্ববর্তী পুনরাবৃত্তির অর্ধেক সময়ের মধ্যে প্রতিটি পুনরাবৃত্তি সম্পন্ন করতে পারে। এটি আক্ষরিক অর্থে একটি সীমিত পরিমাণে অসীম লুপটি সম্পূর্ণ করবে। যেমন একটি অনুকূলকরণ সিপিইউ মানক লঙ্ঘন করে? এটি বলা মোটেও অযৌক্তিক বলে মনে হয় যে অনুকূলিতকরণের ক্ষেত্রে খুব ভাল হলে একটি অপ্টিমাইজ করা সিপিইউ মানটিকে লঙ্ঘন করবে। একই একটি সংকলক ক্ষেত্রে।


মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
স্যামুয়েল লিউ

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

@ পাইপ: আমি মনে করি ঝনঝন এবং জিসিসি রক্ষণকারীরা আশা করছেন যে স্ট্যান্ডার্ডের ভবিষ্যতের সংস্করণটি তাদের সংযোজকগুলির আচরণকে বৈধ করে তুলবে এবং এই সংকলকগুলির রক্ষণাবেক্ষণকারীরা ভান করতে সক্ষম হবেন যে এই ধরনের পরিবর্তনটি কেবল একটি দীর্ঘস্থায়ী ত্রুটির সংশোধন ছিল স্ট্যান্ডার্ড মধ্যে। উদাহরণস্বরূপ, তারা সি 89 এর সাধারণ প্রাথমিক সিকোয়েন্স গ্যারান্টির সাথে এটি আচরণ করেছে।
সুপারক্যাট

@ এসএসএন: হুম ... আমি মনে করি না যে পয়েন্টার-সাম্যতার তুলনার ফলাফল থেকে কিছু নিরবিচ্ছিন্ন ইনফারেন্সেস জিসিসি এবং ঝনঝন ড্র করা যথেষ্ট block
সুপারক্যাট c

@ সুপের্যাট এখানে <s> অন্যান্য </ p> টন রয়েছে।
এসএস আন

-2

আমি দুঃখিত যদি এটি অযৌক্তিকভাবে ঘটনাটি না ঘটে তবে আমি এই পোস্টে হোঁচট খেয়েছি এবং আমি জানি কারণ আমার বছরগুলি জেন্টু লিনাক্স ব্যবহার করে বিকৃত করে যে আপনি যদি সংকলকটি আপনার কোডটি অপ্টিমাইজ না করতে চান তবে আপনাকে ওও (জিরো) ব্যবহার করা উচিত। আমি এটি সম্পর্কে কৌতূহল ছিলাম এবং উপরের কোডটি সংকলন করে চালিয়েছি এবং লুপটি অনির্দিষ্টকালের জন্য যায়। ঝনঝন -9 ব্যবহার করে সংকলিত:

cc -O0 -std=c11 test.c -o test

1
পয়েন্টটি হ'ল অপ্টিমাইজেশন সক্ষম করে একটি অসীম লুপ করা make
এসএস অ্যান

-4

খালি whileলুপটির সিস্টেমে কোনও পার্শ্ব প্রতিক্রিয়া নেই।

অতএব ঝাঁকুনি এটি সরিয়ে দেয়। উদ্দেশ্যমূলক আচরণ অর্জনের জন্য আরও "আরও ভাল" উপায় রয়েছে যা আপনাকে আপনার উদ্দেশ্য সম্পর্কে আরও সুস্পষ্ট হতে বাধ্য করে।

while(1); বাড্ড হয়।


6
অনেক এম্বেড থাকা কনস্ট্রাক্টসে, abort()বা এর কোনও ধারণা নেই exit()। যদি কোনও পরিস্থিতি দেখা দেয় যেখানে কোনও ফাংশন নির্ধারণ করে যে (সম্ভবত স্মৃতি দুর্নীতির ফলস্বরূপ) অব্যাহত সম্পাদনটি বিপজ্জনকের চেয়ে খারাপ হবে, এম্বেড গ্রন্থাগারগুলির জন্য একটি সাধারণ ডিফল্ট আচরণ হ'ল একটি কার্য সম্পাদন করে যা একটি সম্পাদন করে while(1);। সংকলকটির জন্য আরও কার্যকর আচরণের বিকল্পের বিকল্প থাকতে পারে , তবে যে কোনও সংকলক লেখক এই ধরণের সরল কনস্ট্রাক্টটিকে কীভাবে অব্যাহত প্রোগ্রামের প্রয়োগে বাধা হিসাবে আচরণ করতে পারেন তা জটিল অপ্টিমাইজেশনের সাথে বিশ্বাসযোগ্য নয়।
supercat

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

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

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

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