In my code I bring the OpenSSL headers in in a namespace, like this:
#include <cstdio>
namespace OpenSSL {
#include <openssl/ssl.h>
#include <openssl/err.h>
}
But I’ve just discovered that this seems to cause things to explode if I try to do that when working with Boost ASIO, which has OpenSSL support, but appears to bring the OpenSSL symbols in to the global namespace. Is there anything I can do about this, or do I just have to leave all of the OpenSSL library’s symbols in the global namespace?
I did just think of trying a “using namespace OpenSSL” in the offending file after including my header, but that unfortunately causes errors such as:
/usr/include/openssl/x509v3.h:83:13: error: reference to ‘v3_ext_ctx’ is ambiguous
/usr/include/openssl/x509v3.h:71:8: error: candidates are: struct v3_ext_ctx
/usr/include/openssl/ossl_typ.h:160:16: error: struct OpenSSL::v3_ext_ctx
(Note that OpenSSL is a C library, not a C++ library, and thus the original functions are not in any namespace until brought in to a C++ compilation unit. My technique is recommended by Stroustrup in his book The C++ Programming Language, Special Edition. From section 9.5, “Advice”: “[8] #include C headers in namespaces to avoid global names; §8.2.9.1, §9.2.2.”
So the issue seems to be this: OpenSSL’s symbols can be brought in only once; a second #include of them will have no effect due to the include guards. That means that they can be brought in to only one namespace within a compilation unit.
Thus, if you’re going to work with Boost.ASIO in your compilation unit, which requires them to be in the global namespace, you’ll have either to bring them in to the global namespace yourself (before you #include <boost/asio.hpp> or let #include <boost/asio.hpp> do that.