5.2.31 · D5 · HinglishC++ Programming

Question bankInline namespaces, anonymous namespaces

1,774 words8 min read↑ Read in English

5.2.31 · D5 · Coding › C++ Programming › Inline namespaces, anonymous namespaces

Traps se pehle, teen plain-word anchors taaki neeche koi term bina explanation ke na aaye:


True or false — justify karo

Anonymous namespace apne members ko internal linkage deta hai.
True. Har unnamed namespace ek unique hidden name per TU ke roop mein kaam karta hai ek implicit using ke saath, isliye koi doosra TU un members ko naam de ya link kar nahi sakta — yahi internal linkage ki definition hai.
static int x; aur namespace { int x; } file scope par variables ke liye interchangeable hain.
Effectively haan ek plain variable ke liye — dono internal linkage dete hain — lekin namespace form types, templates aur enums ke liye bhi kaam karta hai, jo static nahi kar sakta, isliye namespace ko uniform tool ke roop mein prefer karo.
Ek inline namespace apne members ko inline function ki tarah fast banata hai.
False. Same keyword hai, lekin unrelated mechanism: function par inline ek ODR/linkage hint hai; namespace par inline purely name visibility aur versioning ke baare mein hai — zero runtime effect.
lib ke andar inline namespace v2 { ... } likhna lib ke andar using namespace v2; likhne ke equivalent hai.
False. using sirf lookup ke liye names import karta hai; inline lib::T aur lib::v2::T ko template specialization ke liye same entity banata hai aur v2 ko mangled symbol mein daalta hai, jo using kabhi nahi karta.
Agar do alag libraries dono inline namespace v1 use karein, toh unke symbols silently merge ho jayenge.
False — aur yahi baat hai. v1 har mangled name ka hissa hota hai, isliye alag v1s ke against build kiye gaye objects distinct rehte hain; linker loudly fail karta hai galat code call karne ke bajaaye.
Ek anonymous namespace ko header mein daalna uske contents ko include karne wale ke liye private rakhta hai.
Technically har includer ko ek private copy milti zaroor hai — yahi bug hai. Har including TU apna alag variable/function pata hai, isliye shared-state assumptions toot jaate hain aur binary bloat ho jaata hai.
Argument-Dependent Lookup ek aisi function ko nahi dhundh sakta jo inline namespace mein ho.
False. Kyunki inline namespace ke members aisa behave karte hain jaise ek level upar declare kiye gaye hon, ADL usse "see through" karta hai: enclosing namespace ko type ka associated namespace maana jaata hai.
v1 se v2 mein migrate karne ke liye tumhe har caller ka code edit karna padega.
False. Agar v2 inline (default) namespace hai, toh jo bhi lib::process() likhta tha woh automatically aage aa jaata hai; sirf woh callers jo explicitly lib::v1::process() pin kiya tha woh purane par rehte hain.
Ek namespace ek saath named aur inline dono ho sakta hai.
True — yahi normal case hai (inline namespace v2). "Inline" aur "anonymous" independent flavors hain; versioning idiom deliberately ek named inline namespace use karta hai.

Error dhundho

namespace { struct Cache { int n; }; } jo cache.h mein rakha hai, 5 files ne include kiya.
Unnamed namespace ek .cpp mein hona chahiye, header mein nahi — 5 TUs mein se har ek ka ab apna alag Cache type aur koi file-local state hai, jisse duplication aur subtle "same name, different type" surprises hote hain.
static struct Node { int v; }; likha gaya type ko file-local banane ke liye.
static ek type ko internal linkage nahi de sakta; yeh sirf functions aur variables par apply hota hai (aur yahan toh yeh kisi declared object se attach bhi nahi hota). Iske bajaaye namespace { struct Node { int v; }; } use karo.
namespace lib {
    inline namespace v1 { void go(); }
    inline namespace v2 { void go(); }
}
Phir ek caller likhta hai lib::go();.
Do inline namespaces dono go ko lib mein leak karte hain, isliye lib::go ambiguous hai aur compile nahi hoga. Zyada se zyada ek version inline hona chahiye (current default); baaki non-inline rahein.
// a.cpp aur b.cpp dono mein, global scope par:
const char* tag = "X";
Author ne expect kiya tha ki har file apna tag rakhegi.
Global-scope non-const... actually ek namespace-scope const char* object yahan external linkage rakhta hai, isliye linker do tag symbols dekhta hai → "multiple definition." Dono ko anonymous namespace mein wrap karo taaki woh file-local aur distinct ho jayein.
lib ke andar API ko "version" karne ke liye using namespace v2; use kiya gaya, phir ek caller ne std::hash<lib::T> specialize kiya.
using lib::T aur lib::v2::T ko same entity nahi banata, isliye specialization ek alag naam target karta hai jise lookup nahi dhundh sakta. Sirf inline namespace unhe specialization aur mangling ke liye unify karta hai.
Ek header inline namespace latest { ... } declare karta hai aur .cpp isse namespace latest { ... } ke roop mein reopen karta hai (bina inline ke).
Inconsistent hai: ek baar jab namespace inline introduce ho jaaye, har reopening ko bhi inline rakhna chahiye. Mix karne se confusing/ill-formed inline-ness hoti hai aur "one default version" ki guarantee toot jaati hai.

Why questions

Mechanically, anonymous namespace cross-file collision guarantee kyun karta hai?
Compiler har TU ke liye ek unique hidden naam invent karta hai, isliye fully-qualified naam har file mein alag hota hai; do files kabhi same mangled symbol produce nahi kar sakti.
Version ko mangled symbol mein bake karna ek feature kyun maana jaata hai, bug kyun nahi?
Yeh silent ABI mismatches ko loud link errors mein badal deta hai — v1 ke against build kiya code accidentally v2 ki differently-behaving function ko call nahi kar sakta, jo API evolution ko protect karta hai.
Ek naya default version ship karne ke liye ek inline keyword move karna kaafi kyun hai?
Inline namespace woh set of names hai jo enclosing namespace mein leak hote hain; inline ko v2 se v3 par relocate karna change karta hai ki unqualified callers kaunsa version resolve karein, bina kisi caller edit ke.
Modern C++ mein static ke upar anonymous namespace prefer kyun kiya jaata hai?
Yeh uniform hai — functions, variables, types, templates, aur enums sab ek hi tarah se internal linkage paate hain — jabki static sirf functions aur variables tak pahunchta hai. Dekho static keyword (storage & linkage).
File-local state ko header mein daalna "shared" data ko quietly corrupt kyun kar deta hai?
Kyunki har including TU ek alag copy own karta hai, woh code jo ek single global counter ya cache assume karta hai woh actually kai independent copies read/write karta hai, isliye ek file mein updates doosre mein invisible hote hain.
ADL ko inline namespace ke through "see through" karne ki zaroorat kyun hai?
Taaki ns::impl mein declare kiye gaye type ke saath unqualified functions jaise draw(w) ns se use kiye ja sakein; enclosing namespace ko associated treat karna versioning ko ordinary ADL usage ke liye invisible rakhta hai.

Edge cases

Kya hoga agar tum lib::process() likho aur lib mein koi inline namespace exist hi na kare?
Tab process directly lib mein hi declare hona chahiye; koi inline namespace na hone par upar kuch leak nahi hota, isliye agar process sirf lib::v1 mein hai toh unqualified lib::process nahi mila jaayega.
Agar same anonymous-namespace name do TUs mein odr-used ho — kya yeh ODR violation hai?
Nahi. Yeh genuinely different entities hain (alag invented namespaces), isliye One Definition Rule satisfy hota hai; har ek ki exactly ek definition uske apne TU mein hoti hai.
Kya tum same TU mein anonymous namespace ko aur members add karne ke liye reopen kar sakte ho?
Haan — ek file mein kai namespace { ... } blocks sab us TU ke single unnamed namespace ko refer karte hain, isliye members expect ke mutabiq accumulate hote hain.
const-qualified namespace-scope variable ki linkage kya hoti hai, aur yeh anonymous-namespace idiom ke saath kaise interact karta hai?
Ek namespace-scope const object default mein already internal linkage rakhta hai; isse anonymous namespace mein wrap karna harmless aur consistent hai, aur non-const variables, functions, aur types ke liye still zaroori hai.
Kya inline namespace inline hone ke baad bhi apne explicit naam se resolvable rehta hai?
Haan. lib::v2::process() explicitly kaam karta rehta hai; inlining adds the unqualified lib::process() path bina qualified wala hataaye — dono ek hi entity ka naam hain.
Global (unnamed, top-level) namespace par kya hota hai agar tum ek anonymous namespace ke andar doosra anonymous namespace nest karo?
Yeh legal hai aur simply internal linkage ke andar internal linkage nest ho jaata hai; members TU-local rehte hain. Yeh rarely useful hai lekin error nahi hai.

Recall Ek line summary yaad rakhne ke liye

Anonymous = file-local identity (unique hidden name per TU → internal linkage, kabhi headers mein nahi). Inline = default-version identity (names upar leak hote hain, version mangled symbol mein bake hota hai → safe versioning ek keyword diff ke saath).