New issue 195 by jmccaskey: common.h should not have "using namespace std;"
http://code.google.com/p/protobuf/issues/detail?id=195
I have a project I'm considering using protocol buffers for, but this
project doesn't currently use the standard c++ container classes or
algorithms. In fact we have some name collisions with the std namespace,
so in the few places we do use it we must always fully qualify names with
std::.
In testing out Protocol Buffers for our project we found that
google/protobuf/stubs/common.h which is included by the generated .pb.h
files ends up using the std namespace which then affects lots of our
downstream code negatively.
I've locally removed the using directive and added it to each .cpp instead,
fixing up the .h's to fully qualify names with std::. Seems like it would
be best practice to remove the using directive from common.h in the
official build though instead of assuming everyone wants to have the std
namespace automatically used in their projects. We'd love to see that
happen so merging new versions won't be a nightmare for us in the future if
we go with Protocol Buffers in our project.
"using namespace std;" appears *inside* the google::protobuf namespace, so
it
shouldn't affect you. We do *not* add any new symbols to the global
namespace, except
for "google".
Are you seeing something different?
Yes, although the using statement is inside your own namespace it appears
that at
least in Visual C++ 2005 the encapsulation is leaky and having used the
namespace can
affect other code in the global name space. Maybe this is a Visual C++
bug, it does
seem to be violating scope rules for the using directive somehow. Even if
it is
Visual C++ specific though, what if my application code wanted to use the
google::protobuf name space but not std? Having that also automatically
cause using
of std still seems undesirable.
Below is a simple test program that reproduces the issue directly just by
including
the common.h header. You'll notice I define a swap function directly in
the global
namespace, and it ends up causing ambiguity with the std::swap function.
If the
"using namespace std;" is removed from common.h this problem disappears.
The compilation errors will be:
1>Compiling...
1>test.cpp
1>c:\users\jmccaskey\documents\visual studio
2005\projects\test\test\test.cpp(21) :
error C2668: 'swap' : ambiguous call to overloaded function
1> c:\users\jmccaskey\documents\visual studio
2005\projects\test\test\test.cpp(8): could be 'void swap<int>(T &,T &)'
1> with
1> [
1> T=int
1> ]
1> c:\program files (x86)\microsoft visual studio
8\vc\include\utility(16): or
'void std::swap<int>(_Ty &,_Ty &)'
1> with
1> [
1> _Ty=int
1> ]
1> while trying to match the argument list '(int, int)'
// test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "google/protobuf/stubs/common.h"
template< class T >
void swap( T &a, T &b )
{
T tmp = a;
a = b;
b = tmp;
}
int _tmain(int argc, _TCHAR* argv[])
{
int one = 1;
int two = 2;
swap( one, two );
return 0;
}
Ok, it looks like this *is* a Visual C++ bug. I can simplify my test
program down to
the following and the errors still occur and the using namespace std does
appear to
leak out of it's proper scope. I can't reproduce the same behavior with
gcc on osx.
I'll go look for possible VC++ hotfixes that may address the issue. Still
might be
nice if this could be avoided for VC++ users.
// test.cpp : Defines the entry point for the console application.
//
#include <string>
namespace google {
namespace protobuf {
using namespace std;
namespace internal {
template <bool>
struct CompileAssert {
};
} // namespace internal
/me is increasingly in favor of disallowing all use of using namespace *
in his own code, even inside of other namespaces.
Ok, and one final follow up. I didn't find any hotfixes for VC++ for this,
but moving
the "using namespace std;" to occur right before the closing of the
protobuf namespace
in common.h avoids the bug. This still lets the using apply across almost
all of the
protobuf codebase except common.h itself, and I only had to then change 4
instances of
string to be std::string in common.h itself. That's an easy enough
solution for us.
I think you can call this closed and blame VC++. Sorry to waste your time!
Comment #5 on issue 195 by ken...@google.com: common.h should not
have "using namespace std;"
http://code.google.com/p/protobuf/issues/detail?id=195
> what if my application code wanted to use the
> google::protobuf name space but not std?
You should never use "using namespace". :) Yes, it's hypocritical for me
to say
that, but Google has lots of code that was written before GCC actually
moved STL into
the "std" namespace. As a result, we had to stick "using namespace std"
somewhere to
avoid updating everything, and that in turn means that most Google code
fails to
honor the "std" namespace at all. :/
Strange bug. I'll try to reproduce it and use your work around when I do
the next
release...
I ran into this several months ago but our need to fix was obviated by
moving to
Visual Studio 2008. I ought to have upstreamed the patch.
As you discovered, conflict is between the CompileAssert template
specialization and
the "using namespace std" directive. What I did was to move CompileAssert
to appear
before the "using namespace", and this fixed the namespace pollution.
I just hit this problem today on Solaris with protobuf 2.4.1 using g++
4.6.1 with -std=c++0x. It blew up the compilation of protobuf itself
clashing with a map declaration in netinet.h/if.h.
The only fix was to add std:: in front of string, vector, max, min etc. in
all the protobuf headers. Despite it only took an hour, I can't say it left
me with a good feeling.
The original bug described here is very much due to a Visual C++ compiler
bug.
Your bug sounds like a name clash introduced by some specific headers on
your OS. It sounds like the STL/netinet clash has been dogging people for
a decade: http://lists.kde.org/?l=kde-solaris&m=102448062530634&w=2
It sounds like the bug reported by Robin may be slightly different: If
net/if.h happens to be #included before a protobuf header, then any
reference to "map" in the protobuf headers will resolve to the "sturct map"
defined in if.h instead of to std::map, because the compiler will prefer
the declaration over the one imported via "using namespace".
One simple work-around would be to make sure to #include protobuf headers
before net/if.h.
We might be able to fix this in the protobuf code by writing "using
std::map;" immediately after "using namespace std;" -- this might convince
the compiler that we really do prefer ::std::map over ::map. I'm not sure.
I think this should be opened as a separate bug, though.
Comment #11 on issue 195 by Etienne....@gmail.com: common.h should not have "using namespace std;"
http://code.google.com/p/protobuf/issues/detail?id=195
Hello google !
I just ran into this "using namespace std;" in common.h...
Do you guys have any plans to remove this ugly using from the header file ?
It would be easier for my project to use the whole google::protobuf namespace, but I cannot do that otherwise I use the whole std namespace too, which I do not want.
--
You received this message because this project is configured to send all issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to protobuf+unsubscribe@googlegroups.com.
To post to this group, send email to prot...@googlegroups.com.
Visit this group at http://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.