LLVM CS question about anonymous namespaces

Hi all,

This is a general C++ question, but pertaining to LLVM Coding Standard.

LLVM CS requires the use of anonymous namespaces for file local class/struct definitions to restrict their visibility to that file (so we don’t get link errors when the same name is used in 2 or more translation units). In some downstream code, I have seen file local enum definitions and use of using keyword to establish a file local type alias surrounded by anonymous namespace. I wanted to check if that is really necessary. Are enums and type aliases exported in the generated object file at all to have the possibility of any conflict with enums and type aliased defined in a different translation unit?

I’m not quite following what you’re describing - could you provide an example? (I’d /guess/ the answer is “no” - it sounds a bit convoluted, but not sure)

Sure, something like:

// SomeFile.cpp

namespace {

enum class MyFlag { Default, On, Off};
using ValueVector = SmallVector<Value *>;

}

My question is whether surrounding these 2 in anonymous namespace achieves anything at all. I am not sure I see this in upstream code. I think symbols MyFlag and ValueVector are not exported in the object file so there is no need to restrict their visibility in any way (they are file local by default). Just wanted to confirm this.

Thanks

MyFlag still has linkage in this example, and like a class/struct, needs to be in an anonymous namespace - a concrete example of what makes this necessary would be in template instantiation. If you instantiate some linkage-having template foo with MyFlag and someone else does the same thing in another translation unit, they’ll collide/end up as the same function even though they might be different (perhaps the enums have different storage sizes, the enumerators mean different things/are in different orders/etc - or maybe you’re specializing the linkage-having template for MyFlag, and then the implementations could be totally different, but the linker could treat them as equivalent and replace one with the other)

For ValueVector I think that ones a technicalitiy - I believe the alias technically has linkage but it’s unobservable? So my best guess is that one is technically “better” (than having the alias at global scope) but we don’t generally do anything about it/try to enforce that in LLVM.

Interesting, thanks for clarifying. So, I guess these uses of anonymous namespaces are legit.

1 Like

My rule of thumb would be the following:
If you define something then make sure its static - but if you cant put static on it, then put it inside an anon namespace.

If you alias something, that’s fine.