রিলিজ মোডে, কোড আচরণ প্রত্যাশার মতো নয়


131

নিম্নলিখিত কোডটি ডিবাগ মোড এবং রিলিজ মোডের অধীনে (ভিজ্যুয়াল স্টুডিও ২০০৮ ব্যবহার করে) বিভিন্ন ফলাফল উত্পন্ন করে:

int _tmain(int argc, _TCHAR* argv[])
{

    for( int i = 0; i < 17; i++ ) 
    { 
        int result = i * 16;

        if( result > 255 )
        {
            result = 255;
        }

        printf("i:%2d, result = %3d\n", i, result) ; 
    } 

    return 0;
}

প্রত্যাশা মতো ডিবাগ মোডের আউটপুট:

i: 0, result =   0
i: 1, result =  16
(...)
i:14, result = 224
i:15, result = 240
i:16, result = 255

রিলিজ মোডের আউটপুট, যেখানে আমি: 15 ফলাফল সঠিক নয়:

i: 0, result =   0
i: 1, result =  16
(...)
i:14, result = 224
i:15, result = 255
i:16, result = 255

রিলিজ মোডের অধীনে ভিজ্যুয়াল স্টুডিওতে "অনুকূলকরণ -> অনুকূলকরণ না করা" চয়ন করে আউটপুট ফলাফলটি সঠিক হবে। তবে আমি জানতে চাই কেন অপ্টিমাইজেশন প্রক্রিয়াটি ভুল ফলাফলকে নিয়ে যেতে পারে।


হালনাগাদ:

মোহিত জৈনবাইয়ের পরামর্শ অনুসারে প্রিন্ট করেছেন:

printf("i:%2d, result = %3d, i*16=%d\n", i, result, i*16) ;

রিলিজ মোড আউটপুট সঠিক:

i: 0, result =   0, i*16=0
i: 1, result =  16, i*16=16
(...)
i:14, result = 224, i*16=224
i:15, result = 240, i*16=240
i:16, result = 255, i*16=256

15
এটি দেখতে একটি সংকলক বাগের মতো (এবং এটিতে মোটামুটি উল্লেখযোগ্য)।
WhozCraig

1
@ হোজক্রেইগ কেবল i * 16পোস্টে আউটপুট আপডেট করে এবং ফলাফলটি সঠিক।
লরিস লিন

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

2
এফডব্লিউআইডাব্লু এটি আসন্ন ভিজ্যুয়াল স্টুডিও 2015
ইমেইল

উত্তর:


115

এটি আকর্ষণীয়, অন্তত একটি perspectiveতিহাসিক দৃষ্টিকোণ থেকে। আমি ভিসি 2008 (15.00.30729.01) এবং ভিসি 2010 (16.00.40219.01) (32-বিট x86 বা 64-বিট x64 দ্বারা লক্ষ্যবস্তু) নিয়ে সমস্যাটি পুনরুত্পাদন করতে পারি । ভিসি 2012 (17.00.61030) দিয়ে শুরু করার চেষ্টা করেছি এমন কোনও সংকলক দিয়েও সমস্যাটি দেখা দেয় না।

কমান্ডটি আমি সংকলন করতে ব্যবহৃত: cl /Ox vc15-bug.cpp /FAsc

ভিসি ২০০৮ (এবং ২০১০) এর পরিবর্তে পুরানো এবং সমাধানটি বেশ কয়েক বছর ধরে চলেছে বলে আমি মনে করি না যে মাইক্রোসফ্টের কাছ থেকে কোনও নতুন সংকলক ব্যবহার করা ছাড়া আপনি কোনও পদক্ষেপের আশা করতে পারেন (যদিও সম্ভবত কেউ কোনও কাজের প্রস্তাব দিতে পারে)।

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

; 6    :    for( int i = 0; i < 17; i++ ) 

  00001 33 f6        xor     esi, esi
$LL4@main:
  00003 8b c6        mov     eax, esi
  00005 c1 e0 04     shl     eax, 4

; 7    :    { 
; 8    :        int result = i * 16;
; 9    : 
; 10   :        if( result > 255 )

  // the value `esi` is compared with in the following line should be 15!
  00008 83 fe 0e     cmp     esi, 14            ; 0000000eH
  0000b 7e 05        jle     SHORT $LN1@main

; 11   :        {
; 12   :            result = 255;

  0000d b8 ff 00 00 00   mov     eax, 255       ; 000000ffH
$LN1@main:

; 13   :        }

আপডেট : ভিসি ২০০৮ এর আগে আমি ভিসির সমস্ত সংস্করণ ইনস্টল করেছি ভিসি 6 বাদে একই বাগ রয়েছে - প্রোগ্রামটি সংকলন করে ভিসি 6 সংকলক ক্র্যাশ হয়েছে:

vc15-bug.cpp(10) : fatal error C1001: INTERNAL COMPILER ERROR

সুতরাং এটি একটি বাগ যা এমএসভিসিতে এক বা অন্য কোনও আকারে 10 বছরেরও বেশি সময় ধরে স্থায়ী হয়েছিল!


যদি x86 অ্যাসেম্বলি টাইমিংয়ের আমার স্মৃতি সঠিকভাবে EX এর চেয়ে তুলনা করার জন্য সঠিক হয় তবে কমপ্যাক্স EX হয় না, 255 টি পাইপলাইন স্টলের কারণ ইক্স সবেমাত্র লেখা হয়েছে।
লরেন পেচটেল

3
আমার অনুমান (রূপান্তরের): ফলাফলের> 255, ফলে / 16> 255/16, আমি> 15, আমি <= 14
teki

খুব আকর্ষণীয়! এছাড়াও আপনি তুলনা পরিবর্তন থেকে result > 255থেকে result >= 255এটি সঠিকভাবে আচরণ করে। VS2010 এ যা পরিবর্তিত cmp esi, 14হয় cmp esi, 16(এবং jleথেকে jl)।
অপেলো

16

আপনার উল্লিখিত তথ্যগুলি সঠিক বলে ধরে নিচ্ছেন, এটি একটি সংকলক বাগ হবে। সংকলকটির সর্বশেষতম সংস্করণটি দেখুন। বাগটি এখনও উপস্থিত থাকলে একটি বাগ রিপোর্ট জমা দিন।

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