এই উত্স কোডটি একটি স্ট্রিং সিটিতে স্যুইচ করছে এটি কীভাবে এটি করে?


106

আমি কিছু এমুলেটর কোডটি পড়ছি এবং আমি সত্যিই অদ্ভুত কিছুকে মোকাবিলা করেছি:

switch (reg){
    case 'eax':
    /* and so on*/
}

এটা কিভাবে সম্ভব? আমি ভেবেছিলাম আপনি কেবল switchঅবিচ্ছেদ্য প্রকারের উপরই পারেন। কিছু ম্যাক্রো কৌতুক চলছে?


29
এটি স্ট্রিং নয় 'eax'এবং এটি ধ্রুবক পূর্ণসংখ্যার মান গণনা করে
P__J__

12
একক উদ্ধৃতি, দ্বিগুণ নয়। একটি চরিত্র ধ্রুবক হিসাবে প্রচার করা হয় int, তাই এটি আইনী। তবে, একটি বহু-চরিত্রের ধ্রুবকের মান প্রয়োগ-সংজ্ঞায়িত, সুতরাং কোডটি অন্য সংকলকটিতে প্রত্যাশার মতো কাজ করতে পারে না। উদাহরণস্বরূপ, eaxহতে পারে 0x65, 0x656178, 0x65617800, 0x786165, 0x6165, নাকি অন্য কিছু।
ডেভিসল

2
@ ডেভিস্লোর: ভেরিয়েবলের নাম দেওয়া হয়েছে "রেগ", এবং এ্যাক্সটি একটি এক্স ৮ register register রেজিস্ট্রার হিসাবে, আমি অনুমান করব যে বাস্তবায়ন-সংজ্ঞায়িত আচরণটি ঠিক হওয়ার উদ্দেশ্যে করা হয়েছিল, কারণ কোডটিতে এটি যে কোনও জায়গায় ব্যবহার করা হয়েছে একই রকম। শুধু যতদিন 'eax' != 'ebx', অবশ্যই, তাই এটি শুধুমাত্র আপনার এক বা উদাহরণ দুটি ব্যর্থ। যদিও কোথাও কোথাও এমন কিছু কোড থাকতে পারে যা কার্যকরভাবে ধরে নেওয়া *(int*)("eax") == 'eax'হয় এবং তাই আপনার বেশিরভাগ উদাহরণকে ব্যর্থ করে।
স্টিভ জেসপ

2
@ স্টিভ জেসোপ আপনার বক্তব্যের সাথে আমি দ্বিমত পোষণ করি না, তবে আসল বিপদটি রয়েছে যে কেউ একই সংস্থার জন্য এমনকি আলাদা সংকলকটিতে কোডটি সংকলন করতে এবং ভিন্ন আচরণ পেতে চেষ্টা করতে পারে। উদাহরণস্বরূপ, 'eax'সমান 'ebx'বা এর সাথে তুলনা করতে পারে 'ax', এবং স্যুইচ বিবৃতিটি যেমন ইচ্ছা তেমন কাজ করবে না।
ডেভিস্লোর

1
আপনি যদি আমাদের দেখেন / রেগের ডেটা টাইপ দেখাতেন তবে সেই রহস্যের সমস্তটি দ্রুত তাড়িয়ে দেওয়া হত।
ths

উত্তর:


146

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

প্রোগ্রামের পাঠযোগ্যতা অর্জনের জন্য, বুদ্ধিমান বিকাশকারী বাস্তবায়ন সংজ্ঞায়িত আচরণটি ব্যবহার করছেন'eax'হয় না একটি স্ট্রিং, কিন্তু একটি বহু-চরিত্র ধ্রুবক । চারপাশে একক উদ্ধৃতি অক্ষর খুব সাবধানে নোট করুন eax। সম্ভবত এটি আপনাকে intআপনার ক্ষেত্রে এমন একটি উপহার দিচ্ছে যা চরিত্রের সংমিশ্রণের সাথে অনন্য। (প্রায়শই প্রতিটি চরিত্র 32 বিটের মধ্যে 8 বিট দখল করে থাকে int)। আর সবাই আপনি যা করতে পারেন জানেন switchএকটি অন int!

অবশেষে, একটি স্ট্যান্ডার্ড রেফারেন্স:

সি 99 স্ট্যান্ডার্ড বলেছেন:

6.4.4.4p10: "একটি পূর্ণসংখ্যার অক্ষরের মান ধ্রুবক একাধিক অক্ষর (উদাহরণস্বরূপ, 'আব') ধারণ করে, বা একটি অক্ষর বা পালানো ক্রম রয়েছে যা একক বাইট প্রয়োগের অক্ষরকে মানচিত্র করে না, প্রয়োগকরণ-সংজ্ঞায়িত হয়। "


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

7
@ জাস্টিন এটি করতে পারার সময় এটি যথেষ্ট বিকৃত হবে। যদি উত্তরটি সম্ভবত সবচেয়ে সম্ভবত পরামর্শ দেয় তবে এটি না করে, পরবর্তী সম্ভাব্যতা সম্ভবত এটি প্রথম চরিত্রটি ব্যবহার করে এবং বাকিগুলি উপেক্ষা করে।
বার্মার

5
@ জ্যানলিন্যাক্স আমি ইতিবাচক নই, তবে আমি বিশ্বাস করি যে বৈশিষ্ট্যটি ইউনিকোড এবং অন্যান্য এমবিসিএস মানকে দীর্ঘস্থায়ী করে। "ম্যাজিক নম্বর" যা মেমরি ডাম্পগুলিতে পাঠ্যের মতো দেখায় এবং আরআইএফএফ-স্টাইলের ফাইল-ফর্ম্যাট-অংশ আইডি হ'ল আমি প্রথম অ্যাপ্লিকেশন সম্পর্কে অবগত aware
রাসেল বোরোগোভ

16
@ jpmc26 এটি পূর্বনির্ধারিত আচরণ নয়, এটি বাস্তবায়ন-সংজ্ঞায়িত। তাই সংকলক ডকুমেন্টেশনে অসুরদের উল্লেখ না করা পর্যন্ত আপনার নাক নিরাপদ।
বার্মার

7
@ জ্যানলিনেক্স: আমি ভয় পেয়েছি যে মূল অভিপ্রায়টি ইউনিকোড, ইউটিএফ -8 এবং যে কোনও মাল্টবাইট চরিত্রের এনকোডিংটি প্রায় 20 বছরের মধ্যে পূর্বাভাস দেয়। বহু-চরিত্রের ধ্রুবকটি 2, 3 বা 4 বাইট (বাইট এবং ইনট আকারের উপর নির্ভর করে) এর প্রতিনিধিত্বকারী গোষ্ঠীগুলি প্রকাশ করার জন্য একটি সহজ উপায় ছিল। বাস্তবায়ন এবং আর্কিটেকচার জুড়ে অসঙ্গতিগুলি কমিটিটিকে বাস্তবায়ন সংজ্ঞায়িত হিসাবে ঘোষণা করতে নেতৃত্ব দেয় , যার অর্থ এবং 'ab'থেকে এর মান গণনা করার কোনও বহনযোগ্য উপায় নেই । 'a''b'
chqrlie

45

সি স্ট্যান্ডার্ড অনুযায়ী (6.8.4.2 স্যুইচ বিবৃতি)

3 প্রতিটি কেস লেবেলের প্রকাশটি একটি পূর্ণসংখ্যার ধ্রুবক প্রকাশ হতে হবে ...

এবং (6.6 ধ্রুবক প্রকাশ)

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

এখন কি 'eax'?

সি স্ট্যান্ডার্ড (6.4.4.4 অক্ষর ধ্রুবক)

2 একটি পূর্ণসংখ্যার অক্ষর ধ্রুবক হ'ল 'এক্স' এর মতো একক-কোটায় আবদ্ধ এক বা একাধিক মাল্টিবাইট অক্ষরের ক্রম ...

তাই 'eax'একই বিভাগের অনুচ্ছেদ 10 অনুযায়ী একটি পূর্ণসংখ্যা চরিত্র ধ্রুবক

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

সুতরাং প্রথম উল্লিখিত উক্তি অনুসারে এটি একটি পূর্ণসংখ্যার ধ্রুবক অভিব্যক্তির অপারেন্ড হতে পারে যা কেস লেবেল হিসাবে ব্যবহৃত হতে পারে।

মনোযোগ দিন যে একটি অক্ষর ধ্রুবক (একক উদ্ধৃতিতে আবদ্ধ) টাইপ রয়েছে intএবং স্ট্রিং আক্ষরিক (ডাবল উদ্ধৃতিতে অক্ষরগুলির ক্রম) এর মতো নয় যা অক্ষরের অ্যারেগুলির একটি ধরণের রয়েছে।


12

যেমন অন্যান্য বলেছেন, এটি একটি int ধ্রুবক এবং এর আসল মান বাস্তবায়ন-সংজ্ঞায়িত।

আমি ধরে নিলাম বাকী কোডটি দেখতে কিছুটা দেখতে একরকম দেখাচ্ছে

if (SOMETHING)
    reg='eax';
...
switch (reg){
    case 'eax':
    /* and so on*/
}

আপনি নিশ্চিত হতে পারেন যে প্রথম অংশে 'ইক্স' এর দ্বিতীয় অংশে 'ইএক্স' এর সমান মূল্য রয়েছে, তাই এটি সমস্ত কার্যকর হয়, তাই না? ... ভুল

একটি মন্তব্যে @ ডেভিস্লার 'ইক্স' এর জন্য কিছু সম্ভাব্য মান তালিকাভুক্ত করেছে:

... 0x65, 0x656178, 0x65617800, 0x786165, 0x6165, নাকি অন্য কিছু

প্রথম সম্ভাব্য মান লক্ষ্য করুন? এটি ঠিক 'e', অন্য দুটি চরিত্রকে উপেক্ষা করে। সমস্যাটি হ'ল প্রোগ্রামটি সম্ভবত ব্যবহার করে 'eax', 'ebx'ইত্যাদি। এই সমস্ত ধ্রুবকের যদি 'e'আপনার সমাপ্তির সমান মান থাকে তবে

switch (reg){
    case 'e':
       ...
    case 'e':
       ...
    ...
}

এটি খুব ভাল দেখাচ্ছে না, তাই না?

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

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

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


1
কিছু রূপ ছাড়া অন্য কিছু assert('eax' != 'ebx'); //if this fails you can't compile the code because...আছে যে
নির্মাণটি

6
একই মানযুক্ত দুটি কেস লেবেল একটি সীমাবদ্ধতা লঙ্ঘন (6.8.4.2p3: "... একই স্যুইচ স্টেটমেন্টে ধ্রুবক ক্ষেত্রে দু'জনের কোনওটিরই রূপান্তর হওয়ার পরে একই মান হবে না"), যতক্ষণ না সমস্ত কোড থাকে এই ধ্রুবকগুলির মানগুলি অস্বচ্ছ হিসাবে বিবেচনা করে, এটি কাজ করে বা সংকলনে ব্যর্থ হওয়ার গ্যারান্টিযুক্ত।
zwol

সবচেয়ে খারাপ দিকটি হ'ল দরিদ্র সহকর্মী অন্য সংকলকটিতে সংকলন সম্ভবত কোনও সংকলন-সময় ত্রুটি দেখতে পাবে না (ints স্যুইচ করা ভাল); পরিবর্তে, রান-টাইম ত্রুটিগুলি
কাটবে

1

কোড টুকরাটি একটি historicalতিহাসিক বিজোড়তা ব্যবহার করে যার নাম মাল্টি-ক্যারেক্টার ক্যারেক্টার কনস্ট্যান্ট , এটি মাল্টি-চরস হিসাবেও পরিচিত ।

'eax' একটি পূর্ণসংখ্যা ধ্রুবক যার মান বাস্তবায়ন সংজ্ঞায়িত।

এখানে মাল্টি-চরগুলিতে একটি আকর্ষণীয় পৃষ্ঠা রয়েছে এবং সেগুলি কীভাবে ব্যবহার করা যেতে পারে তবে তা করা উচিত নয়:

http://www.zipcon.net/~swhite/docs/computers/languages/c_multi-char_const.html


রিয়ারভিউ আয়নাতে আরও দূরে ফিরে তাকানোর জন্য, এখানে কীভাবে ডেনিস রিচি দ্বারা মূল পুরানো দিনগুলি ( https://www.bell-labs.com/usr/dmr/www/cman.pdf ) নির্দিষ্ট চরিত্রের ধ্রুবক থেকে শুরু করা হয়েছে ।

২.৩.২ চরিত্রের ধ্রুবক

একটি অক্ষর ধ্রুবক 1 বা 2 অক্ষর একক উদ্ধৃতি '' ''' এ আবদ্ধ । একটি চরিত্রের ধ্রুবকটির মধ্যে একটি একক উদ্ধৃতি অবশ্যই ব্যাক-স্ল্যাশ '' \'এর আগে হওয়া উচিত । কিছু অ-গ্রাফিক অক্ষর এবং '' \'' নিজেই নিম্নলিখিত টেবিল অনুসারে পালাতে পারে:

    BS \b
    NL \n
    CR \r
    HT \t
    ddd \ddd
    \ \\

এস্কেপ '' \ddd'' ব্যাকস্ল্যাশকে অনুসরণ করে 1, 2, বা 3 টি অষ্টাল অঙ্ক করে যা পছন্দসই অক্ষরের মান নির্দিষ্ট করতে নেওয়া হয়। এই নির্মাণের একটি বিশেষ কেস ''\0 '' (কোনও অঙ্কের পরে নয়) যা নাল চরিত্রকে নির্দেশ করে।

চরিত্রের ধ্রুবকগুলি হুবহু পূর্ণসংখ্যার মতো আচরণ করে (বিশেষত, চরিত্রের ধরণের বস্তুর মতো নয়)। পিডিপি -11 এর ঠিকানা কাঠামোর সাথে সামঞ্জস্য রেখে, দৈর্ঘ্য 1 এর একটি ধ্রুবক ধ্রুবকটিতে নিম্ন-অর্ডার বাইটে প্রদত্ত চরিত্রের কোড এবং হাই-অর্ডার বাইটে 0 থাকে; দৈর্ঘ্য 2 এর একটি অক্ষরের ধ্রুবকটিতে নিম্ন বাইটে প্রথম অক্ষরের এবং উচ্চ-আদেশ বাইটে দ্বিতীয় অক্ষরের জন্য কোড থাকে। একাধিক চরিত্রযুক্ত চরিত্রের ধ্রুবকগুলি সহজাতভাবে মেশিন-নির্ভর এবং এড়ানো উচিত avoided

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

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