কোনও পরিবর্তনশীল সূচনাতে লাফিয়ে ফেলা কি খারাপ ধারণা তৈরি হয়েছে বা এটি অনির্ধারিত আচরণের কারণ ঘটায়?


17

এই কোডটি বিবেচনা করুন:

void foo()
{
    goto bar;
    int x = 0;
    bar: ;
}

জিসিসি এবং ক্ল্যাং এটিকে প্রত্যাখ্যান করে , কারণ bar:পরিবর্তনশীল সূচনাটিকে বাইপাস করে। এমএসভিসি মোটেও অভিযোগ করে না ( সতর্কতার কারণ হিসাবে ব্যবহার xকরা বাদে bar:)।

আমরা একটি দিয়ে একই জিনিস করতে পারি switch:

void foo()
{
    switch (0)
    {
        int x = 0;
        case 0: ;
    }
}

এখন তিনটি সংকলক ত্রুটি নির্গত করে

এই স্নিপেটগুলি কি গঠনযুক্ত? বা তারা ইউবি সৃষ্টি করে?

আমি ভাবতাম যে দু'জনই দুর্বল, তবে আমি স্ট্যান্ডার্ডের উদ্ভাসিত অংশগুলি খুঁজে পাই না। [stmt.goto] এ সম্পর্কে কিছুই বলে না এবং [stmt.select ] ও করে না ।


1
আপনি যদি xলাফ দেওয়ার পরে ব্যবহার করেন তবে বিষয়টি আরও তুচ্ছ ।
জারোড 42

1
মানক নয়, তবে এখানে এটির জন্য কিছু তথ্য পাওয়া যাবে: বিশেষত: en.cppreferences.com/w/cpp/language/goto : "নিয়ন্ত্রণের স্থানান্তর যদি কোনও স্বয়ংক্রিয় ভেরিয়েবলের স্কোপে প্রবেশ করে (উদাহরণস্বরূপ কোনও ঘোষণার উপরে এগিয়ে যাওয়ার মাধ্যমে) বিবৃতি), প্রোগ্রামটি
দুর্গঠিত

/permissive-এমএসভিসিতে পতাকা যুক্ত করুন এবং এটিও অভিযোগ করবে। আমি জানি না যে পতাকাটি ব্যতীত এমএসভিসির আচরণটি সঠিকভাবে সংজ্ঞায়িত হয়েছে কিনা (আমি তা ধরে নেব, নইলে তারা কেন এটি অনুমতি দেবে?)।
আখরোট

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

উত্তর:


20

যখন সূচনাটি শূন্য না হয় তখন এটি দূষিত।

[Stmt.dcl]

3 কোনও ব্লকে স্থানান্তর করা সম্ভব, তবে এমনভাবে নয় যে প্রারম্ভিককরণের সাথে ঘোষণাকে বাইপাস করে (শর্ত এবং সূচনা-বিবৃতি সহ)। যে প্রোগ্রামটি এমন একটি বিন্দু থেকে লাফ দেয় যেখানে স্বয়ংক্রিয় স্টোরেজ সময়কাল সহ একটি ভেরিয়েবল এমন বিন্দুতে স্কোপ হয় না যেখানে এটি স্কোপতে থাকে তবে ভেরিয়েবলের শূন্য সূচনা ([বেসিক.লাইফ]) না থাকলে অসুস্থ হয়। এই ক্ষেত্রে, শূন্য সূচনা সহ ভেরিয়েবলগুলি তাদের ঘোষণার ক্রম হিসাবে নির্মিত হয়।

ইনিশিয়ালাইজার সূচনাটি শূন্য করে তোলে। বিপরীতে, এটি

void foo()
{
    goto bar;
    int x; // no initializer
    bar: ;
}

সুগঠিত হবে। যদিও xএকটি অনির্দিষ্ট মান সহ ব্যবহার সম্পর্কে সাধারণ সতর্কতা প্রযোজ্য।


ভেরিয়েবলের ঘোষণা কীভাবে কোনও সুযোগে প্রথম হওয়া উচিত?
ক্রুঙ্কার

4
@ ক্রাঙ্কার - সি 89 এর প্রয়োজনীয় ছিল। সি ++ কখনও করেনি, এবং আধুনিক সিও আর করে না।
গল্পগ্রাহক - আনস্ল্যান্ডার মনিকা

3

গোটো স্টেটমেন্ট থেকে :

নিয়ন্ত্রণের স্থানান্তর যদি কোনও স্বয়ংক্রিয় ভেরিয়েবলের স্কোপগুলিতে প্রবেশ করে (উদাহরণস্বরূপ কোনও ঘোষণার বিবরণীর উপরে ঝাঁপিয়ে পড়ে), প্রোগ্রামটি খারাপভাবে গঠিত (সংকলন করা যায় না), যদি না সমস্ত ভেরিয়েবল যার স্কোপটি প্রবেশ করে থাকে

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