ন্যূনতম চলমান মাল্টি-ফাইল স্কোপের উদাহরণ
এখানে আমি ব্যাখ্যা করেছি যে কীভাবে staticএকাধিক ফাইল জুড়ে ফাংশন সংজ্ঞাগুলির সুযোগকে প্রভাবিত করে।
এসি
#include <stdio.h>
/* Undefined behavior: already defined in main.
* Binutils 2.24 gives an error and refuses to link.
* /programming/27667277/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c
*/
/*void f() { puts("a f"); }*/
/* OK: only declared, not defined. Will use the one in main. */
void f(void);
/* OK: only visible to this file. */
static void sf() { puts("a sf"); }
void a() {
f();
sf();
}
main.c
#include <stdio.h>
void a(void);
void f() { puts("main f"); }
static void sf() { puts("main sf"); }
void m() {
f();
sf();
}
int main() {
m();
a();
return 0;
}
গিটহাব উজানের দিকে ।
সংকলন এবং চালান:
gcc -c a.c -o a.o
gcc -c main.c -o main.o
gcc -o main main.o a.o
./main
আউটপুট:
main f
main sf
main f
a sf
ব্যাখ্যা
- দুটি পৃথক ফাংশন রয়েছে
sf, প্রতিটি ফাইলের জন্য একটি
- একটি একক ভাগ করা ফাংশন আছে
f
যথারীতি স্কোপটি যত ছোট হবে তত ভাল, staticযদি আপনি পারেন তবে সর্বদা ফাংশনগুলি ঘোষণা করুন ।
সি প্রোগ্রামিংয়ে ফাইলগুলি প্রায়শই "শ্রেণি" উপস্থাপন করতে ব্যবহৃত হয় এবং staticফাংশনগুলি শ্রেণীর "ব্যক্তিগত" পদ্ধতিগুলি উপস্থাপন করে।
একটি সাধারণ সি প্যাটার্ন হ'ল thisপ্রথম "পদ্ধতি" আর্গুমেন্ট হিসাবে একটি কাঠামো পাস করা , যা মূলত হুডের নীচে সি ++ যা করে।
স্ট্যান্ডার্ড এটি সম্পর্কে কি বলে
C99 N1256 খসড়া 6.7.1 "স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারী" বলছে এটি staticএকটি "স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারী"।
6.2.2 / 3 "সনাক্তকারীদের লিঙ্কেজ" বলতে staticবোঝায় internal linkage:
যদি কোনও বস্তুর বা কোনও ফাংশনের জন্য কোনও ফাইল স্কোপ শনাক্তকারীর ঘোষণায় স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারক স্থিতিশীল থাকে, সনাক্তকারীটির অভ্যন্তরীণ সংযোগ থাকে।
এবং 6.2.2 / 2 বলেছেন যে internal linkageআমাদের উদাহরণের মতো আচরণ করে:
অনুবাদ ইউনিট এবং গ্রন্থাগারগুলির সেটগুলিতে যা একটি সম্পূর্ণ প্রোগ্রাম গঠন করে, বাহ্যিক লিঙ্কেজ সহ একটি নির্দিষ্ট সনাক্তকারীর প্রতিটি ঘোষণা একই বস্তু বা ফাংশনকে বোঝায়। একটি অনুবাদ ইউনিটের মধ্যে, অভ্যন্তরীণ লিঙ্কেজ সহ সনাক্তকারীগুলির প্রতিটি ঘোষণা একই বস্তু বা ফাংশনটিকে বোঝায়।
যেখানে "অনুবাদ ইউনিট" প্রাকপ্রসেসিংয়ের পরে উত্স ফাইল।
কীভাবে জিসিসি এটি ইএলএফ (লিনাক্স) এর জন্য প্রয়োগ করে?
সঙ্গে STB_LOCALবাঁধাই।
যদি আমরা সংকলন করি:
int f() { return 0; }
static int sf() { return 0; }
এবং এর সাথে প্রতীক টেবিলটি বিচ্ছিন্ন করুন:
readelf -s main.o
আউটপুট রয়েছে:
Num: Value Size Type Bind Vis Ndx Name
5: 000000000000000b 11 FUNC LOCAL DEFAULT 1 sf
9: 0000000000000000 11 FUNC GLOBAL DEFAULT 1 f
সুতরাং বাঁধাই তাদের মধ্যে একমাত্র উল্লেখযোগ্য পার্থক্য। Valueএটি কেবল .bssবিভাগে তাদের অফসেট , সুতরাং আমরা এটির ভিন্নতা প্রত্যাশা করি।
STB_LOCALhttp://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html এ ইএলএফ স্পেশায় নথিভুক্ত করা হয়েছে :
STB_LOCAL স্থানীয় চিহ্নগুলি তাদের সংজ্ঞা সম্বলিত অবজেক্ট ফাইলের বাইরে দৃশ্যমান নয়। একে অপরের সাথে হস্তক্ষেপ না করে একই নামের স্থানীয় চিহ্নগুলি একাধিক ফাইলে থাকতে পারে
যা প্রতিনিধিত্ব করার জন্য এটি একটি নিখুঁত পছন্দ করে তোলে static।
স্ট্যাটিক ব্যতীত ফাংশনগুলি হ'ল STB_GLOBAL, এবং চশমাটি বলে:
লিঙ্ক এডিটরটি যখন বেশ কয়েকটি স্থান পরিবর্তনযোগ্য অবজেক্ট ফাইল সংযুক্ত করে, তখন এটি একই নামের সাথে STB_GLOBAL প্রতীকগুলির একাধিক সংজ্ঞা দেয় না।
যা একাধিক অ স্থিত সংজ্ঞাতে লিঙ্ক ত্রুটির সাথে সুসংগত।
যদি আমরা এর সাহায্যে অপ্টিমাইজেশানটি ক্র্যাঙ্ক করি -O3তবে sfপ্রতীকটি পুরোপুরি প্রতীক টেবিল থেকে সরিয়ে দেওয়া হবে: এটি বাহিরের বাইরে থেকে ব্যবহার করা যাবে না। আজ কেন কোনও অপ্টিমাইজেশন নেই কেন প্রতীক টেবিলের স্থির ফাংশন রাখবেন? এগুলি কি কোনও কিছুর জন্য ব্যবহার করা যায়?
আরো দেখুন
সি ++ বেনামে নামস্থান
সি ++ তে আপনি স্ট্যাটিকের পরিবর্তে বেনামে নেমস্পেস ব্যবহার করতে চাইতে পারেন যা একইরকম প্রভাব অর্জন করে তবে প্রকারের সংজ্ঞাগুলি গোপন করে: অজ্ঞাত / বেনাম নেমস্পেস বনাম স্থির ফাংশন