বিটওয়াইজ অপারেশনের ফলে অপ্রত্যাশিত পরিবর্তনশীল আকারের ফলাফল হয়


24

প্রসঙ্গ

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

if(~counter) counter++;

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

সমস্যা

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

uint8_t i = 0;
int sz;

sz = sizeof(i);
printf("Size of variable: %d\n", sz); // Size of variable: 1

sz = sizeof(~i);
printf("Size of result: %d\n", sz); // Size of result: 4

আউটপুট প্রথম লাইনে, আমরা যা প্রত্যাশা করব তা পাই: i1 বাইট। তবে, বিটওয়াইসের পরিপূরকটি iআসলে চারটি বাইট যা সমস্যার কারণ কারণ এটির সাথে এখন তুলনা করা প্রত্যাশিত ফলাফল দেয় না। উদাহরণস্বরূপ, যদি করা হয় (যেখানে iসঠিকভাবে-সূচনা করা হয়েছে uint8_t):

if(~i) i++;

আমরা i0xFF থেকে 0x00 এ ফিরে "প্রায় মোড়ানো" দেখতে পাব । পূর্ববর্তী সংকলক এবং 8-বিট পিআইসির মাইক্রোকন্ট্রোলারের মধ্যে যেমনটি কাজ করা হয়েছিল তখন তার সাথে তুলনা করে এই আচরণটি জিসিসিতে আলাদা।

আমরা সচেতন যে আমরা এর মতো কাস্টিংয়ের মাধ্যমে সমাধান করতে পারি:

if((uint8_t)~i) i++;

অথবা দ্বারা

if(i < 0xFF) i++;

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

প্রশ্ন

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

উপরিভাগে এটি কোনও বিশাল সমস্যার মতো মনে হচ্ছে না তবে এই পূর্বে কাজ করা প্রতিমাটি কয়েকশ জায়গায় ব্যবহার করা হয়েছে এবং ব্যয়বহুল পরিবর্তনগুলি নিয়ে এগিয়ে যাওয়ার আগে আমরা এটি বুঝতে আগ্রহী।


দ্রষ্টব্য: এখানে আপাতদৃষ্টিতে অনুরূপ তবে সঠিক ডুপ্লিকেট প্রশ্ন নেই: চরে বিটওয়াস অপারেশন 32 বিট ফলাফল দেয়

আমি সেখানে আলোচিত ইস্যুর আসল চরিত্রটি দেখতে পাইনি, অর্থাত্ অপারেটরটিতে যা হয়েছে তার চেয়ে বিটওয়াইসের পরিপূরকের ফলাফলের আকারটি আলাদা being


14
"আমাদের ধারণাটি কি সঠিক, যে বিটওয়াইজ পরিপূরকের মতো কোনও ক্রিয়াকলাপ অপারেন্ডের সমান আকারের ফলাফলটি ফিরিয়ে আনবে?" না, এটি সঠিক নয়, পূর্ণসংখ্যা প্রচারগুলি প্রয়োগ হয়।
থমাস জাগার

2
যদিও অবশ্যই প্রাসঙ্গিক, তবুও আমি এগুলি এই নির্দিষ্ট প্রশ্নের সদৃশ নয়, কারণ তারা সমস্যার সমাধান দেয় না solution
কোডি গ্রে

3
আমার মনে হচ্ছে আমি পাগল বড়ি নিচ্ছি এবং সি এর চেয়ে কিছুটা বেশি বহনযোগ্য হওয়া উচিত। আপনি যদি 8-বিট প্রকারের পূর্ণসংখ্যার প্রচার না পেয়ে থাকেন তবে আপনার সংকলক সি স্ট্যান্ডার্ড উপযুক্ত নয়। সেক্ষেত্রে আমি মনে করি আপনার পরীক্ষা করা উচিত এবং যদি প্রয়োজন হয় তবে তা ঠিক করার জন্য আপনার সমস্ত গণনা করা উচিত ।
ব্যবহারকারী 694733

1
আমি কি কেবলই ভাবছি যে যুক্তি, সত্যিই গুরুত্বহীন কাউন্টারগুলি বাদ দিয়ে, "পর্যাপ্ত জায়গা থাকলে বর্ধিতকরণে নিয়ে যেতে পারি, অন্যথায় এটি ভুলে যেতে পারে"? আপনি যদি পোর্টিং কোড করেন তবে আপনি কি uint_8 এর পরিবর্তে int (4 বাইট) ব্যবহার করতে পারেন? এটি আপনার ক্ষেত্রে অনেক ক্ষেত্রে প্রতিরোধ করবে।
দুষ্টু ছেলে

1
@ পাক আপনি ঠিক বলেছেন, আমরা এটিকে 4 বাইটে পরিবর্তন করতে পারতাম, তবে বিদ্যমান সিস্টেমগুলির সাথে যোগাযোগ করার সময় এটি সামঞ্জস্যতা ভঙ্গ করবে। উদ্দেশ্যটি হ'ল কখন কোনও ত্রুটি রয়েছে এবং তাই 1 বাইট কাউন্টারটি মূলত যথেষ্ট ছিল, এবং তাই রয়েছে।
চার্লি সল্টস

উত্তর:


26

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

নিম্নলিখিত যেখানেই ব্যবহার করা যেতে পারে intবা যেখানে ব্যবহার করা যেতে পারে কোনও অভিব্যক্তিতে unsigned intব্যবহৃত হতে পারে

  • একটি বস্তু বা অভিব্যক্তি একটি পূর্ণসংখ্যা ধরনের সঙ্গে (ব্যতীত অন্য intবা unsigned int) যাদের পূর্ণসংখ্যা রূপান্তর র্যাঙ্ক কম বা পদে সমান intএবং unsigned int
  • প্রকারের একটি বিট-ফিল্ড _Bool, int ,স্বাক্ষরযুক্ত , orস্বাক্ষরবিহীন int` `

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

সুতরাং যদি কোনও ভেরিয়েবলের টাইপ থাকে uint8_tএবং মান 255 হয় তবে এতে কোনও কাস্টার বা অ্যাসাইনমেন্ট বাদে অন্য কোনও অপারেটর ব্যবহার করে প্রথমে intঅপারেশনটি সম্পাদনের আগে 255 মানের সাথে টাইপ করতে এটি রূপান্তরিত হবে । এজন্য sizeof(~i)আপনাকে 1 এর পরিবর্তে 4 দেয়।

বিভাগ 6.5.3.3 বর্ণনা করে যে পূর্ণসংখ্যা প্রচারগুলি ~অপারেটরের ক্ষেত্রে প্রযোজ্য :

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

সুতরাং একটি 32 বিট ধরে int, যদি counter8 বিটের মান থাকে তবে 0xffএটি 32 বিটের মানতে রূপান্তরিত হয় 0x000000ffএবং ~এটি প্রয়োগ করে আপনাকে দেয় 0xffffff00

সম্ভবত এটি পরিচালনা করার সহজতম উপায় হ'ল ধরণটি না জেনে এটি হ'ল মূল্যবৃদ্ধির পরে 0 হয়, এবং যদি তাই হ্রাস হয়।

if (!++counter) counter--;

স্বাক্ষরবিহীন পূর্ণসংখ্যার মোড়ক উভয় দিকেই কাজ করে, সুতরাং 0 এর মান হ্রাস আপনাকে সর্বাধিক ধনাত্মক মান দেয়।


1
if (!++counter) --counter;কমা অপারেটর ব্যবহারের চেয়ে কিছু প্রোগ্রামারদের কাছে কম অদ্ভুত হতে পারে।
এরিক পোস্টপিসিল

1
আর একটি বিকল্প হ'ল ++counter; counter -= !counter;
এরিক পোস্টপিসিল

@ এরিকপোস্টপিসিল আসলে, আমি আপনার প্রথম বিকল্পটি আরও ভাল পছন্দ করি like সম্পাদনা করা হয়েছে।
dbush

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

5
এছাড়াও, আপনি এটিকে কোনও ফাংশন করতে পারবেন না, কারণ এটি বিভিন্ন যুক্তির ধরণের জন্য আলাদাভাবে আচরণ করতে হয়। আপনাকে একটি টাইপ-জেনেরিক ম্যাক্রো ব্যবহার করতে হবে ।
ব্যবহারকারী 2357112 মনিকা

7

মধ্যে sizeof (ঝ); আপনি পরিবর্তনশীল আকার অনুরোধ আমি , তাই 1

মধ্যে যাও sizeof (~ ঝ); আপনি আপনার ক্ষেত্রে 4 এর মত প্রকাশের ধরণের আকারের জন্য অনুরোধ করেন, এটি একটি অন্তর্নিহিত


ব্যবহার করা

যদি (~ ঝ)

যদি জানেন যে আমি (একটি uint8_t সঙ্গে আপনার ক্ষেত্রে) 255 মূল্য নেই খুব পাঠযোগ্য শুধু করি

if (i != 255)

এবং আপনার একটি পোর্টেবল এবং পঠনযোগ্য কোড থাকবে


একাধিক আকারের ভেরিয়েবল রয়েছে (উদা।, Uint16_t এবং স্বাক্ষরবিহীন চর ইত্যাদি)

স্বাক্ষরবিহীন যে কোনও আকার পরিচালনা করতে:

if (i != (((uintmax_t) 2 << (sizeof(i)*CHAR_BIT-1)) - 1))

সংক্ষেপণ সময়ে অভিব্যক্তিটি অবিচ্ছিন্ন, তাই গণনা করা।

# অন্তর্ভুক্ত <limits.h> জন্য CHAR_BIT এবং #include <stdint.h> জন্য uintmax_t


3
প্রশ্নটি স্পষ্টভাবে জানিয়েছে যে তাদের মোকাবেলায় একাধিক আকার রয়েছে, তাই != 255এটি অপর্যাপ্ত।
এরিক পোস্টপিসিল

@ এরিকপোস্টপিসিল আহ হ্যাঁ, আমি এটি ভুলে গেছি, তাই "যদি (আমি! = ((1 ইউ << মাপের (আমি) * 8) - 1)))" মনে করি সবসময় স্বাক্ষরবিহীন?
ব্রুনো

1
এটি unsignedবস্তুর জন্য অপরিজ্ঞাত হবে যেহেতু পূর্ণ বস্তুর প্রস্থের শিফটগুলি সি স্ট্যান্ডার্ড দ্বারা সংজ্ঞায়িত করা হয়নি তবে এটি দিয়ে এটি স্থির করা যেতে পারে (2u << sizeof(i)*CHAR_BIT-1) - 1
এরিক পোস্টপিসিল

ওহ হ্যাঁ, চ্যার_বিট, আমার খারাপ
ব্রুনো

2
বিস্তৃত প্রকারের সুরক্ষার জন্য, কেউ ব্যবহার করতে পারে ((uintmax_t) 2 << sizeof(i)*CHAR_BIT-1) - 1
এরিক পোস্টপিসিল

5

কিছু স্বাক্ষরযুক্ত পূর্ণসংখ্যার ধরণের xপ্রদানে “ 1 টি যোগ করুন তবে সর্বাধিক উপস্থাপনযোগ্য মানের উপরে বাতা চাপুন ” প্রয়োগের জন্য এখানে বেশ কয়েকটি বিকল্প রয়েছে x:

  1. একটি যুক্ত করুন যদি কেবলমাত্র xতার ধরণের উপস্থাপনযোগ্য সর্বোচ্চ মানের চেয়ে কম হয়:

    x += x < Maximum(x);

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

  2. প্রকারের বৃহত্তম মানের সাথে তুলনা করুন:

    if (x < ((uintmax_t) 2u << sizeof x * CHAR_BIT - 1) - 1) ++x

    (এটি 2 এন গণনা করে , যেখানে এনx 2 বি 2 দ্বারা এন −1 বিট স্থানান্তরিত করে বিটের সংখ্যা । আমরা 1 এন বিট স্থানান্তরিত করার পরিবর্তে এটি করি কারণ কোনও ধরণের বিটের সংখ্যার সাথে শিফট সি দ্বারা সংজ্ঞায়িত হয় না স্ট্যান্ডার্ড। CHAR_BITম্যাক্রো কারও কারও কাছে অপরিচিত হতে পারে; এটি একটি বাইটে বিটের সংখ্যা, তাই sizeof x * CHAR_BITধরণের বিটের সংখ্যাও রয়েছে x))

    নন্দনতত্ব এবং স্পষ্টতার জন্য এটি ম্যাক্রোতে আবশ্যক:

    #define Maximum(x) (((uintmax_t) 2u << sizeof (x) * CHAR_BIT - 1) - 1)
    if (x < Maximum(x)) ++x;
  3. বৃদ্ধি xএবং সঠিক যদি এটি শূন্যে আবৃত হয় তবে একটি ব্যবহার করে if:

    if (!++x) --x; // !++x is true if ++x wraps to zero.
  4. xএক্সপ্রেশন ব্যবহার করে শূন্যে আবৃত হলে বৃদ্ধি এবং সঠিক করুন:

    ++x; x -= !x;

    এটি নামমাত্র শাখাবিহীন (কখনও কখনও পারফরম্যান্সের জন্য উপকারী) তবে সংকলক প্রয়োজনের ভিত্তিতে একটি শাখা ব্যবহার করে তবে সম্ভবত লক্ষ্য শৈলীর উপযুক্ত নির্দেশনা থাকলে শর্তহীন নির্দেশাবলীর সাহায্যে এটি উপরের মতো প্রয়োগ করতে পারে।

  5. উপরের ম্যাক্রো ব্যবহার করে একটি শাখাবিহীন বিকল্প হ'ল:

    x += 1 - x/Maximum(x);

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


1
আমি কেবল নিজেকে ম্যাক্রো ব্যবহারের প্রস্তাব দিয়ে এমন একটি উত্তর তুলে ধরতে পারি না। সি এর ইনলাইন ফাংশন রয়েছে। আপনি সেই ম্যাক্রো সংজ্ঞায় এমন কিছু করছেন না যা কোনও ইনলাইন ফাংশনের ভিতরে সহজে করা যায় না। এবং যদি আপনি ম্যাক্রো ব্যবহার করতে চলেছেন তবে নিশ্চিত হয়ে নিন যে আপনি কৌশলগতভাবে স্পষ্টতার জন্য প্রথম বন্ধনীকরণ করেছেন: অপারেটর << এর খুব কম প্রাধান্য রয়েছে। ঝাঁকুনি এই সম্পর্কে সতর্ক করে -Wshift-op-parentheses। সুসংবাদটি হ'ল, একটি অপ্টিমাইজ করা সংকলক এখানে বিভাজন তৈরি করে না , সুতরাং এটি ধীর হওয়ার বিষয়ে আপনাকে চিন্তা করতে হবে না।
কোডি গ্রে

1
@ কোডি গ্রে, আপনি যদি মনে করেন কোনও ফাংশন দিয়ে আপনি এটি করতে পারেন তবে একটি উত্তর লিখুন।
কার্স্টেন এস

2
@ কোডি গ্রে: sizeof xকোনও সি ফাংশনের অভ্যন্তরে প্রয়োগ করা যাবে না কারণ xকিছু নির্দিষ্ট ধরণের একটি প্যারামিটার (বা অন্য এক্সপ্রেশন) হতে হবে। এটি কলকারী যেভাবে যুক্তি টাইপ করে তা আকার দিতে পারে না। একটি ম্যাক্রো ক্যান।
এরিক পোস্টপিসিল

2

Stdint.h এর আগে ভেরিয়েবলের আকারগুলি সংকলক থেকে সংকলক পর্যন্ত পরিবর্তিত হতে পারে এবং সি এর প্রকৃত ভেরিয়েবল প্রকারগুলি এখনও int, দীর্ঘ, ইত্যাদি এবং এখনও তাদের আকার হিসাবে সংকলক লেখক দ্বারা সংজ্ঞায়িত করা হয়। কিছু মানক বা লক্ষ্য নির্দিষ্ট সুনির্দিষ্ট নয়। লেখক (গুলি) এর পরে দুটি বিশ্বের মানচিত্রের জন্য stdint.h তৈরি করা দরকার, এটি ud_ ম্যাপ করার জন্য stdint.h এর উদ্দেশ্য যা দীর্ঘ, সংক্ষেপে।

আপনি যদি অন্য সংকলক থেকে কোড পোর্টিং করে থাকেন এবং এটি চর, সংক্ষিপ্ত, ইনট, লং ব্যবহার করে তবে আপনাকে প্রতিটি ধরণের মাধ্যমে যেতে হবে এবং নিজের বন্দরটি নিজেই করতে হবে, এর আশেপাশের কোনও উপায় নেই। এবং হয় আপনি ভেরিয়েবলের জন্য সঠিক আকারের সাথে শেষ করেন, ঘোষণাটি পরিবর্তিত হয় তবে কোডটি লিখিত কাজ হিসাবে ....

if(~counter) counter++;

বা ... সরাসরি মাস্ক বা টাইপকাস্ট সরবরাহ করুন

if((~counter)&0xFF) counter++;
if((uint_8)(~counter)) counter++;

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

আপনি যদি পোর্টিংয়ের আগে কোডে ভেরিয়েবলের প্রকারগুলি আলাদা করতে চান এবং ভেরিয়েবল প্রকারগুলি কত আকারের হয়, তবে এটি করা ভেরিয়েবলগুলি আলাদা করুন (গ্রেপ করা সহজ হওয়া উচিত) এবং stdint.h সংজ্ঞা ব্যবহার করে তাদের ঘোষণাগুলি পরিবর্তন করুন যা আশা করি ভবিষ্যতে পরিবর্তন হবে না, এবং আপনি অবাক হবেন তবে ভুল শিরোনামগুলি কখনও কখনও ব্যবহৃত হয় এমনকি চেক লাগিয়ে দেওয়া হয় যাতে আপনি রাতে ভাল ঘুমাতে পারেন

if(sizeof(uint_8)!=1) return(FAIL);

এবং কোডিংয়ের সেই স্টাইলটি (যদি (~ কাউন্টার) কাউন্টার ++;) কাজ করে তবে বহনযোগ্যতা কামনা করার জন্য এখন এবং ভবিষ্যতে নির্দিষ্ট করে আকার সীমাবদ্ধ করার জন্য একটি মুখোশ ব্যবহার করা ভাল (এবং ঘোষণার উপর নির্ভর করে না), যখন এটি করুন কোডটি প্রথম স্থানে লেখা আছে বা কেবল বন্দরটি শেষ করুন এবং তারপরে আপনাকে অন্য কোনও দিন এটি পুনরায় পোর্ট করতে হবে না। অথবা কোডটিকে আরও পঠনযোগ্য করে তোলার জন্য যদি x <0xFF তখন বা x! = 0xFF বা এর মতো কিছু করেন তবে সংকলক এটির যে কোনও সমাধানের জন্য একই কোডে এটি অপ্টিমাইজ করতে পারে, কেবল এটিকে আরও পঠনযোগ্য এবং কম ঝুঁকিপূর্ণ করে তোলে ...

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


0
.5.৫.৩.৩ অ্যানারি পাটিগণিত অপারেটর
...
অপারেটরের ফলাফল ~তার (প্রচারিত) অপারেন্ডের বিটওয়াস পরিপূরক (অর্থাৎ, ফলাফলের প্রতিটি বিট সেট করা থাকে যদি এবং কেবল রূপান্তরিত অপারেন্ডে সংশ্লিষ্ট বিট সেট না করা থাকে) )। পূর্ণসংখ্যা প্রচারগুলি অপারেন্ডে সঞ্চালিত হয় এবং ফলাফলটি প্রচারিত ধরণের হয় । যদি প্রচারিত প্রকারটি একটি স্বাক্ষরবিহীন প্রকারের হয় তবে অভিব্যক্তিটি ~Eসেই ধরণের বিয়োগে উপস্থাপনযোগ্য সর্বাধিক মানের সমান E

সি 2011 অনলাইন খসড়া

সমস্যাটি হ'ল অপারেটরটি অপারেটর প্রয়োগ হওয়ার আগে ~প্রচার করা হচ্ছে int

দুর্ভাগ্যক্রমে, আমি মনে করি না এর থেকে সহজ উপায় আছে। লেখা

if ( counter + 1 ) counter++;

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

#define MAX_COUNTER 255
...
if ( counter < MAX_COUNTER-1 ) counter++;

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