যদি কেবল ম্যাক্রোটিকে ইতিমধ্যে সংজ্ঞায়িত না করা হয় তবে কেন এটি সংজ্ঞায়িত করবেন?


93

আমাদের সি কোড বেস জুড়ে, আমি প্রতিটি ম্যাক্রো নিম্নলিখিত উপায়ে সংজ্ঞায়িত দেখতে পেলাম:

#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS                   0.2f
#endif

#ifndef BEEPTRIM_ROLL_RATE_DEGPS
#define BEEPTRIM_ROLL_RATE_DEGPS                    0.2f
#endif

#ifndef FORCETRIMRELEASE_HOLD_TIME_MS
#define FORCETRIMRELEASE_HOLD_TIME_MS               1000.0f
#endif

#ifndef TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS       50.0f
#endif

এগুলি কেবল ম্যাক্রো সংজ্ঞায়িত করার পরিবর্তে এই সংজ্ঞায়িত চেকগুলি করার যৌক্তিকতা কী?

#define BEEPTRIM_PITCH_RATE_DEGPS                   0.2f
#define BEEPTRIM_ROLL_RATE_DEGPS                    0.2f
#define FORCETRIMRELEASE_HOLD_TIME_MS               1000.0f
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS       50.0f

ওয়েবে কোথাও এই অনুশীলনটির ব্যাখ্যা দেওয়া আমি পাই না।


6
কোডের অন্য কোথাও কনস্ট্যান্ট পরিবর্তন করা এইভাবে কাজ করার গ্যারান্টিযুক্ত। যদি অন্য কোথাও কেউ those ম্যাক্রোগুলির মধ্যে একটির সংজ্ঞা দেয়, তারা যখন এই ফাইলটিকে বিশ্লেষণ করে তখন প্রিপ্রসেসর দ্বারা ওভাররাইট করা হবে না।
এনজো ফারবার

8
এটি ডব্লিউইটি ডিজাইনের নীতিমালার একটি উদাহরণ
স্টার্ক

একটি উদাহরণ সহ একটি উত্তর পোস্ট করুন, এটি সংকলন চেষ্টা করুন।
এনজো ফেরবার

উত্তর:


141

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

gcc -DMACRONAME=value

হেডার ফাইলের সংজ্ঞাগুলি ডিফল্ট হিসাবে ব্যবহৃত হয়।


51

আমি মন্তব্যে যেমন বলেছি, এই পরিস্থিতিটি কল্পনা করুন:

foo.h

#define FOO  4

Defs.h

#ifndef FOO
#define FOO 6
#endif

#ifndef BAR
#define BAR 4
#endif

বার

#include "foo.h"
#include "defs.h"

#include <stdio.h>

int main(void)
{
    printf("%d%d", FOO, BAR);
    return 0;
}

ছাপবে 44

তবে শর্তসাপেক্ষে ifndefনা থাকলে ফলাফলটি ম্যাক্রো পুনঃনির্ধারণের সংকলন সতর্কতা ছিল এবং এটি মুদ্রণ করবে 64

$ gcc -o bar bar.c
In file included from bar.c:2:0:
defs.h:1:0: warning: "FOO" redefined [enabled by default]
 #define FOO 6
 ^
In file included from bar.c:1:0:
foo.h:1:0: note: this is the location of the previous definition
 #define FOO 4
 ^

4
এটি সংকলক-নির্দিষ্ট। পুনরায় সংজ্ঞাটি "একই" না হওয়া পর্যন্ত কোনও অবজেক্টের মতো ম্যাক্রোর পুনরায় সংজ্ঞা দেওয়া (এটির জন্য আরও প্রযুক্তিগত নির্দিষ্টকরণ রয়েছে, তবে এটি এখানে গুরুত্বপূর্ণ নয়)। অবৈধ কোডটির জন্য ডায়াগনস্টিক প্রয়োজন হয় এবং ডায়াগনস্টিক জারি করে (এখানে একটি সতর্কতা দেওয়া হয়), সংকলক বাস্তবায়ন-সুনির্দিষ্ট ফলাফল সহ কোডটি সংকলন সহ কিছু করতে মুক্ত free
পিট বেকার

7
আপনি একই ম্যাক্রো জন্য defs পরস্পরবিরোধী করে থাকেন, না হবে বরং অধিকাংশ ক্ষেত্রে সর্তকবার্তা পান? নিঃশব্দে প্রথম সংজ্ঞাটি ব্যবহার করার পরিবর্তে (কারণ দ্বিতীয়টি ifdefনতুন ব্যাখ্যাটি এড়াতে একটি ব্যবহার করে )।
পিটার কর্ডস

@ পিটারকর্ডস বেশিরভাগ ক্ষেত্রে #infdefএস এর অধীনে সংজ্ঞাগুলি "ফ্যালব্যাক" বা "ডিফল্ট" মান হিসাবে ব্যবহৃত হয়। মূলত, "ব্যবহারকারী এটি কনফিগার করে থাকলে, ঠিক আছে not না হলে, একটি ডিফল্ট মান ব্যবহার করুন use"
অ্যাঞ্জিউ আর

@Angew: ঠিক আছে, তাই যদি আপনি কিছু আছে #definesএকটি লাইব্রেরি হেডারের মধ্যে যে লাইব্রেরির ABI- র অংশ, আপনি উচিত না তাদের মধ্যে মোড়ানো #ifndef। (বা আরও ভাল, একটি ব্যবহার করুন enum)। আমি কেবল এটি পরিষ্কার করতে চেয়েছিলাম যে #ifndefকেবল তখনই উপযুক্ত যখন একটি সংকলনের ইউনিটে কোনও কিছুর জন্য কাস্টম সংজ্ঞা থাকলেও অন্যটি ঠিক নয়। যদি a.cশিরোনামকে আলাদা অর্ডারে অন্তর্ভুক্ত করা হয় তবে b.cতারা বিভিন্ন সংজ্ঞা পেতে পারে max(a,b)এবং এর মধ্যে একটি সংজ্ঞাটি ভেঙে যেতে পারে max(i++, x)তবে অন্যটি কোনও জিএনইউ স্টেটমেন্ট-এক্সপ্রেশনে অস্থায়ী ব্যবহার করতে পারে। তবুও অন্তত বিভ্রান্ত!
পিটার কর্ডস

@ পিটারকর্ডস আমি এই ক্ষেত্রে যা করতে চাই তা হল#ifdef FOO #error FOO already defined! #endif #define FOO x
কোল জনসন

17

আমি প্রসঙ্গটি জানি না তবে ব্যবহারকারীর সেই ম্যাক্রো সংজ্ঞা দ্বারা নির্ধারিত মানগুলিকে ওভাররাইড করার জন্য প্রাপ্যতা দিতে ব্যবহার করা যেতে পারে। যদি ব্যবহারকারী স্পষ্টভাবে those ম্যাক্রোর যে কোনওটির জন্য আলাদা মান নির্ধারণ করে তবে এটি এখানে ব্যবহৃত মানগুলির পরিবর্তে ব্যবহৃত হবে।

উদাহরণস্বরূপ g ++ এ আপনি -Dসংকলনের সময় পতাকাটি ম্যাক্রোতে মান পাস করতে ব্যবহার করতে পারেন ।


14

এটি করা হয়েছে যাতে শিরোনাম ফাইলের ব্যবহারকারী তার / তার কোড থেকে বা সংকলকের -D পতাকা থেকে সংজ্ঞাগুলি ওভাররাইড করতে পারে।


7

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


2

আপনি এমন একটি ফ্রেমওয়ার্ক / লাইব্রেরি সম্পর্কে ভাবতে পারেন যা ব্যবহারকারীকে একটি ডিফল্ট প্রাকसेट দেয় যা ব্যবহারকারীকে সংকলন করতে এবং এটিতে কাজ করতে দেয়। এই সংজ্ঞায়িতগুলি বিভিন্ন ফাইলগুলিতে ছড়িয়ে পড়ে এবং চূড়ান্ত ব্যবহারকারীর পরামর্শ দেওয়া হয় যে এটির কনফিগার ফাইলটি যেখানে সে এর মানগুলি কনফিগার করতে পারে include যদি ব্যবহারকারী কিছু ভুলে যায় তবে সিস্টেমটি প্রিসেটটির কারণে কাজ চালিয়ে যেতে পারে।


1

ব্যবহার

#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS                   0.2f
#endif

কমান্ড লাইন আর্গুমেন্ট (জিসিসি / ক্ল্যাং / ভিএস) ব্যবহার করে ব্যবহারকারীকে ম্যাক্রোর মান নির্ধারণ করতে দেয় -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f

আরও একটি গুরুত্বপূর্ণ কারণ রয়েছে। প্রিপ্রোসেসর ম্যাক্রোটিকে ভিন্নভাবে সংজ্ঞায়িত করা একটি ত্রুটি। অন্য এসও প্রশ্নের এই উত্তরটি দেখুন । #ifndefচেক ব্যতীত , -DBEEPTRIM_PITCH_RATE_DEGPS=0.3fসংকলক অনুরোধে কমান্ড লাইন আর্গুমেন্ট হিসাবে ব্যবহৃত হলে সংকলকটির একটি ত্রুটি তৈরি করা উচিত ।

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