0

I have been reading about declaring anonymous namespaces for achieving a lower linking-time.

However, I have read that declaring anonymous namespaces in header files are trully not recommended:

When an unnamed namespace is defined in a header file, it can lead to surprising results. Due to default internal linkage, each translation unit will define its own unique instance of members of the unnamed namespace that are ODR-used within that translation unit. This can cause unexpected results, bloat the resulting executable, or inadvertently trigger undefined behavior due to one-definition rule (ODR) violations.

The above is a quote extracted from the link below, in which there are several examples of anonymous namespaces' unexpected behaviors: https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL59-CPP.+Do+not+define+an+unnamed+namespace+in+a+header+file

So, my questions are:

The mentioned problems only applies to anonymous-namespace variables, not methods. Is that right?

Does the same problem appears when using static keyword for forcing internal linkage with variables? If so, is there any other way to achive this in a safety way?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Dan
  • 2,452
  • 20
  • 45
  • *"bloat the resulting executable"* - Applies to functions. The safe way, pardon the bluntness, is to know what you are doing when declaring things with internal linkage in a header, no matter how you declare them. – StoryTeller - Unslander Monica Mar 31 '18 at 14:29
  • 2
    If you want things to have internal linkage, perhaps you shouldn't put them in a header file at all. – Bo Persson Mar 31 '18 at 14:31
  • Yes, the same logic applies to `static` functions or variables in header files as it does to anonymous `namespace` in header files. Header files is not the right place to put things for internal linkage. – Eljay Mar 31 '18 at 14:32

1 Answers1

2

The mentioned problems only applies to anonymous-namespace variables, not methods. Is that right?

The mentionned problem happen to anything inside anonymous-namespace.

Does the same problem appears when using static keyword for forcing internal linkage with variables?

The same happens.

If so, is there any other way to achive this in a safety way?

There are not.

The ODR violation will soon or later happen if you put inside a header file which is included in different translation units any entity with internal linkage (class, variable, member function, template, etc...). You will soon have a problem if any entity with external linkage uses one of these entity with internal linkage in its definition or declaration.

Any entity declared inside an anonymous namespace, those declared static and not-extern const variables have internal linkage.

There are 2 partial solutions to what you are, supposedly, looking for:

  • Inline variables and functions can have their definitions appearing inside mutliple translation units, so it is safe to define them in header files.

  • If what your are looking for is not to make the names visibles outside of the library your are writting, define them in a private header and apply to them visibility attributes ([[gnu:visibility("hidden")]] or no __dllexprot for MSVC)

Oliv
  • 17,610
  • 1
  • 29
  • 72