সি এর লুকানো বৈশিষ্ট্য


141

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


আপনি / কেউ যদি এই প্রশ্নের সি # এবং পার্ল সংস্করণগুলিতে সেরা লুকানো বৈশিষ্ট্যগুলি বেছে নেওয়ার জন্য "প্রশ্ন" সম্পাদনা করে থাকেন তবে তা দুর্দান্ত হবে।
ডোনাল ফেলো

উত্তর:


62

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

তারপরে স্ট্যান্ডার্ড লাইব্রেরিতে লুকানো রত্ন রয়েছে যেমন qsort (), bsearch (), strpbrk (), strcspn () [দ্বিতীয়টি একটি strtok () প্রতিস্থাপন বাস্তবায়নের জন্য কার্যকর)।

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


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

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

2
@zvrba, "লাইব্রেরির রুটিনগুলি যা পাটিগণিত ওভারফ্লো পরীক্ষা করতে পারে (সমস্ত মৌলিক ক্রিয়াকলাপ)" যদি আপনি এটি যোগ করে থাকেন তবে কোনও সংখ্যক গাণিতিক ক্রিয়াকলাপের জন্য আপনাকে উল্লেখযোগ্য পারফরম্যান্সের ক্ষতি করতে হবে। ===== কেস স্টাডি ম্যাটল্যাব বিশেষভাবে সংখ্যার ওভারফ্লো আচরণকে মোড়ানো বা পরিপূর্ণ করার জন্য নিয়ন্ত্রণের বৈশিষ্ট্যটি এডিডিএস করে। যখনই ওভারফ্লো ঘটে তখন এটি একটি ব্যতিক্রম ছুঁড়ে দেয় ==> মতলব পূর্ণসংখ্যার ক্রিয়াকলাপ: খুব কম। আমার নিজস্ব উপসংহার: আমি মনে করি মতলব একটি বাধ্যতামূলক কেস স্টাডি যা এটি দেখায় যে আপনি কেন পূর্ণসংখ্যার ওভারফ্লো চেকিং চান না।
ট্রেভর বয়ড স্মিথ

15
আমি বলেছিলাম যে স্ট্যান্ডার্ডটি গাণিতিক ওভারফ্লো পরীক্ষা করার জন্য গ্রন্থাগার সহায়তা সরবরাহ করা উচিত ছিল । এখন, আপনি যদি কখনও এটি ব্যবহার না করেন তবে কোনও লাইব্রেরি রুটিন কীভাবে পারফরম্যান্স হিট করতে পারে?
zvrba

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

116

জিসিসি সংকলকটির আরও কৌশল, তবে আপনি সংস্থাপকটিতে শাখা সূচক ইঙ্গিত দিতে পারেন (লিনাক্স কার্নেলের মধ্যে সাধারণ)

#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)

দেখুন: http://kerneltrap.org/node/4705

আমি এই সম্পর্কে যা পছন্দ করি তা হ'ল এটি কিছু ফাংশনে কিছুটা এক্সপ্রেশনও যোগ করে।

void foo(int arg)
{
     if (unlikely(arg == 0)) {
           do_this();
           return;
     }
     do_that();
     ...
}

2
এই কৌশলটি দুর্দান্ত ... :) বিশেষত আপনি যে ম্যাক্রোগুলি সংজ্ঞায়িত করেছেন তা দিয়ে। :)
সূন্দর - মনিকা

77
int8_t
int16_t
int32_t
uint8_t
uint16_t
uint32_t

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

#define INT16 short
#define INT32  long

ইত্যাদি। এটি আমার চুলগুলি টেনে আনতে চায়। কেবল ফ্রেইকিং স্ট্যান্ডার্ড পূর্ণসংখ্য টাইপডিফ ব্যবহার করুন!


3
আমি তাদের C99 বা তাই মনে হয়। এগুলি প্রায় হবে তা নিশ্চিত করার মতো কোনও পোর্টেবল উপায় আমি খুঁজে পাইনি।
akauppi

3
এগুলি সি 99 এর একটি alচ্ছিক অংশ, তবে আমি এমন কোনও সংকলক বিক্রেতাদের সম্পর্কে জানি যা এটি প্রয়োগ করে না।
বেন কলিন্স 21

10
stdint.h সি 99 এ alচ্ছিক নয়, তবে সি 99 মান অনুসরণ করা স্পষ্টতই কিছু বিক্রেতাদের জন্য ( কাশি মাইক্রোসফ্ট)।
বেন কম্বি

5
@ পিট, যদি আপনি পায়খানা হতে চান: (1) এই থ্রেডটির কোনও মাইক্রোসফ্ট পণ্য নিয়ে কোনও যোগাযোগ নেই। (২) এই থ্রেডটির কখনই সি ++ এর সাথে কিছুই করার ছিল না। (3) সি ++ 97 এর মতো কোনও জিনিস নেই
বেন কলিন্স 21

5
gnud

73

কমা অপারেটরটি বহুল ব্যবহৃত হয় না। এটি অবশ্যই আপত্তিজনক হতে পারে তবে এটি খুব কার্যকরও হতে পারে। এই ব্যবহারটি সর্বাধিক সাধারণ:

for (int i=0; i<10; i++, doSomethingElse())
{
  /* whatever */
}

তবে আপনি এই অপারেটরটি যে কোনও জায়গায় ব্যবহার করতে পারেন। পালন:

int j = (printf("Assigning variable j\n"), getValueFromSomewhere());

প্রতিটি বিবৃতি মূল্যায়ন করা হয়, তবে প্রকাশের মানটি সর্বশেষ বিবৃতিতে মূল্যায়ন করা হবে।


7
সিআই এর 20 বছরের মধ্যে এটি কখনও দেখেনি!
মার্টিন বেকেট

11
সি ++ এ আপনি এটি ওভারলোডও করতে পারেন।
ওয়াউটার লিভেন্সস

6
অবশ্যই! = অবশ্যই ওভারলোডিংয়ের সাথে বিপদটি হ'ল বিল্ট ইনটি ইতিমধ্যে শূন্যতাসহ সমস্ত কিছুর ক্ষেত্রে প্রযোজ্য, তাই উপলব্ধ ওভারলোডের অভাবে সংকলন করতে কখনই ব্যর্থ হবে না। অর্থাৎ প্রোগ্রামারকে অনেক দড়ি দেয়।
অ্যারন

লুপের অভ্যন্তরীণ সি এর সাথে কাজ করবে না: এটি একটি সি ++ ইমপ্রোভমেন্ট। "," একই অপারেশন (i = 0, j = 10; i <j; j--, i ++) এর মতো?
আইফ

63

কাঠামো শূন্যে আরম্ভ করা হচ্ছে

struct mystruct a = {0};

এটি সমস্ত স্টাকচার উপাদানগুলিকে শূন্য করবে।


2
তবে প্যাডিং শূন্য হয় না, যদি থাকে তবে।
মাইকেজ

2
@ সিমন, না যদি এটি কাঠামোতে অ-ইন্টিগ্রাল টাইপ থাকে তবে এটি সংজ্ঞায়িত আচরণ করে না। ফ্লোট / ডাবলের স্মৃতিতে 0 দিয়ে মেমসেটটি শূন্য হবে যখন আপনি ভাসা / ডাবলকে ব্যাখ্যা করবেন (ভাসা / ডাবল উদ্দেশ্য হিসাবে এমনভাবে নকশা করা হয়েছে)।
ট্রেভর বয়েড স্মিথ

6
@ অ্যান্ড্রু: memset/ callocকরুন "সমস্ত বাইট শূন্য" (অর্থাত্ শারীরিক জিরো), যা প্রকৃতপক্ষে সমস্ত ধরণের জন্য সংজ্ঞায়িত নয়। যথাযথ যৌক্তিক শূন্য মান সহ সবকিছু{ 0 } অন্তর্নির্মিত করার গ্যারান্টিযুক্ত । উদাহরণস্বরূপ, প্রদত্ত প্ল্যাটফর্মের নাল-মানটি হলেও পয়েন্টারগুলি তাদের যথাযথ নাল মানগুলি পাওয়ার জন্য গ্যারান্টিযুক্ত । 0xBAADFOOD
এএনটি

1
@ এনভিএল: আপনি যখন শারীরিক শূন্য পাবেন তখন যখন আপনি কেবলমাত্র শক্তভাবে অবজেক্টের দ্বারা দখলকৃত সমস্ত মেমরি অল-বিট-শূন্য স্থিতিতে সেট করেন। এটিই হয় memset( 0দ্বিতীয় যুক্তি হিসাবে)। আপনি উত্স কোডে অবজেক্টটিতে (বা ) সূচনা / নির্ধারণ করার সময় আপনি যৌক্তিক শূন্য পাবেন । এই দুই ধরণের জিরো অগত্যা একই ফল দেয় না। পয়েন্টার সহ উদাহরণ হিসাবে। আপনি যখন কোনও পয়েন্টারে করেন, আপনি একটি পয়েন্টার পান। তবে আপনি যখন কোনও পয়েন্টারকে অর্পণ করেন, আপনি নাল পয়েন্টার মান পাবেন যা শারীরিক স্তরে বা অন্য যে কোনও কিছু হতে পারে । 0{ 0 }memset0x000000xBAADF00D
এএনটি

3
@ এনভিএল: ঠিক আছে, বাস্তবে পার্থক্যটি প্রায়শই ধারণাগত। তবে তত্ত্বগতভাবে, কার্যত যে কোনও ধরণের এটি থাকতে পারে। উদাহরণস্বরূপ double,। সাধারণত এটি আইইইই -754 স্ট্যান্ডার্ড অনুযায়ী বাস্তবায়িত হয়, যেখানে লজিকাল শূন্য এবং শারীরিক শূন্য একই হয়। তবে আইইইই -754 ভাষার প্রয়োজন হয় না। সুতরাং এটি ঘটতে পারে যখন আপনি double d = 0;(লজিকাল শূন্য) করেন, শারীরিকভাবে মেমরির কিছু বিট দখল dকরা শূন্য হবে না।
এএনটি

52

বহু চরিত্রের ধ্রুবক:

int x = 'ABCD';

এটি সেট xকরে 0x41424344(বা 0x44434241, স্থাপত্যের উপর নির্ভর করে)।

সম্পাদনা: এই কৌশলটি পোর্টেবল নয়, বিশেষত যদি আপনি ইনটকে সিরিয়াল করেন। তবে স্ব-ডকুমেন্টিং এনামগুলি তৈরি করতে এটি অত্যন্ত কার্যকর হতে পারে। যেমন

enum state {
    stopped = 'STOP',
    running = 'RUN!',
    waiting = 'WAIT',
};

আপনি যদি কোনও কাঁচা মেমরির ডাম্পের দিকে তাকিয়ে থাকেন এবং কোনও এনামের সন্ধান না করেই এটির মূল্য নির্ধারণ করা প্রয়োজন এটি এটিকে আরও সহজ করে তোলে।


আমি নিশ্চিত যে এটি কোনও বহনযোগ্য নির্মাণ নয়। বহু-চরিত্রের ধ্রুবক তৈরির ফলাফলটি বাস্তবায়ন-সংজ্ঞায়িত।
মার্ক বেসে

8
"বহনযোগ্য নয়" মন্তব্যগুলি পুরোপুরি মিস করে। এটি INT_MAX ব্যবহারের জন্য একটি প্রোগ্রামের সমালোচনা করার মতো, কারণ INT_MAX "পোর্টেবল নয়" :) এই বৈশিষ্ট্যটি যেমন প্রয়োজন তেমন বহনযোগ্য। মাল্টি-চর ধ্রুবক একটি অত্যন্ত কার্যকর বৈশিষ্ট্য যা অনন্য পূর্ণসংখ্যার আইডি তৈরির জন্য পাঠযোগ্য উপায় সরবরাহ করে।
এন্টি

1
@ ক্রিস লুটজ - আমি পুরোপুরি নিশ্চিত যে পিছনে থাকা কমাটি কে ও আর-তে ফিরে গেছে। এটি দ্বিতীয় সংস্করণে বর্ণিত (1988)।
ফেরুক্সিও

1
@ ফারুচ্চিও: আপনি অবশ্যই সামগ্রিক সূচনাদর্শী তালিকার পিছনে থাকা কমা সম্পর্কে চিন্তা করছেন। এনাম ঘোষণাপত্রের পিছনে কমা হিসাবে - এটি সাম্প্রতিক সংযোজন, সি 99।
এন্টি

3
আপনি 'হ্যাং' বা '
বিএসওড

44

আমি কখনই বিট ফিল্ড ব্যবহার করিনি তবে এগুলি অতি নিম্ন-স্তরের স্টাফের জন্য দুর্দান্ত।

struct cat {
    unsigned int legs:3;  // 3 bits for legs (0-4 fit in 3 bits)
    unsigned int lives:4; // 4 bits for lives (0-9 fit in 4 bits)
    // ...
};

cat make_cat()
{
    cat kitty;
    kitty.legs = 4;
    kitty.lives = 9;
    return kitty;
}

এর অর্থ এটি sizeof(cat)যতটা ছোট হতে পারে sizeof(char)


হারুন এবং লেপ্পির সমন্বিত মন্তব্যগুলি , ধন্যবাদ ছেলেরা।


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

5
বিটফিল্ডগুলি পোর্টেবল নয় - সংকলকটি নির্দ্বিধায় চয়ন করতে পারে, উদাহরণস্বরূপ, পাগুলি সর্বাধিক উল্লেখযোগ্য 3 বিট বা কমপক্ষে উল্লেখযোগ্য 3 বিট বরাদ্দ করা হবে কিনা।
zvrba

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

26
বিটফিল্ডগুলি প্রকৃতপক্ষে বহনযোগ্য যেমন আপনি তাদের কাঠামোগত উপাদান হিসাবে বিবেচনা করেন না, "পূর্ণসংখ্যার টুকরা"। আকার, অবস্থান নয়, একটি এম্বেডড সিস্টেমে সীমাবদ্ধ মেমরির বিষয়গুলি যেমন প্রতিটি বিট মূল্যবান ... তবে আজকের বেশিরভাগ কোডার এটি মনে রাখতে খুব কম বয়সী। :-)
অ্যাডাম লিস

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

37

সি এর একটি স্ট্যান্ডার্ড রয়েছে তবে সমস্ত সি সংকলক সম্পূর্ণরূপে মেনে চলে না (আমি কোনও সম্পূর্ণ কমপ্লায়েন্ট সি 99 সংকলক এখনও দেখিনি!)।

এটি বলেছিল, যে কৌশলগুলি আমি পছন্দ করি সেগুলি হ'ল প্ল্যাটফর্মগুলি জুড়ে অ-সুস্পষ্ট এবং পোর্টেবল যা তারা সি সিমেটিকের উপর নির্ভর করে। তারা সাধারণত ম্যাক্রো বা বিট পাটিগণিত সম্পর্কে হয়।

উদাহরণস্বরূপ: অস্থায়ী ভেরিয়েবল ব্যবহার না করে দুটি স্বাক্ষরবিহীন পূর্ণসংখ্যার অদলবদল:

...
a ^= b ; b ^= a; a ^=b;
...

বা সীমাবদ্ধ রাষ্ট্রীয় মেশিনগুলির প্রতিনিধিত্ব করতে "বিস্তৃত সি":

FSM {
  STATE(x) {
    ...
    NEXTSTATE(y);
  }

  STATE(y) {
    ...
    if (x == 0) 
      NEXTSTATE(y);
    else 
      NEXTSTATE(x);
  }
}

যা নিম্নলিখিত ম্যাক্রোগুলির সাহায্যে অর্জন করা যেতে পারে:

#define FSM
#define STATE(x)      s_##x :
#define NEXTSTATE(x)  goto s_##x

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


18
সি চেইন সমর্থন করে, তাই আপনি একটি ^ = বি ^ = এ ^ = বি করতে পারেন;
ওজে।

4
কড়া কথায় বলতে গেলে, রাষ্ট্রীয় উদাহরণটি প্রিপ্রসেসরগুলির একটি টিক, এবং সি ভাষা নয় - পরবর্তীটি ছাড়াই পূর্বের ব্যবহার সম্ভব।
গ্রেগ হুইটফিল্ড

15
ওজে: আসলে আপনি যা পরামর্শ দিচ্ছেন তা হ'ল সিকোয়েন্স পয়েন্ট নিয়মের কারণে অপরিবর্তিত আচরণ। এটি বেশিরভাগ সংকলকগুলিতে কাজ করতে পারে তবে সঠিক বা পোর্টেবল নয়।
ইভান তেরান

5
নিখরচায় নিবন্ধের ক্ষেত্রে জোর অদলবদল কম কার্যকর হতে পারে। কোনও শালীন অপ্টিমাইজার অস্থায়ী ভেরিয়েবলটিকে একটি রেজিস্টার হিসাবে তৈরি করে। বাস্তবায়নের উপর নির্ভর করে (এবং সমান্তরালতার সমর্থনের প্রয়োজন) সোয়াপটি একটি নিবন্ধের পরিবর্তে প্রকৃত মেমরি ব্যবহার করতে পারে (যা একই হবে)।
পল ডি ভ্রিজে

27
: দয়া করে কখনও আসলে এটা করো না en.wikipedia.org/wiki/...
খ্রিস্টান Oudard

37

ডাফের ডিভাইসের মতো ইন্টারলেসিং স্ট্রাকচারগুলি :

strncpy(to, from, count)
char *to, *from;
int count;
{
    int n = (count + 7) / 8;
    switch (count % 8) {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
               } while (--n > 0);
    }
}

29
@ কমসউবি, ডাফের ডিভাইস ব্যবহার করা যে কেউ হ'ল একটি স্ক্রিপ্ট কিডি যিনি ডাফের ডিভাইসটি দেখেছেন এবং ভেবেছিলেন যে তারা ডাফের ডিভাইসটি ব্যবহার করলে তাদের কোডটি 1337 লাগবে। (১) ডফের ডিভাইস আধুনিক প্রসেসরের উপর কোনও কার্যকারিতা বাড়ানোর প্রস্তাব দেয় না কারণ আধুনিক প্রসেসরের শূন্য-ওভারহেড-লুপিং রয়েছে। অন্য কথায় এটি কোডের একটি অপ্রচলিত টুকরা। (২) এমনকি আপনার প্রসেসরের শূন্য-ওভারহেড-লুপিং অফার না করা সত্ত্বেও এতে সম্ভবত এসএসই / অ্যালটিভিক / ভেক্টর-প্রসেসিংয়ের মতো কিছু থাকবে যা আপনি ম্যাকপি ব্যবহার করার সময় আপনার ডাফের ডিভাইসটিকে লজ্জায় ফেলবে। (৩.) আমি কী উল্লেখ করেছি যে অন্যটি মেমকি () ডুফ করা কার্যকর নয়?
ট্রেভর বয়ড স্মিথ

2
@কমসবি, দয়া করে আমার প্রথম মৃত্যু ( en.wikedia.org/wiki/… ) এর সাথে দেখা করুন
ট্রেভর বয়েড স্মিথ

12
@ ট্রেভর: তাই কেবল স্ক্রিপ্ট কিডিজ প্রোগ্রাম 8051 এবং পিআইসি মাইক্রোকন্ট্রোলার, তাই না?
এসএফ

6
@ ট্র্যাভর বয়েড স্মিথ: ডাফের ডিভাইসটি পুরানো মনে হলেও এটি এখনও একটি curতিহাসিক কৌতূহল, যা কমসবভির উত্তরকে বৈধ করেছে। যাইহোক, উইকিপিডিয়াকে উদ্ধৃত করে: "সংস্করণ ৪.০-এ XFree86 সার্ভার থেকে যখন ডাফের ডিভাইসের অসংখ্য উদাহরণ সরিয়ে দেওয়া হয়েছিল, তখন কার্য সম্পাদনের ক্ষেত্রে একটি উল্লেখযোগ্য উন্নতি হয়েছিল।" ...
প্যারাসেবল

2
সিম্বিয়ানে, আমরা একবারে দ্রুত পিক্সেল কোডিংয়ের জন্য বিভিন্ন লুপগুলি মূল্যায়ন করেছি; ডাবের ডিভাইস, এসেম্বলারের মধ্যে, দ্রুততম ছিল। সুতরাং আজও এটি আপনার স্মার্টফোনে মূলধারার এআরএম কোরগুলির সাথে প্রাসঙ্গিকতা রয়েছে।
উইল

33

আমি মনোনীত প্রারম্ভিকগুলির খুব পছন্দ, সি 99 এ যুক্ত (এবং দীর্ঘ সময়ের জন্য জিসিসিতে সমর্থিত):

#define FOO 16
#define BAR 3

myStructType_t myStuff[] = {
    [FOO] = { foo1, foo2, foo3 },
    [BAR] = { bar1, bar2, bar3 },
    ...

অ্যারের সূচনাটি আর অবস্থান নির্ভর নয়। আপনি যদি এফইও বা বারের মান পরিবর্তন করেন তবে অ্যারে সূচনা স্বয়ংক্রিয়ভাবে তাদের নতুন মানের সাথে মিলবে correspond


সিনট্যাক্স জিসিসি দীর্ঘ সময় ধরে সমর্থন করেছে যা স্ট্যান্ডার্ড সি 99 সিনট্যাক্সের মতো নয়।
মার্ক বেকার

28

C99 এর কিছু দুর্দান্ত-অর্ডার কাঠামোর সূচনা রয়েছে।

struct foo{
  int x;
  int y;
  char* name;
};

void main(){
  struct foo f = { .y = 23, .name = "awesome", .x = -38 };
}


27

বেনামে কাঠামো এবং অ্যারেগুলি আমার পছন্দসই। (সিএফ। http://www.run.montefiore.ulg.ac.be/~martin/resources/kung-f00.html )

setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, (int[]){1}, sizeof(int));

অথবা

void myFunction(type* values) {
    while(*values) x=*values++;
}
myFunction((type[]){val1,val2,val3,val4,0});

এমনকি এটি লিঙ্কযুক্ত তালিকাগুলি প্রশমিত করতে ব্যবহার করা যেতে পারে ...


3
এই বৈশিষ্ট্যটিকে সাধারণত "যৌগিক আক্ষরিক" বলা হয়। নামবিহীন (বা নামবিহীন) স্ট্রাকচারগুলি নেস্টেড স্ট্রাকচারকে মনোনীত করে যার কোনও সদস্যের নাম নেই।
কলন্ডো

আমার জিসিসির মতে, "আইএসও সি 90 যৌগিক আক্ষরিক নিষিদ্ধ করেছে"।
jmtd

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

24

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

int my_printf (void *my_object, const char *my_format, ...)
            __attribute__ ((format (printf, 2, 3)));

24

আমি যখন প্রথম দেখলাম তখন যে "লুকানো" বৈশিষ্ট্যটি আমাকে "হতবাক" করেছিল তা হ'ল প্রিন্টএফ সম্পর্কে। এই বৈশিষ্ট্যটি আপনাকে তাদের বিন্যাসের ফর্ম্যাট নির্দিষ্টকরণের জন্য ভেরিয়েবলগুলি ব্যবহার করতে দেয়। কোডটি সন্ধান করুন, আপনি আরও ভাল দেখতে পাবেন:

#include <stdio.h>

int main() {
    int a = 3;
    float b = 6.412355;
    printf("%.*f\n",a,b);
    return 0;
}

* চরিত্রটি এই প্রভাবটি অর্জন করে।


24

ঠিক আছে ... আমি মনে করি সি ভাষার অন্যতম শক্তিশালী বিষয় হল এর বহনযোগ্যতা এবং মানকতা, সুতরাং যখনই আমি বর্তমানে ব্যবহার করছি প্রয়োগকরণের মধ্যে যখন কিছু "লুকানো কৌশল" পাওয়া যায়, তখন আমি এটি ব্যবহার করার চেষ্টা করি না কারণ আমি নিজের চেষ্টা করার চেষ্টা করি সি কোড হিসাবে মান এবং সম্ভব হিসাবে পোর্টেবল।


কিন্তু বাস্তবে, কত ঘন ঘন আপনার কোডটি অন্য সংকলক দিয়ে সংকলন করতে হবে?
জো ডি

3
@ জো ডি যদি এটির উইন্ডোজ / ওএসএক্স / লিনাক্সের মতো ক্রস প্ল্যাটফর্মের প্রকল্প, সম্ভবত কিছুটা, এবং x86 বনাম x86_64 এবং ইত্যাদির মতো আলাদা
খিলানও রয়েছে

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


16

ধ্রুব স্ট্রিং কনক্যাটেনেশন

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

আমার বর্তমান কোডটিতে আমার কেস ব্যবহার করুন: আমার কাছে একটি আছে #define PATH "/some/path/" কোডটিতে থাকা কেসটি একটি কনফিগারেশন ফাইল রয়েছে (সত্যই এটি মেকফিল দ্বারা সেট করা আছে)। এখন আমি রিসোর্সগুলি খুলতে ফাইলের নাম সহ পুরো পথটি তৈরি করতে চাই। এটি কেবল এখানে যায়:

fd = open(PATH "/file", flags);

ভয়ঙ্কর পরিবর্তে, তবে খুব সাধারণ:

char buffer[256];
snprintf(buffer, 256, "%s/file", PATH);
fd = open(buffer, flags);

লক্ষ্য করুন যে সাধারণ ভয়াবহ সমাধানটি হ'ল:

  • দীর্ঘ হিসাবে তিনবার
  • পড়া খুব কম সহজ
  • অনেক ধীর
  • এটিতে কম পাওয়ারফুল একটি স্বেচ্ছাসেবী বাফার আকারের সীমাতে সেট করে (তবে ধ্রুব স্ট্রিং কনটেন্টেশন ছাড়া এটি এড়াতে আপনাকে আরও দীর্ঘ কোড ব্যবহার করতে হবে)।
  • আরও স্ট্যাক স্পেস ব্যবহার করুন

1
নোংরা `\` ব্যবহার না করে একাধিক উত্স লাইনে স্ট্রিং ধ্রুবককে বিভক্ত করাও দরকারী `
ডলম্যান

15

ঠিক আছে, আমি এটি কখনই ব্যবহার করি নি, এবং আমি নিশ্চিত হয়েও জানি না যে আমি এটির আগে কারও কাছে পরামর্শ দিয়েছি কিনা, তবে আমার মনে হয় এই প্রশ্নটি সাইমন টাথামের সহ-রুটিন কৌশল সম্পর্কে উল্লেখ না করেই অসম্পূর্ণ হবে


12

অ্যারে বা এনামগুলি শুরু করার সময়, আপনি প্রাথমিকের তালিকার শেষ আইটেমের পরে কমা রাখতে পারেন। উদাহরণ:

int x[] = { 1, 2, 3, };

enum foo { bar, baz, boom, };

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


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

এনামস সি 99 হতে পারে। অ্যারে ইনিশিয়েলাইজার এবং ট্রেলিং কমা হ'ল কে অ্যান্ড আর।
ফেরুকসিও

সমতল এনামগুলি সিএফ ৮ এ ছিল, আফাইক AI কমপক্ষে তারা প্রায় যুগে যুগে ছিল।
এক্সটিএল

12

স্ট্রাক্ট অ্যাসাইনমেন্টটি দুর্দান্ত। অনেক লোক বুঝতে পারে না যে স্ট্রাক্টগুলিও খুব মূল্যবান এবং এগুলি চারপাশে নির্ধারিত করা যেতে পারে, ব্যবহার করার দরকার নেইmemcpy() , যখন কোনও সরল অ্যাসাইনমেন্ট ট্রিকটি করে তখন ।

উদাহরণস্বরূপ, কিছু কাল্পনিক 2D গ্রাফিক্স গ্রন্থাগার বিবেচনা করুন, এটি কোনও (পূর্ণসংখ্যা) স্ক্রিন সমন্বয় উপস্থাপনের জন্য কোনও ধরণের সংজ্ঞা দিতে পারে:

typedef struct {
   int x;
   int y;
} Point;

এখন, আপনি এমন কাজগুলি করেন যা "ভুল" বলে মনে হতে পারে, যেমন একটি ফাংশন লিখুন যা ফাংশন আর্গুমেন্ট থেকে শুরু করে একটি বিন্দু তৈরি করে, এবং এটিকে ফেরত দেয়:

Point point_new(int x, int y)
{
  Point p;
  p.x = x;
  p.y = y;
  return p;
}

এটি নিরাপদ, যতক্ষণ না (অবশ্যই) স্ট্রাক্ট অ্যাসাইনমেন্ট ব্যবহার করে মান দ্বারা অনুলিপি করা হয়:

Point origin;
origin = point_new(0, 0);

এই পদ্ধতিতে আপনি বেশ পরিষ্কার এবং অবজেক্ট-ওরিয়েন্টেড-ইশ কোড লিখতে পারেন, সবগুলি সাধারণ স্ট্যান্ডার্ড সিতে in


4
অবশ্যই, এইভাবে বড় বড় স্ট্রাকগুলি পেরিয়ে যাওয়ার পারফরম্যান্সের প্রভাব রয়েছে; এটি প্রায়শই দরকারী (এবং আসলে এমন কিছু যা লোকেরা বুঝতে পারে না যে আপনি কী করতে পারেন) তবে আপনাকে পয়েন্টারগুলি উত্তীর্ণ করা ভাল কিনা তা বিবেচনা করা উচিত।
মার্ক বাকের

1
অবশ্যই, থাকতে পারে। এটি সংকলকটির পক্ষে ব্যবহার সনাক্তকরণ এবং এটি অনুকূলকরণের পক্ষে যথেষ্ট সম্ভব।
বিনোদন

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

সংকলক বিশ্বব্যাপী অপ্টিমাইজেশন না করতে পারলে বাই-রেফারেন্সির সাথে রূপান্তরিত এই মানটি রূপান্তরকে অনুকূল করতে পারে না।
ব্লেসরব্লেড

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

10

অদ্ভুত ভেক্টর সূচক:

int v[100]; int index = 10; 
/* v[index] it's the same thing as index[v] */

4
এটি আরও ভাল ... চর সি = 2 ["হ্যালো"]; (c == 'l' এর পরে)।
yrp

5
আপনি যখন ভি [সূচক] == * (ভি + সূচক) এবং সূচী [v] ​​== * (সূচক + ভি) বিবেচনা করছেন তখন এত বিস্ময়কর নয়
ফেরুঁচিও

17
দয়া করে আমাকে বলুন আপনি আসলে এই "সর্বদা" ব্যবহার করেন না, যেমন প্রশ্ন জিজ্ঞাসা করে!
ট্রেকে

9

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

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

সি কোড ভঙ্গকারী বিভিন্ন কৌশলগুলির মধ্যে রয়েছে:

  1. সংকলক কীভাবে মেমরিতে স্ট্রাক্ট আউট করে তার উপর নির্ভর করে।
  2. পরিণতি সম্পর্কে অনুমানপূর্ণসংখ্যার / ফ্লোটগুলির সম্পর্কে ।
  3. ফাংশন এবিআই-তে অনুমান।
  4. স্ট্যাক ফ্রেমগুলি যে দিকে বাড়ায় সেদিকে অনুমান।
  5. বিবৃতিতে ফাঁসির আদেশ সম্পর্কে অনুমান।
  6. ফাংশন আর্গুমেন্টে বিবৃতি কার্যকর করার আদেশ সম্পর্কে অনুমান।
  7. সংক্ষিপ্ত, অভ্যন্তরীণ, দীর্ঘ, ভাসমান এবং দ্বৈত প্রকারের বিট আকার বা যথার্থ সম্পর্কে অনুমান।

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


এর বেশিরভাগ সমাধানের জন্য, এই অনুমানগুলি আপনার প্ল্যাটফর্মের বৈশিষ্ট্যের উপর নির্ভরশীল করুন এবং প্রতিটি প্ল্যাটফর্মকে তার নিজস্ব শিরোনামে বর্ণনা করুন। অর্ডার এক্সিকিউশন একটি ব্যতিক্রম - কখনও তার উপর নির্ভর করবেন না; অন্যান্য ধারণাগুলিতে, প্রতিটি প্ল্যাটফর্মের একটি নির্ভরযোগ্য সিদ্ধান্ত নেওয়া দরকার।
ব্লেসরব্লেড

2
@ ব্লাইসারব্ল্যাড, আরও ভাল, আপনার অনুমানগুলি নথিভুক্ত করার জন্য সংকলন-কালীন দৃser়তাগুলি ব্যবহার করুন যাতে এমন একটি প্ল্যাটফর্ম যেখানে সংকলনটি লঙ্ঘিত হয় তা সংকলন ব্যর্থ করে দেয়।
আরবের্টেইগ

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

ফাংশন এবিআই চেকগুলি একটি পরীক্ষা স্যুট দ্বারা পরিচালনা করা উচিত।
ডলম্যান

9

Sscanf ব্যবহার করার সময় আপনি কোথায় পড়তে হবে তা জানতে% n ব্যবহার করতে পারেন:

sscanf ( string, "%d%n", &number, &length );
string += length;

স্পষ্টতই, আপনি অন্য উত্তর যুক্ত করতে পারবেন না, সুতরাং আমি এখানে একটি দ্বিতীয় যুক্ত করব, আপনি "&&" এবং "||" ব্যবহার করতে পারেন শর্ত হিসাবে:

#include <stdio.h>
#include <stdlib.h>

int main()
{
   1 || puts("Hello\n");
   0 || puts("Hi\n");
   1 && puts("ROFL\n");
   0 && puts("LOL\n");

   exit( 0 );
}

এই কোডটি আউটপুট দেবে:

ওহে
rofl

8

কোডটিতে ব্রেক পয়েন্ট সেট করতে INT (3) ব্যবহার করা আমার সর্বকালের প্রিয়


3
আমি এটি পোর্টেবল মনে করি না। এটি x86 এ কাজ করবে, তবে অন্যান্য প্ল্যাটফর্মগুলির কী হবে?
ক্রিশ্চিয়ান সিউপিতু

1
আমার কোনও ধারণা নেই - আপনার এটি সম্পর্কে একটি প্রশ্ন পোস্ট করা উচিত
ডরর হেল্পার

2
এটি একটি ভাল কৌশল এবং এটি এক্স 86 নির্দিষ্ট (যদিও অন্যান্য প্ল্যাটফর্মগুলিতে সম্ভবত একই জাতীয় কৌশল রয়েছে)। তবে এটি সি এর বৈশিষ্ট্য নয় এটি নির্ভর করে অ-মানক সি এক্সটেনশন বা লাইব্রেরি কলগুলির উপর।
ফেরুঁচিও

1
জিসিসিতে __builtin_trap এবং MSVC __debugbreak এর জন্য রয়েছে যা কোনও সমর্থিত আর্কিটেকচারে কাজ করবে।
এক্সেল Gneiting

8

আমার সি এর প্রিয় "লুকানো" বৈশিষ্ট্যটি হ'ল স্ট্যাকটিতে আবার লিখতে প্রিন্টফের% n ব্যবহার। সাধারণত প্রিন্টফ স্ট্যাট থেকে প্যারামিটারের মানগুলি ফর্ম্যাট স্ট্রিংয়ের উপর ভিত্তি করে পপ করে তবে% n সেগুলি আবার লিখতে পারে।

বিভাগটি এখানে দেখুন 3.4.2 । প্রচুর দুষ্টু দুর্বলতার দিকে নিয়ে যেতে পারে।


লিঙ্কটি আর কাজ করছে না, বাস্তবে মনে হয় সাইটটি কাজ করছে না। আপনি অন্য লিঙ্ক প্রদান করতে পারেন?
thequark

@ থেকার্ক: "ফর্ম্যাট স্ট্রিং দুর্বলতা" সম্পর্কিত যে কোনও নিবন্ধে এর কিছু তথ্য থাকবে .. (উদাহরণস্বরূপ crypto.stanford.edu/cs155/papers/formatstring-1.2.pdf ) .. তবে ক্ষেত্রের প্রকৃতির কারণে, সুরক্ষা ওয়েবসাইটগুলি নিজেরাই কিছুটা ঝাপটায় এবং বাস্তব শিক্ষাগত নিবন্ধগুলি কার্যকর করা কার্যকর হয় (বাস্তবায়নের সাথে)।
শ্রীধর আইয়ার

8

এনামগুলি ব্যবহার করে সংকলন-সময় অনুমান-পরীক্ষা করা: বোকা উদাহরণ, তবে কম্পাইল-টাইম কনফিগারযোগ্য ধ্রুবক সহ লাইব্রেরিগুলির জন্য সত্যই কার্যকর হতে পারে।

#define D 1
#define DD 2

enum CompileTimeCheck
{
    MAKE_SURE_DD_IS_TWICE_D = 1/(2*(D) == (DD)),
    MAKE_SURE_DD_IS_POW2    = 1/((((DD) - 1) & (DD)) == 0)
};

2
+1 ঝরঝরে। আমি মাইক্রোসফ্ট থেকে কমপ্লেয়ারএসার্ট ম্যাক্রো ব্যবহার করতাম, তবে আপনারটিও খারাপ নয়। ( #define CompilerAssert(exp) extern char _CompilerAssert[(exp)?1:-1])
প্যাট্রিক Schlüter

1
আমি গণনা পদ্ধতি পছন্দ করি। আমি আগে যে পদ্ধতিটি ব্যবহার করেছি তা ডেড কোড অপসারণের সুবিধা নিয়েছিল: "যদি (কিছু_আবাদ) {শূন্য হয়ে যায় BLORG_IS_WOOZLED (বাতিল); BLORG_IS_WOOZLED (); link" যা লিঙ্ক সময় পর্যন্ত ত্রুটি করেনি, যদিও এটি অনুমতি দেওয়ার সুযোগ দেয় নি প্রোগ্রামার ত্রুটি বার্তার মাধ্যমে জানেন যে ব্লগারটি woozled ছিল।
সুপারক্যাট

8

জিসিসি (সি) এর কিছু মজাদার বৈশিষ্ট্য রয়েছে যা আপনি সক্ষম করতে পারবেন যেমন নেস্টেড ফাংশন ডিক্লেয়ারেশন এবং?: অপারেটরের a: b ফর্ম যা কোনও মিথ্যা না হলে একটি ফেরত দেয়?


8

আমি সম্প্রতি 0 বিটফিল্ড আবিষ্কার করেছি।

struct {
  int    a:3;
  int    b:2;
  int     :0;
  int    c:4;
  int    d:3;
};

যা একটি লেআউট দেবে

000aaabb 0ccccddd

এর পরিবর্তে: 0;

0000aaab bccccddd

0 প্রস্থের ক্ষেত্রটি জানিয়েছে যে নিম্নলিখিত বিটফিল্ডগুলি পরবর্তী পরমাণু সত্তা ( char) এ সেট করা উচিত


7

C99- স্টাইলের পরিবর্তনশীল আর্গুমেন্ট ম্যাক্রোস, ওরফে

#define ERR(name, fmt, ...)   fprintf(stderr, "ERROR " #name ": " fmt "\n", \
                                  __VAR_ARGS__)

যা ব্যবহার করা হবে

ERR(errCantOpen, "File %s cannot be opened", filename);

আমি এখানে স্ট্রিংাইজ অপারেটর এবং স্ট্রিং ধ্রুবক কনটেন্টেশন, অন্যান্য বৈশিষ্ট্যগুলিও সত্যিই পছন্দ করি।


ভিএআরজিএসে আপনার একটি অতিরিক্ত 'আর' রয়েছে ।
ব্লেসরব্লেড

6

পরিবর্তনশীল আকারের স্বয়ংক্রিয় ভেরিয়েবলগুলি কিছু ক্ষেত্রে কার্যকর। এগুলিকে iCC99 এ যুক্ত করা হয়েছিল এবং দীর্ঘ সময় ধরে জিসিসিতে সমর্থন করা হয়েছে।

void foo(uint32_t extraPadding) {
    uint8_t commBuffer[sizeof(myProtocol_t) + extraPadding];

আপনি স্থির-আকারের প্রোটোকল শিরোনাম প্লাস ভেরিয়েবল সাইজের ডেটার জন্য স্ট্যাকের স্ট্যাকের একটি বাফার দিয়ে শেষ করতে পারেন। আপনি বরাদ্দ () দিয়ে একই প্রভাব পেতে পারেন তবে এই বাক্য গঠনটি আরও কমপ্যাক্ট।

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


টার্গেট প্ল্যাটফর্মে কোনও বাইট / চর ঠিক 8 বিট প্রশস্ত না হলে এটি কি সঠিকভাবে কাজ করবে? আমি জানি, এই কেসগুলি বিরল, কিন্তু এখনও ... :)
স্টেফান202
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.