সি-তে ঘোষিত, অবিচ্ছিন্ন ভেরিয়েবলের কী ঘটে? এর কোন মূল্য আছে?


139

সিআই তে থাকলে লিখুন:

int num;

আমি যে কোনও কিছু অর্পণ করার আগে num, numঅনির্দিষ্ট মানটির মূল্য ?


4
উম, এটি কি কোনও সংজ্ঞায়িত পরিবর্তনশীল নয়, ঘোষিত নয় ? (এটি যদি আমার সি ++ এর মাধ্যমে জ্বলজ্বলে হয় তবে আমি দুঃখিত)
এসবিআই

6
না। আমি এটির সংজ্ঞা না দিয়ে পরিবর্তনশীল ঘোষণা করতে পারি: extern int x;তবে সর্বদা সংজ্ঞায়িত হ'ল ঘোষণাকে বোঝায়। এটি সি ++ তে সত্য নয়, স্ট্যাটিক ক্লাসের সদস্য ভেরিয়েবলগুলি ঘোষণা ছাড়াই সংজ্ঞা দিতে পারে, কারণ ঘোষণাটি অবশ্যই শ্রেণির সংজ্ঞায় থাকতে হবে (ঘোষণা নয়!) এবং সংজ্ঞাটি অবশ্যই শ্রেণির সংজ্ঞার বাইরে থাকতে হবে।
বিডনলান

ee.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1.4.html সংজ্ঞায়িত মনে হচ্ছে এর অর্থ আপনাকেও এটি শুরু করতে হবে।
21

উত্তর:


188

স্ট্যাটিক ভেরিয়েবল (ফাইল স্কোপ এবং ফাংশন স্ট্যাটিক) শূন্য থেকে শুরু করা হয়:

int x; // zero
int y = 0; // also zero

void foo() {
    static int x; // also zero
}

অ স্থিতিশীল ভেরিয়েবল (স্থানীয় ভেরিয়েবল) অনির্দিষ্ট । অপরিশোধিত আচরণে কোনও মান ফলাফল নির্ধারণের আগে সেগুলি পড়া।

void foo() {
    int x;
    printf("%d", x); // the compiler is free to crash here
}

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

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

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


2
ওহ না তারা হয় না আপনি হয়ত ভাগ্যবান হলে, আপনি কোনও গ্রাহকের সামনে না থাকলে, আপনি যদি ভাগ্যবান হন
মার্টিন বেকেট

8
কি না? স্ট্যাটিক সূচনাটি স্ট্যান্ডার্ড দ্বারা প্রয়োজনীয়; আইএসও / আইইসি 9899: 1999 6.7.8 # 10
বিডনলান

2
প্রথম উদাহরণটি যতদূর আমি বলতে পারি ঠিক আছে। আমি যদিও কম

6
@ স্টুয়ার্ট: "ট্র্যাপ প্রতিনিধিত্ব" নামে একটি জিনিস রয়েছে যা মূলত কিছুটা প্যাটার্ন যা কোনও বৈধ মানকে বোঝায় না এবং রানটাইমের সময় যেমন হার্ডওয়ার ব্যতিক্রম হতে পারে ex কেবলমাত্র সি ধরণের যার জন্য গ্যারান্টি রয়েছে যে কোনও বিট প্যাটার্ন একটি বৈধ মান char; অন্য সকলের ফাঁদে উপস্থাপনা থাকতে পারে। বিকল্পভাবে - যেহেতু অবিচ্ছিন্ন ভেরিয়েবলটি অ্যাক্সেস করা যেকোনো উপায়েই ইউবি হয় - তবে একটি সংমিশ্রণকারী সংকলক সম্ভবত কিছু পরীক্ষা-নিরীক্ষা করতে পারে এবং সমস্যার সংকেত দেওয়ার সিদ্ধান্ত নিতে পারে।
পাভেল মিনায়েভ

5
বিডোনিয়ান সঠিক। সি সর্বদা মোটামুটি সুনির্দিষ্টভাবে নির্দিষ্ট করা হয়েছে। সি 98 এবং সি 99 এর আগে, ডিসিআর দ্বারা প্রকাশিত একটি কাগজ 1970 এর দশকের গোড়ার দিকে এই সমস্ত বিষয় নির্দিষ্ট করে দেয়। এমনকি ক্রুডেস্ট এমবেডেড সিস্টেমে, জিনিসগুলি সঠিকভাবে করতে কেবল একটি মেমসেট লাগে (), তাই কোনও নন-কনফর্মিং পরিবেশের জন্য কোনও অজুহাত নেই। আমি আমার উত্তরে মানটি উল্লেখ করেছি।
ডিজিটালরোস

57

0 স্থিতিশীল বা বিশ্বব্যাপী, স্টোরেজ শ্রেণি স্বয়ংক্রিয় হলে অনির্দিষ্ট

সি সর্বদা অবজেক্টের প্রাথমিক মান সম্পর্কে খুব নির্দিষ্ট হয়ে থাকে। যদি গ্লোবাল বা static, তাদের শূন্য করা হবে। যদি auto, মান অনির্দিষ্ট হয়

এটি সি -89 পূর্বের সংকলকগুলিতে কেসআরআর এবং ডিএমআর এর মূল সি রিপোর্টে উল্লেখ করা হয়েছিল।

এটি সি 98 এর ক্ষেত্রে ছিল, বিভাগ 6.5.7 দেখুন ।

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

এটি সি 99 এর ক্ষেত্রে ছিল , .7.৮ সূচনাটি দেখুন ।

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

ঠিক অনির্দিষ্ট মানে কী, আমি সি 98 এর পক্ষে নিশ্চিত নই, সি 99 বলেছেন:

৩.১.2.২
অনির্দিষ্ট মান

হয় একটি অনির্দিষ্ট মান বা একটি ফাঁদ উপস্থাপনা

তবে মানক যা বলে তা নির্বিশেষে, বাস্তব জীবনে, প্রতিটি স্ট্যাক পৃষ্ঠাটি শূন্য হিসাবে শুরু হয়, কিন্তু যখন আপনার প্রোগ্রামটি কোনও autoস্টোরেজ শ্রেণীর মান দেখায় , যখন এটি সর্বশেষে সেই স্ট্যাক ঠিকানাগুলি ব্যবহার করেছিল তখন এটি আপনার নিজের প্রোগ্রামের পিছনে যা ছিল তা তা দেখতে পাবে। যদি আপনি প্রচুর autoঅ্যারে বরাদ্দ করেন তবে আপনি দেখতে পাবেন সেগুলি শেষ পর্যন্ত জিরো দিয়ে ঝরঝরে শুরু করবে।

আপনি ভাবতে পারেন, কেন এইভাবে? একটি ভিন্ন এসও উত্তর সেই প্রশ্নের সাথে ডিল করে, দেখুন: https://stackoverflow.com/a/2091505/140740


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

সি 11 এন 1570 খসড়ায়, সংজ্ঞাটি indeterminate value3.19.2 এ পাওয়া যাবে।
ব্যবহারকারী 3528438

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

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

@ ব্রায়ানপোস্টো নো, এটি সঠিক নয়। স্ট্যাকওভারফ্লো . com/a/40674888/584518 দেখুন । একটি অনির্দিষ্ট মান ব্যবহার ঘটায় অনির্দিষ্ট আচরণ, না অনির্ধারিত আচরণ, ফাঁদ উপস্থাপনা ক্ষেত্রে জন্য সংরক্ষণ করুন।
লন্ডিন

12

এটি ভেরিয়েবলের সঞ্চয়স্থানের সময়কালের উপর নির্ভর করে। স্ট্যাটিক স্টোরেজ সময়কাল সহ একটি পরিবর্তনশীল সর্বদা স্পষ্টভাবে শূন্য দিয়ে শুরু করা হয়।

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

int num;
int a = num;
int b = num;

যে পরিবর্তনশীল গ্যারান্টি দেয় না aএবং bঅভিন্ন মান পাবেন। মজার বিষয় হল, এটি কোনও পেডেন্টিক তাত্ত্বিক ধারণা নয়, এটি অপ্টিমাইজেশনের ফলস্বরূপ বাস্তবে ঘটে।

সুতরাং সাধারণভাবে, জনপ্রিয় উত্তর যে "যা ময়লা ছিল মেমরির সাথে তা দিয়ে শুরু করা হয়েছিল" এমনকি দূরবর্তী থেকেও সঠিক নয়। Uninitialized পরিবর্তনশীল আচরণ একটি পরিবর্তনশীল যে থেকে ভিন্ন সক্রিয়া আবর্জনা সঙ্গে।


আমি বুঝতে পারি না (ভাল আমি খুব ভাল করতে পারি ) কেন এটির মাত্র এক মিনিট পরে ডিজিটালরোস এর চেয়ে অনেক কম উচ্চারণ আছে: ডি
অ্যান্টি হাপাল

7

উবুন্টু 15.10, কার্নেল 4.2.0, x86-64, জিসিসি 5.2.1 উদাহরণ

পর্যাপ্ত মান, আসুন একটি বাস্তবায়ন দেখুন :-)

স্থানীয় পরিবর্তনশীল

মানক: অপরিবর্তিত আচরণ

বাস্তবায়ন: প্রোগ্রামটি স্ট্যাকের স্থান বরাদ্দ করে, এবং কখনও কখনও সেই ঠিকানায় কিছুই স্থানান্তরিত করে না, তাই আগে যা ছিল তা ব্যবহৃত হয়।

#include <stdio.h>
int main() {
    int i;
    printf("%d\n", i);
}

সংকলন:

gcc -O0 -std=c99 a.c

আউটপুট:

0

এবং এর সাথে decompiles:

objdump -dr a.out

প্রতি:

0000000000400536 <main>:
  400536:       55                      push   %rbp
  400537:       48 89 e5                mov    %rsp,%rbp
  40053a:       48 83 ec 10             sub    $0x10,%rsp
  40053e:       8b 45 fc                mov    -0x4(%rbp),%eax
  400541:       89 c6                   mov    %eax,%esi
  400543:       bf e4 05 40 00          mov    $0x4005e4,%edi
  400548:       b8 00 00 00 00          mov    $0x0,%eax
  40054d:       e8 be fe ff ff          callq  400410 <printf@plt>
  400552:       b8 00 00 00 00          mov    $0x0,%eax
  400557:       c9                      leaveq
  400558:       c3                      retq

X86-64 কলিং কনভেনশন সম্পর্কে আমাদের জ্ঞান থেকে:

  • %rdiপ্রথম প্রিন্টফ আর্গুমেন্ট, সুতরাং "%d\n"ঠিকানায় স্ট্রিং0x4005e4

  • %rsiএইভাবে দ্বিতীয় প্রিন্টফ যুক্তি i

    এটি থেকে আসে -0x4(%rbp), এটি প্রথম 4-বাইট স্থানীয় পরিবর্তনশীল।

    এই মুহুর্তে, rbpস্ট্যাকের প্রথম পৃষ্ঠায় কার্নেল দ্বারা বরাদ্দ করা হয়েছে, সুতরাং সেই মানটি বোঝার জন্য আমরা কার্নেল কোডটি সন্ধান করতে হবে এবং এটি কী সেট করে তা নির্ধারণ করতে হবে।

    টোডো কি কোনও প্রক্রিয়া মারা যাওয়ার পরে কার্নেলটি অন্য প্রক্রিয়াগুলির পুনরায় ব্যবহার করার আগে সেই মেমরিটিকে কিছু সেট করে? যদি তা না হয় তবে নতুন প্রক্রিয়াটি অন্যান্য সমাপ্ত প্রোগ্রামগুলির মেমরি পড়তে সক্ষম হবে, তথ্য ফাঁস করবে। দেখুন: অবিচ্ছিন্ন মানগুলি কি কখনও সুরক্ষা ঝুঁকিপূর্ণ?

এরপরে আমরা আমাদের নিজস্ব স্ট্যাক পরিবর্তনগুলি নিয়ে খেলতে এবং মজাদার জিনিসগুলি লিখতে পারি:

#include <assert.h>

int f() {
    int i = 13;
    return i;
}

int g() {
    int i;
    return i;
}

int main() {
    f();
    assert(g() == 13);
}

স্থানীয় পরিবর্তনশীল -O3

বাস্তবায়ন বিশ্লেষণ এখানে: জিডিবিতে <মান অপ্টিমাইজড> এর অর্থ কী?

গ্লোবাল ভেরিয়েবল

স্ট্যান্ডার্ড: 0

বাস্তবায়ন: .bssবিভাগ

#include <stdio.h>
int i;
int main() {
    printf("%d\n", i);
}

gcc -00 -std=c99 a.c

সংকলন:

0000000000400536 <main>:
  400536:       55                      push   %rbp
  400537:       48 89 e5                mov    %rsp,%rbp
  40053a:       8b 05 04 0b 20 00       mov    0x200b04(%rip),%eax        # 601044 <i>
  400540:       89 c6                   mov    %eax,%esi
  400542:       bf e4 05 40 00          mov    $0x4005e4,%edi
  400547:       b8 00 00 00 00          mov    $0x0,%eax
  40054c:       e8 bf fe ff ff          callq  400410 <printf@plt>
  400551:       b8 00 00 00 00          mov    $0x0,%eax
  400556:       5d                      pop    %rbp
  400557:       c3                      retq
  400558:       0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
  40055f:       00

# 601044 <i>এটি iঠিকানাতে 0x601044এবং বলে:

readelf -SW a.out

রয়েছে:

[25] .bss              NOBITS          0000000000601040 001040 000008 00  WA  0   0  4

যা বলছে বিভাগের 0x601044ঠিক মাঝখানে .bss, যা শুরু হয় 0x601040এবং এটি 8 বাইট দীর্ঘ।

ELF মান তারপর গ্যারান্টী বা নিশ্চয়তা নামে অধ্যায় .bssসম্পূর্ণরূপে শূন্য দিয়ে পূর্ণ:

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

তদ্ব্যতীত, প্রকারটি SHT_NOBITSকার্যকর এবং এক্সিকিউটেবল ফাইলে কোনও স্থান দখল করে না:

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

তারপরে লিনাক্স কার্নেলের উপর নির্ভর করে প্রোগ্রামটি মেমোরিতে লোড করার সময় সেই মেমরি অঞ্চলটি শূন্যের বাইরে চলে যায়।


4

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


1

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

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

uint16_t hey(uint32_t x, uint32_t mode)
{ uint16_t q; 
  if (mode==1) q=2; 
  if (mode==3) q=4; 
  return q; }

 uint32_t wow(uint32_t mode) {
   return hey(1234567, mode);
 }

খুব ভাল ফলাফল wow()যথাক্রমে 1234567 মান 0 এবং 1 যথাক্রমে রেজিস্টারগুলিতে সঞ্চয় করে এবং কল করে foo()। যেহেতু x"foo" এর মধ্যে প্রয়োজন নেই, এবং যেহেতু ফাংশনগুলি তাদের রিটার্নের মান 0 রেজিস্টারে রাখার কথা, তাই সংকলকটি 0 থেকে নিবন্ধিক বরাদ্দ করতে পারে q। যদি mode1 বা 3 হয় তবে রেজিস্টার 0 যথাক্রমে 2 বা 4 দিয়ে লোড হবে, তবে এটি যদি অন্য কোনও মান হয় তবে ফাংশনটি রেজিস্টারে 0 (যেমন মান 1234567) -তে থাকা সত্ত্বেও ফিরিয়ে দিতে পারে যদিও সেই মান সীমাটির মধ্যে নেই is uint16_t।

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

void moo(int mode)
{
  if (mode < 5)
    launch_nukes();
  hey(0, mode);      
}

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


0

প্রাথমিক উত্তরটি হ্যাঁ, এটি অপরিজ্ঞাত।

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


0

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

তবে কিছু সংকলকগুলির এ জাতীয় সমস্যা এড়াতে ব্যবস্থা থাকতে পারে।

আমি এনইসি ভি 850 সিরিজের সাথে কাজ করছি যখন আমি বুঝতে পারলাম ট্র্যাপের উপস্থাপনা রয়েছে যা বিট প্যাটার্ন রয়েছে যা চর জন্য ব্যতীত ডেটা ধরণের জন্য অপরিজ্ঞাত মানকে উপস্থাপন করে। যখন আমি একটি অবিচ্ছিন্ন চর নিয়েছি তখন ফাঁদ উপস্থাপনের কারণে আমি একটি শূন্য ডিফল্ট মান পেয়েছি। এটি necv850es ব্যবহার করে যে কোনও 1 এর জন্য কার্যকর হতে পারে


স্বাক্ষরবিহীন চর ব্যবহার করার সময় আপনি ট্র্যাপের উপস্থাপনাগুলি পান তবে আপনার সিস্টেমটি উপযুক্ত নয়। তাদের স্পষ্টভাবে ফাঁদ উপস্থাপনা, C17 6.2.6.1/5 ধারণ করার অনুমতি নেই।
লুন্ডিন

-2

মূল মানটি (র‌্যাম) থেকে নামটির মানটি কিছু আবর্জনা মান হবে। এটি তৈরির পরে যদি আপনি ভেরিয়েবলটি শুরু করেন তবে এটি আরও ভাল।


-4

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

int i;
printf('%d',i);

উদাহরণস্বরূপ যদি আপনি একটি ডিটারমিনিস্টিক মান পান তবে 0আপনার সংকলকটি সম্ভবত এটির যে মানটি পেয়েছে তা নিশ্চিত করার জন্য অতিরিক্ত পদক্ষেপ নিয়ে যায় (যেভাবেই ভেরিয়েবলগুলি সূচনা করার জন্য কোড যুক্ত করে)। কিছু সংকলক এটি "ডিবাগ" সংকলন করার সময় এটি করেন তবে 0এগুলির জন্য মানটি বেছে নেওয়া একটি খারাপ ধারণা কারণ এটি আপনার কোডের ত্রুটিগুলি আড়াল করে রাখবে (আরও সঠিক জিনিসটি সত্যিই অসম্পূর্ণ সংখ্যার মতো 0xBAADF00Dবা অনুরূপ কিছুটির গ্যারান্টি দিতে পারে )। আমি মনে করি বেশিরভাগ সংকলক মেমরিটি ভেরিয়েবলের মান হিসাবে দখল করতে ঘটবে যা কিছু ঘটবে তা ছেড়ে দেবে (যেমন এটি সাধারণভাবে হিসাবে একত্রিত হয় না0 )।
7:25
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.