সি ফাংশনে বহিরাগত কীওয়ার্ডের প্রভাব


171

সি তে, আমি externফাংশন ঘোষণার আগে ব্যবহৃত কীওয়ার্ডটির কোনও প্রভাব লক্ষ্য করিনি । প্রথমদিকে, আমি ভেবেছিলাম যে extern int f();কোনও একক ফাইলের সংজ্ঞা দেওয়ার সময় আপনাকে ফাইলের আওতার বাইরে এটি প্রয়োগ করতে বাধ্য করে । তবে আমি যে উভয়:

extern int f();
int f() {return 0;}

এবং

extern int f() {return 0;}

জিসিসি থেকে কোনও সতর্কতা ছাড়াই ঠিকঠাক সংকলন করুন। আমি ব্যবহার করেছি gcc -Wall -ansi; এটি এমনকি //মন্তব্য গ্রহণ করবে না ।

extern ফাংশন সংজ্ঞা আগে ব্যবহার করার জন্য কোনও প্রভাব আছে ? বা এটি কার্যকারণের জন্য কোনও পার্শ্ব প্রতিক্রিয়া ছাড়াই কেবল একটি alচ্ছিক কীওয়ার্ড।

পরবর্তী ক্ষেত্রে আমি বুঝতে পারি না যে কেন স্ট্যান্ডার্ড ডিজাইনাররা অতিমাত্রায় কীওয়ার্ড সহ ব্যাকরণে লিটার বেছে নিয়েছিল।

সম্পাদনা করুন: নির্মল করার জন্য, আমি জানি সেখানে ব্যবহার এর externভেরিয়েবলের মধ্যে, কিন্তু আমি মাত্র জিজ্ঞেস করছি externমধ্যে ফাংশন


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

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

@ এড .. যদি অস্থায়ী ইন্ট foo foo.c এ একটি গ্লোবাল হয়, এবং বার.c.c এর প্রয়োজন হয় তবে বার.c.c এটি অবশ্যই বাহ্যিক হিসাবে ঘোষণা করবে। এটির সুবিধাগুলি রয়েছে। এর বাইরে, আপনাকে এমন কিছু ফাংশন ভাগ করতে হবে যা আপনি পাবলিক শিরোনামে প্রকাশ করতে চান না।
টিম পোস্ট


2
@ ব্যারি যদি কিছুটা হয় তবে অন্য প্রশ্নটি এটির একটি সদৃশ। 2009 বনাম 2012
এলাজার লাইবোভিচ

উত্তর:


138

আমাদের কাছে দুটি ফাইল রয়েছে, foo.c এবং বার।

এখানে foo.c

#include <stdio.h>

volatile unsigned int stop_now = 0;
extern void bar_function(void);

int main(void)
{
  while (1) {
     bar_function();
     stop_now = 1;
  }
  return 0;
}

এখন, এখানে বার

#include <stdio.h>

extern volatile unsigned int stop_now;

void bar_function(void)
{
   while (! stop_now) {
      printf("Hello, world!\n");
      sleep(30);
   }
}

যেমন আপনি দেখতে পাচ্ছেন, foo.c এবং bar.c এর মধ্যে আমাদের কোনও শেয়ার্ড শিরোনাম নেই, তবে বার.c.c এর সাথে লিঙ্কযুক্ত হওয়ার সময় foo.c এ ঘোষিত কিছু দরকার হয় এবং লিংকযুক্ত হওয়ার পরে foo.c বারক থেকে একটি ফাংশন প্রয়োজন।

'বাহ্যিক' ব্যবহার করে আপনি সংকলককে বলছেন যে এটি অনুসরণ করবে তা লিঙ্ক সময়ে পাওয়া যাবে (অ স্থিতিশীল); বর্তমান পাসে এটির জন্য কোনও কিছু সংরক্ষণ করবেন না কারণ এটি পরে আসবে be এক্ষেত্রে ফাংশন এবং ভেরিয়েবলগুলি সমানভাবে বিবেচিত হয়।

আপনার যদি মডিউলগুলির মধ্যে কিছু বৈশ্বিক ভাগ করা প্রয়োজন এবং এটি কোনও শিরোনামে রাখতে / আরম্ভ করতে না চান তবে এটি খুব কার্যকর।

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

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

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

আশা করি এইটি কাজ করবে :)


56
আপনার কোডটি বার_ ফাংশনের আগে বাহ্যিক ছাড়া ঠিক জরিমানা সংকলন করবে।
এলাজার লাইবোভিচ

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

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

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

1
ফাংশন ঘোষণার উপর বহিরাগত 'স্বাক্ষরবিহীন ইন' এর মতো 'ইন্ট' এর মতো অতিরিক্ত অতিরিক্ত super প্রোটোটাইপ কোনও অগ্রণী ঘোষণা না হলে 'বাহ্যিক' ব্যবহার করা ভাল অনুশীলন ... তবে কার্যটি প্রান্তের কেস না হলে এটি অবশ্যই 'বাহ্যিক' ছাড়াই শিরোনামে বাস করা উচিত। stackoverflow.com/questions/10137037/...

82

আমি যতদূর মানটি মনে করি, সমস্ত ফাংশন ঘোষণাগুলি ডিফল্টরূপে "বাহ্যিক" হিসাবে বিবেচিত হয়, সুতরাং এটি স্পষ্টভাবে নির্দিষ্ট করার দরকার নেই।

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


21
তারপরে স্ট্যান্ডার্ড ডিজাইনার হিসাবে আমি ফাংশনগুলির সাথে এক্সটার্নাল ব্যবহার করা বারণ করব , কারণ এটি ব্যাকরণে কেবল শব্দ যোগ করে।
এলাজার লেইবোভিচ

3
পিছনের সামঞ্জস্য একটি ব্যথা হতে পারে।
ম্যাথুসাম মুট

1
@ ইলজারলিবুভিচ প্রকৃতপক্ষে, এই বিশেষ ক্ষেত্রে এটি অস্বীকার করা ব্যাকরণে গোলমাল যুক্ত করবে।
অরবিট মধ্যে হালকাতা রেস

1
কিভাবে একটি শব্দ সীমিত যোগ গোলমাল আমাকে অতিক্রম করিয়া, কিন্তু আমি অনুমান এটা স্বাদ ব্যাপার আছে।
এলাজার লাইবোভিচ

এটি ফাংশনগুলির জন্য "বহিরাগত" ব্যবহারের অনুমতি দেওয়ার জন্য দরকারী, যদিও এটি অন্যান্য প্রোগ্রামারদের নির্দেশ করে যে ফাংশনটি অন্য ফাইলটিতে সংজ্ঞায়িত করা হয়েছে, বর্তমান ফাইলে নয় এবং অন্তর্ভুক্ত শিরোনামগুলির মধ্যে একটিতেও ঘোষিত হয়নি।
DimP

23

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

আমি যদি লিখি

extern int i;

কোনও সি ফাইলে ফাইল স্কোপে (কোনও ফাংশন ব্লকের বাইরে), তারপরে আপনি বলছেন "ভেরিয়েবলটি অন্য কোথাও সংজ্ঞায়িত করা যেতে পারে"।

extern int f() {return 0;}

উভয়ই হ'ল ফাংশনটির ঘোষণা এবং এফ-এর একটি সংজ্ঞা। এক্ষেত্রে সংজ্ঞাটি বাহ্যিক অংশটিকে ওভার রাইড করে।

extern int f();
int f() {return 0;}

সংজ্ঞাটি অনুসরণ করে প্রথমে একটি ঘোষণা।

externআপনি যদি একটি ফাইল স্কোপ ভেরিয়েবল ঘোষণা করতে এবং একই সাথে সংজ্ঞায়িত করতে চান তবে এর ব্যবহার ভুল। উদাহরণ স্বরূপ,

extern int i = 4;

সংকলকটির উপর নির্ভর করে একটি ত্রুটি বা সতর্কতা দেবে।

externআপনি যদি সুস্পষ্টভাবে কোনও ভেরিয়েবলের সংজ্ঞা এড়াতে চান তবে এর ব্যবহার দরকারী।

আমাকে ব্যাখ্যা করতে দাও:

ধরা যাক ফাইল এসি-তে রয়েছে:

#include "a.h"

int i = 2;

int f() { i++; return i;}

আহ ফাইলের মধ্যে রয়েছে:

extern int i;
int f(void);

এবং বিসি ফাইল রয়েছে:

#include <stdio.h>
#include "a.h"

int main(void){
    printf("%d\n", f());
    return 0;
}

শিরোনামের বাহ্যিকটি দরকারী, কারণ এটি লিঙ্ক ফেজ চলাকালীন সংকলককে বলে, "এটি একটি ঘোষণা, কোনও সংজ্ঞা নয়"। আমি যদি এসি-র রেখাটি সরিয়ে ফেলি যা আমি সংজ্ঞায়িত করে, এর জন্য স্থান বরাদ্দ করে এবং এর জন্য একটি মান নির্ধারণ করে, প্রোগ্রামটি একটি অপরিজ্ঞাত রেফারেন্স সহ সংকলন করতে ব্যর্থ হবে। এটি বিকাশকারীকে বলে যে সে একটি পরিবর্তনশীল উল্লেখ করেছে তবে এখনও এটি সংজ্ঞায়িত হয়নি। অন্যদিকে, আমি "বাহ্যিক" কীওয়ার্ডটি বাদ দিয়েছি এবং int i = 2লাইনটি সরিয়ে দিই , প্রোগ্রামটি এখনও সংকলন করে - আমি 0 এর একটি ডিফল্ট মান দিয়ে সংজ্ঞায়িত করব।

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

ফাংশনগুলির জন্য, ফাংশন ঘোষণায়, কীওয়ার্ডটি সত্যই অপ্রয়োজনীয়। ফাংশন ঘোষণার অন্তর্নিহিত সংজ্ঞা নেই।


আপনি কি int i = 2তৃতীয় অনুচ্ছেদে লাইনটি সরিয়ে ফেলতে চাইছেন ? এবং এটি বর্ণনা করা কি সঠিক int i;, সংকলকটি সেই ভেরিয়েবলের জন্য মেমরি বরাদ্দ করবে, কিন্তু দেখছি extern int i;, সংকলক স্মৃতি বরাদ্দ করবে না তবে অন্য কোথাও ভেরিয়েবলটির সন্ধান করবে?
হিমশীতল শিখা

আসলে আপনি "বাহ্যিক" কীওয়ার্ড বাদ দিলে এসি এবং বিসি-তে আই-এর নতুন সংজ্ঞা দেওয়ার কারণে প্রোগ্রামটি সংকলন করবে না (আহের কারণে)।
নেক্সট

15

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

static int g();
extern int g(); /* g has internal linkage */

extern int j(); /* j has tentative external linkage */

extern int h();
static int h(); /* error */

C99 খসড়া (n1256) থেকে এখানে সম্পর্কিত অনুচ্ছেদ রয়েছে:

.2.২.২ শনাক্তকারীদের লিঙ্কেজ

[...]

4 স্টোরেজ-ক্লাস স্পেসিফায়ারের সাথে বাহ্যিকভাবে ঘোষিত কোনও সনাক্তকারীর জন্য যেখানে সেই শনাক্তকারীর পূর্বের ঘোষণা দৃশ্যমান থাকে, ২৩) পূর্বের ঘোষণাপত্রটি অভ্যন্তরীণ বা বাহ্যিক সংযোগ নির্দিষ্ট করে দেয়, তবে পরবর্তী ঘোষণাপত্রে সনাক্তকারীটির সংযোগটি একই পূর্বের ঘোষণায় নির্দিষ্ট লিঙ্কেজ হিসাবে যদি পূর্বের কোনও ঘোষণা দৃশ্যমান না হয় বা পূর্ব ঘোষণার কোনও সংযোগ নির্দিষ্ট না করে থাকে, তবে সনাক্তকারীটির বাহ্যিক সংযোগ রয়েছে।

5 যদি কোনও ক্রমের জন্য সনাক্তকারী হিসাবে ঘোষণার কোনও স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারক না থাকে তবে এর সংযোগটি ঠিক যেমন স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারী বহির্মুখী হিসাবে ঘোষিত হয়েছিল তা নির্ধারিত হয়। যদি কোনও সামগ্রীর জন্য সনাক্তকারী হিসাবে ঘোষণার ক্ষেত্রে ফাইল স্কোপ থাকে এবং স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারক না থাকে তবে এর সংযোগটি বাহ্যিক।


এটি কি আদর্শ, বা আপনি আমাকে কেবল একটি সাধারণ সংকলকের আচরণ বলছেন? মানটির ক্ষেত্রে, আমি মানটির সাথে একটি লিঙ্কের জন্য খুশি হব be কিন্তু ধন্যবাদ!
এলাজার লাইবোভিচ

এটি স্ট্যান্ডার্ড আচরণ। সি 99 খসড়াটি এখানে উপলভ্য: < ওপেন-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf >। প্রকৃত মানটি যদিও নিখরচায় নয় (বেশিরভাগ কারণে খসড়াটি যথেষ্ট ভাল)।
নির্বিঘ্নে

1
আমি এটি কেবলমাত্র জিসিসি তে পরীক্ষা করেছি এবং এটি উভয়ই "এক্সটার্নাল ইন h (); স্ট্যাটিক ইনট h () {রিটার্ন 0;}" এবং "ইন্ট এইচ (); স্ট্যাটিক ইনট h () {রিটার্ন 0;}" একই সাথে স্বীকৃত সাবধানবাণী। এটি কি কেবল সিএন 99 এবং এএনএসআই নয়? আপনি খসড়াটির সঠিক বিভাগটি সম্পর্কে আমাকে উল্লেখ করতে পারেন, যেহেতু এটি জিসিসির পক্ষে সত্য বলে মনে হয় না।
এলাজার লাইবোভিচ

আবার পরীক্ষা করুন. আমি জিসিসি 4.0.০.১ এর সাথে একই চেষ্টা করেছি এবং এটি যেখানে হওয়া উচিত সেখানে আমি একটি ত্রুটি পেয়েছি। আপনার যদি অন্য সংকলকগুলির অ্যাক্সেস না থাকে তবে কমেউ'র অনলাইন সংকলক বা কোডপ্যাড.অর্গ.ও চেষ্টা করুন। স্ট্যান্ডার্ড পড়ুন।
নির্বিঘ্নে

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

11

ইনলাইন ফাংশনগুলির অর্থ কী তা সম্পর্কে বিশেষ বিধি রয়েছেextern । (নোট করুন যে ইনলাইন ফাংশনগুলি একটি C99 বা GNU এক্সটেনশান; সেগুলি মূল সিটিতে ছিল না they

অন-ইনলাইন ফাংশনগুলির জন্য, externএটি ডিফল্টরূপে যেমন হয় তেমন প্রয়োজন হয় না।

মনে রাখবেন যে সি ++ এর নিয়মগুলি আলাদা। উদাহরণস্বরূপ, extern "C"সি ফাংশনগুলির সি ++ ঘোষণার প্রয়োজন যা আপনি সি ++ থেকে কল করতে চলেছেন এবং সে সম্পর্কে বিভিন্ন বিধি রয়েছে inline


এখানে একমাত্র উত্তর যে উভয়ই সঠিক এবং আসলে প্রশ্নের উত্তর দেয়।
রবিনজাম

4

আইওডাব্লু, এক্সটার্নাল অপ্রয়োজনীয়, এবং কিছুই করে না।

যে কারণে, 10 বছর পরে:

কমিট অ্যাড dad১ এডডেড দেখুন , কমেন্ট বি 199d71 , কমেন্ট 5545442 (29 এপ্রিল 2019) ডেন্টন লিউDenton-L দ্বারা ( )
(দ্বারা একীভূত junio সি Hamano - gitster- মধ্যে কমিট 4aeeef3 , 13 মে 2019)

*.[ch]: externব্যবহার করে ফাংশন ঘোষণা থেকে অপসারণspatch

externফাংশন ঘোষণা থেকে সরানোর জন্য একটি চাপ দেওয়া হয়েছে ।

externফাংশন ঘোষণার জন্য " " এর কিছু উদাহরণ সরিয়ে ফেলুন যা কোকিনেলেল ধরা পড়ে।
নোট করুন যে কোকিনেলেলের সাথে __attribute__বা ভ্যারাগস প্রক্রিয়াকরণে কিছুটা অসুবিধা রয়েছে তাই কিছু externঘোষণা ভবিষ্যতের প্যাঁচে ডিল করার জন্য পিছনে থাকে।

এটি ছিল কোকিনেল প্যাচ:

  @@
    type T;
    identifier f;
    @@
    - extern
    T f(...);

এবং এটি দিয়ে চালানো হয়েছিল:

  $ git ls-files \*.{c,h} |
    grep -v ^compat/ |
    xargs spatch --sp-file contrib/coccinelle/noextern.cocci --in-place

এটি সর্বদা সহজ নয় যদিও:

দেখুন কমিট 7027f50 (04 সেপ্টেম্বর 2019) দ্বারা ডেন্টন লিউ ( Denton-L)
(দ্বারা একীভূত ডেন্টন লিউ - Denton-L- মধ্যে কমিট 7027f50 , 05 সেপ্টেম্বর 2019)

compat/*.[ch]: externস্প্যাচ ব্যবহার করে ফাংশন ঘোষণা থেকে সরান

5545442 ( *.[ch]: externস্প্যাচ, 2019-04-29, গিট ভি 2.22.0-আরসি0 ব্যবহার করে ফাংশন ঘোষণাগুলি থেকে সরিয়ে দিন) ব্যবহার করে spatchআমরা ফাংশন ঘোষণাগুলি থেকে বহিরা সরিয়ে ফেললাম তবে আমরা ইচ্ছাকৃতভাবে ফাইলগুলি বাদ দিয়েছি compat/যেহেতু কিছু সরাসরি প্রবাহ থেকে অনুলিপি করা হয়েছে এবং আমাদের এড়াতে হবে এগুলি মন্থন করা যাতে ভবিষ্যতে আপডেটগুলি ম্যানুয়ালি মেশানো সহজ হয়।

শেষ প্রতিশ্রুতিতে, আমরা ফাইলগুলি নির্ধারণ করেছি যা একটি প্রবাহ থেকে নেওয়া ফাইলগুলি যাতে আমরা সেগুলি বাদ দিতে পারি এবং বাকীটি spatchচালিয়ে যেতে পারি ।

এটি ছিল কোকিনেল প্যাচ:

@@
type T;
identifier f;
@@
- extern
  T f(...);

এবং এটি দিয়ে চালানো হয়েছিল:

$ git ls-files compat/\*\*.{c,h} |
    xargs spatch --sp-file contrib/coccinelle/noextern.cocci --in-place
$ git checkout -- \
    compat/regex/ \
    compat/inet_ntop.c \
    compat/inet_pton.c \
    compat/nedmalloc/ \
    compat/obstack.{c,h} \
    compat/poll/

কোকিনেলেলের __attribute__ভারতে এবং ভার্সে কিছু সমস্যা আছে তাই অবশিষ্ট পরিবর্তনগুলি পিছনে না রইল তা নিশ্চিত করার জন্য আমরা নিম্নলিখিতটি চালিয়েছি:

$ git ls-files compat/\*\*.{c,h} |
    xargs sed -i'' -e 's/^\(\s*\)extern \([^(]*([^*]\)/\1\2/'
$ git checkout -- \
    compat/regex/ \
    compat/inet_ntop.c \
    compat/inet_pton.c \
    compat/nedmalloc/ \
    compat/obstack.{c,h} \
    compat/poll/

দ্রষ্টব্য যে গিট ২.২৪ (Q4 2019) এর সাথে যেকোন উত্সাহী externবাদ পড়েছে।

এমিলি শেফার ( ) দ্বারা 65904b8 (30 সেপ্টেম্বর 2019) কমিট করুন দেখুন । সহায়তা করেছেন: জেফ কিং ( ) । দেখুন কমিট 8464f94 (21 সেপ্টেম্বর 2019) দ্বারা ডেন্টন লিউ ( ) । সহায়তা করেছেন: জেফ কিং ( )(দ্বারা একীভূত junio সি Hamano - - মধ্যে 59b19bc কমিট , 07 অক্টোবর 2019)nasamuffin
peff
Denton-L
peff
gitster

promisor-remote.h: externফাংশন ঘোষণা থেকে ড্রপ

এই ফাইলটি তৈরির সময়, প্রতিটি সময় নতুন ফাংশন ঘোষণার প্রচলন করা হয়েছিল, এতে একটি অন্তর্ভুক্ত ছিল extern
তবে, 5545442 থেকে শুরু করে *.[ch]: ( 2019-04-29, গিট ভি 2.22.0-আরসি0 externব্যবহার করে ফাংশন ঘোষণাপত্রগুলি সরিয়ে spatchদিন), আমরা বাহ্যিকগুলি ফাংশন ঘোষণায় ব্যবহার করতে বাধা দেওয়ার জন্য সক্রিয়ভাবে চেষ্টা করছি কারণ তারা অপ্রয়োজনীয়।

এই উদ্দীপনা externগুলি সরান ।


3

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


2

কোনও ক্রিয়াকলাপের বহিরাগত ঘোষণার অর্থ এর সংজ্ঞা সংযোগের সময় সংশ্লেষের সময় সমাধান হবে, সংকলনের সময় নয়।

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

আমি মনে করি না যে এটি করা খুব বেশি কার্যকর হবে তবে এই জাতীয় পরীক্ষাগুলি করা ভাষার সংকলক এবং লিঙ্কার কীভাবে কাজ করে সে সম্পর্কে আরও ভাল অন্তর্দৃষ্টি দেয়।


2
আইওডাব্লু, এক্সটার্নাল অপ্রয়োজনীয়, এবং কিছুই করে না। আপনি যদি সেভাবে রাখেন তবে এটি আরও পরিষ্কার হবে।
এলাজার লাইবোভিচ

@ ইলজারলিবুভিচ আমি কেবল আমাদের কোডবেসে একইরকম একটি মামলার মুখোমুখি হয়েছি এবং একই সিদ্ধান্তে এসেছি। এখানে উত্তরগুলির মাধ্যমে সমস্তগুলি আপনার এক লাইনে সংক্ষিপ্ত করা যেতে পারে। এটির ব্যবহারিক প্রভাব নেই তবে পাঠযোগ্যতার জন্য এটি দুর্দান্ত। আপনাকে অনলাইনে দেখে খুব ভাল লাগল এবং কেবল মিলিতভাবে নয় :)
আভিভ

1

এর কোনও প্রভাব নেই বলে কারণ লিংক-সময়ে লিঙ্কার বাহ্যিক সংজ্ঞাটি সমাধান করার চেষ্টা করে (আপনার ক্ষেত্রে extern int f())। এটি একই ফাইল বা অন্য কোনও ফাইলে এটি খুঁজে পাওয়া যায় না যতক্ষণ না এটি পাওয়া যায়।

আশা করি এটি আপনার প্রশ্নের উত্তর দেয়।


1
তাহলে কেন externকোনও কার্যক্রমে যোগ করার অনুমতি দিচ্ছেন ?
এলাজার লাইবোভিচ

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