Home > OS >  Real Applications of internal linkage in C
Real Applications of internal linkage in C

Time:09-28

This sounds like a duplicate version of What is the point of internal linkage in C and probably is. There was only one post with some code that didn't look like a practical example. C ISO draft says:

When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit.

It looks a good punctual definition for me, but I couldn't find any reasonable application of that, something like: "look this code, the internal linkage here makes a great difference to implement it". Furthermore based on the definition provided above,it looks that global variables fulfils the internal linkage duty. Could you provide some examples?

CodePudding user response:

Internal linkage is a practical way to comply with the One Definition Rule.

One might find the need to define functions or objects with plain names, like sum, or total, or collection, or any one of other common terms, more than once. In different translation units they might serve different purposes, specific purposes that are particular to that, particular, translation unit.

If only external linkage existed you'd have to make sure that the same name will not be repeated in different translation units, i.e. little_sum, big_sum, red_sum, etc... At some point this will get real old, real fast.

Internal linkage solves this problem. And unnamed namespaces effectively result in internal linkage for entire classes and templates. With an unnamed namespace: if a translation unit has a need for its own private little template, with a practical name of trampoline it can go ahead and use it, safely, without worrying about violating the ODR.

CodePudding user response:

Consider helper functions, that don't exactly need to be exposed to the outside like:

// Foo.hh
void do_something();
// Foo.cc
static void log(std::string) { /* Log into foo.log */ }
void do_something() { /* Do stuff while using log() to log info */ }
// Bar.hh
void bar();
// Bar.cc
static void log(std::string) { /* Log into bar.log */ }
void bar() { /* Do stuff while using log */ }

You can use the proper log function within two parts of your project, while avoiding multiple definition errors.

This latter part becomes very important for header only libraries, where the library might be included in multiple translation units within the same project.

Now as to a reason of using internal linkage with variables: Again you can avoid multiple definitions errors, which would be the result of code like this:

// Foo.cc
int a = 5;
// Bar.cc
int a = 5;

When compiling this the compiler will happily produce object code but the linker will not link it together.

  • Related