[libc++] Is namespace "index" a special kind of a namespace in libc++?

Hi libc++ developers,

I’m having a problem compiling the following code:

Header (index.hpp):

#ifndef INDEX_HPP_
#define INDEX_HPP_

#include

namespace index {

class Index {
public:
Index();
};

}

#endif // INDEX_HPP_

Source (index.cpp):

#include “index.hpp”

namespace index {

Index::Index() {
}

}

These are the errors I get:

index.cpp:5:1: error: use of undeclared identifier ‘Index’; did you mean ‘::index::Index’?
Index::Index() {
^~~~~
::index::Index
./index.hpp:8:7: note: ‘::index::Index’ declared here
class Index {
^
index.cpp:5:8: error: cannot define or redeclare ‘Index’ here because namespace ‘index’ does not enclose namespace ‘Index’
Index::Index() {

2 errors generated.

This is my compile command:
clang++ --stdlib=libc++ index.cpp

clang version:

clang version 5.0.0 (tags/RELEASE_500/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin

libc++ version is today's trunk

System: Linux trusty64 3.16.0-55-generic #74~14.04.1-Ubuntu SMP Tue Nov 17 10:15:59 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

If I don't include <algorithm> or if I change the name of the namespace to something other than "index", the code compiles.

Is this a libc++ bug?

Cheers,
Klemen

There is a ::index function in strings.h on some platforms that might be leaking into .

There is a ::index function in strings.h on some platforms that might be leaking into .

And I would add to this that I’ve definitely seen Clang give pretty bad diagnostics when it hits this kind of ambiguity.

John.

Looks like glibc provides it in <string.h> too if _GNU_SOURCE is defined, which it always is when compiling in C++ mode (unless explicitly undefined). :frowning:

Is it still the case that glibc requires _GNU_SOURCE to be defined in order for it to provide the symbols that C++ compilation requires? A quick test seems to show that _ISOC99_SOURCE (or sometimes _ISOC11_SOURCE) is actually sufficient. Perhaps we should provide a mode that doesn’t define _GNU_SOURCE (ideally, -std=c++XX would have that effect, but that’s probably going to break too much).

Hi Richard,

thanks replying. So if I understood correctly, undefining _GNU_SOURCE and defining _ISOC99_SOURCE instead, should be a good fix until this gets patched in libc++? :slight_smile:

Cheers,
Klemen

Hi Richard,

thanks replying. So if I understood correctly, undefining _GNU_SOURCE and
defining _ISOC99_SOURCE instead, should be a good fix until this gets
patched in libc++? :slight_smile:

There's nothing that libc++ can do about it; the 'index' function is coming
from your libc implementation. But yes, undefining _GNU_SOURCE and defining
_ISOC99_SOURCE (and maybe also _ISOC11_SOURCE) should probably work.

Thanks for your reply. When I try to build my previously posted example (index.hpp and index.cpp) with the flags “-U_GNU_SOURCE -D_ISOC99_SOURCE” it works, but when I try it on my production code, I get random errors in all sorts of places. Having tried that, is there anything else I can do, besides renaming my namespace index to something else?

Should I have rebuilt libc++ itself with those flags instead of my code?

I should note, though, using the command “clang++ index.cpp” (which uses the system’s libstdc++ 4.8) to build my previously posted example, doesn’t require me to undefine _GNU_SOURCE and define _ISOC99_SOURCE to make it compile. What does libstdc++ do differently than libc++?

Thanks again.

Thanks for your reply. When I try to build my previously posted example
(index.hpp and index.cpp) with the flags "-U_GNU_SOURCE -D_ISOC99_SOURCE"
it works, but when I try it on my production code, I get random errors in
all sorts of places. Having tried that, is there anything else I can do,
besides renaming my namespace index to something else?

Should I have rebuilt libc++ itself with those flags instead of my code?

No, you did the right thing. Most likely either your code or one of your
dependencies (maybe even libc++) depends on an extension that's disabled by
-U_GNU_SOURCE. If you can figure out which one, you should be able to
re-enable that extension with the relevant *_SOURCE macro.

I should note, though, using the command "clang++ index.cpp" (which uses
the system's libstdc++ 4.8) to build my previously posted example, doesn't
require me to undefine _GNU_SOURCE and define _ISOC99_SOURCE to make it
compile. What does libstdc++ do differently than libc++?

Its <algorithm> header presumably has a different set of #includes.