I installed libboost-all-dev (v1.67) on my fully up-to-date Debian 10 machine to work with a closed-source source-tree we licensed of a different company. It won't compile due to many boost-related issues. I was able to narrow it down to the lack of nearly all BOOST_* macros.
Then I created a minimal test
#include <boost/config.hpp> //every boost-functionality uses this include
#ifndef BOOST_NOEXCEPT
#error MISSING BOOST_NOEXCEPT!
#endif
int main(int argc, char** argv) {
return 0;
}
When running g++ boost_test.cpp -o boost_test && ./boost_test the compilation fails with
boost_test.cpp:3:2: error: #error MISSING BOOST_NOEXCEPT!
#error MISSING BOOST_NOEXCEPT!
This puzzles me since the doc clearly states that, no matter what, BOOST_NOEXCEPT should be defined:
If BOOST_NO_CXX11_NOEXCEPT is defined (i.e. C++03 compliant compilers) these macros are defined as:
#define BOOST_NOEXCEPT
#define BOOST_NOEXCEPT_OR_NOTHROW throw()
#define BOOST_NOEXCEPT_IF(Predicate)
#define BOOST_NOEXCEPT_EXPR(Expression) false
If BOOST_NO_CXX11_NOEXCEPT is not defined (i.e. C++11 compliant compilers) they are defined as:
#define BOOST_NOEXCEPT noexcept
#define BOOST_NOEXCEPT_OR_NOTHROW noexcept
#define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate))
#define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression))
However, when manually including boost/config/detail/suffix.hpp (where BOOST_NOEXCEPT gets defined) it is correctly defined. Now I don't know what's wrong because <boost/config.hpp> already does include suffix.hpp.
Is something wrong with my installation? I don't want to manually hot-fix this by including boost/config/detail/suffix.hpp in every boost-related file in the source-tree.
Related
When testing for features in Visual Studio, I found this weird behaviour:
#ifndef __cpp_constexpr
#error Opposite day! //Compiler error
#endif
#define test_macro
#ifndef test_macro
#error But only for feature macros? //No compiler error
#endif
int main() {}
__cpp_constexpr is definitely defined, I used it in the actual program.
From my testing, it seems that with feature macros #ifndef behaves like #ifdef
and vice versa.
Is this a Visual Studio bug, or am I missing something?
Compiled in VS 2017, Visual C++14 or later, with C++17 standard enabled.
P.S. Intellisense is working as intended, it's only the compiler.
You are using incorrect pre-defined macro and pre-proc code. Next code can help:
#if defined(__GNUG__) && (__cplusplus > 201103L)
# define HAS_CONSTEXPR
#elif defined(_MSC_VER) && (_MSC_FULL_VER >= 190024210)
# define HAS_CONSTEXPR
#endif // __GNUG__
#ifndef HAS_CONSTEXPR
# error Opposite day! //Compiler error
#else
# define test_macro
# ifndef test_macro // useless by why not ?
# error But only for feature macros? //No compiler error
# endif
#endif
Suggesting to use boost config library. It is cross compiler, an you can solve it like this:
#ifdef BOOST_NO_CXX11_CONSTEXPR
# error Opposite day! //Compiler error
#endif
And it is going to work for all compilers supported by boost (according to the boost license, you can exam the source code and replicate is in you project)
I'm porting a code from Windows to CentOS but I'm confronting with a problem that I've never seen before.
Given that function declaration (there are many more) :
byte getValueInt8() const throw(.../*Exception*/);
I get this error:
error: expected type-specifier before ‘...’ token unsigned short getValueInt8() const throw(.../*Exception*/);
Of course I've checked the internet and I've found that it is a visibility problem in shared objects.
This website https://gcc.gnu.org/wiki/Visibility explains that but I had already done this when I read it.
My defines are:
#if defined(_MSC_VER)
#include <winsock2.h>
#ifdef MFTINTERFACE_EXPORTS
#define EXPORT_IMPORT __declspec(dllexport)
#else
#define EXPORT_IMPORT __declspec(dllimport)
#endif
#elif defined(_GCC)
#include <arpa/inet.h>
#include "CmnSocketsDef.h"
#include "CmnDefs.h"
#define EXPORT_IMPORT __attribute__((visibility("default")))
#else
#define EXPORT_IMPORT
#define IMPORT
#pragma warning Unknown dynamic link import/EXPORT_IMPORT semantics.
#endif
Of course, all EXPORT_IMPORT are well set in my code.
The code, before modification compiles in Windows.
throw(...) as an exception specification isn't legal c++.
I can only assume you've encountered a Microsoft abomination extension.
You'll need to remove it. In any case the only exception specifier that makes any sense in reality is nothrow (or throw() if you're using an ancient compiler).
Indeed, here's the smoking gun:
https://msdn.microsoft.com/en-us/library/wfa0edys.aspx
proposal to deprecate:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3051.html
I see this being done all the time for example in the Linux Kernel. What is the purpose of using the preprocessor commands vs just normal C++ if else block? Is there a speed advantage or something?
A preprocessor changes the C/C++ code before it gets compiled (hence pre processor).
Preprocessor ifs are evaluated at compile-time.
C/C++ ifs are evaluated at run-time.
You can do things that can't be done at run-time.
Adjust code for different platforms or different compilers:
#ifdef __unix__ /* __unix__ is usually defined by compilers targeting Unix systems */
#include <unistd.h>
#elif defined _WIN32 /* _Win32 is usually defined by compilers targeting 32 or 64 bit Windows systems */
#include <windows.h>
#endif
Ensure header file definitions are included only once (equivalent of #pragma once, but more portable):
#ifndef EXAMPLE_H
#define EXAMPLE_H
class Example { ... };
#endif
You can make things faster than at run-time.
void some_debug_function() {
#ifdef DEBUG
printf("Debug!\n");
#endif
}
Now, when compiling with DEBUG not defined (likely a command line parameter to your compiler), any calls to some_debug_function can be optimized away by the compiler.
Preprocessor is run before the compilation pass, so the compiler won't even see anything that was in the not-taken #if branch.
#if DEBUG
int a;
#else
double b;
#endif
gcc -c -DDEBUG=1 file.c will see "int a"
gcc -c file.c will see "double b"
Preprocessor allows you to actually cut out or paste in to your source file, code to be compiled. If its cut out, its gone, its like a comment, does nothing, is not compiled, produces no code in the binary. Devs will often use this technique to add code only in debug build for debugging purposes or for adding or excluding code for specific operating systems.
I work in Visual Studio but my project is for a POSIX-based environment (marmalade sdk). In this project, the release
build is compiled with gcc for ARM but the debug version works on windows and is compiled by MS compiler. Also this environmet has its own implementation of STL and other standard libraries.
Many of these c++ librares have code like this:
#if defined( _MSC_VER )
#include <Windows.h>
#else
#include <pthread.h>
#endif
Is it possible to undefine the _MSC_VER macro? - So that the C++ libraries will detect a POSIX system here.
_MSC_VER is (and always should be) defined when compiling with the Microsoft compiler so that it "evaluates to the major and minor number components of the compiler's version number". Therefore, the code is using the wrong macro test, since it will always be defined to some value for your compiler regardless of the Windows environment differences.
Rather than destroy the definition of _MSC_VER (which could lead to other problems if any code really does want to know the compiler version), what you really should do instead is to correct the condition so that a more appropriate macro test is used that distinguishes between the kinds of Windows environments that you might encounter.
See the more complete list of predefined macros you could consider here
You could either replace the condition ...
#if someOtherConditionGoesHere
... or extend it with additional conditions, e.g.
#if defined(_MSC_VER) && someOtherConditionGoesHere
Of course:
#undef _MSC_VER
#if defined( _MSC_VER )
#include <Windows.h>
#else
#include <pthread.h>
#endif
Or, #undef it before you include the file where _MSC_VER is used.
Please look at the following file: (it is a complete file)
#ifndef TEES_ALGORITHM_LIBRARY_WRAPPER_H
#define TEES_ALGORITHM_LIBRARY_WRAPPER_H
#ifdef _TEES_COMPILE_AS_LIB
#include <dfa\Includes\DFC_algorithms.hpp>
#include <DFA\FuzzyClassifier\FuzzyAlgorithmIntialization\InitFuzzyAlgorithm.hpp>
typedef teesalgorithm::tees_fuzzy_algorithms algorithms_switchyard_class;
#else
#include <DFA\Includes\commercial_algorithms.hpp>
//An incomplete class to hide implementation
class algorithms_switchyard_class;
#endif
class AlgorithmLibraryWrapper {
algorithms_switchyard_class * algorithmPtr_;
typedef teesalgorithm::tees_paramObj paramObj_type;
typedef teesalgorithm::tees_errorObj errorObj_type;
typedef teesalgorithm::tees_statusObj statusObj_type;
typedef teesalgorithm::tees_dataObj dataObj_type;
typedef teesalgorithm::tees_outputObj outputObj_type;
public:
AlgorithmLibraryWrapper(const std::string& sAlgName, paramObj_type& paramObj, errorObj_type& errObj, statusObj_type& statusObj, const char* sFilePath);
static bool dataReader(const std::string& sFileName, dataObj_type& dataObj, errorObj_type& errObj, statusObj_type& statusObj);
bool runalgorithm(const dataObj_type& dataObj, outputObj_type& outObj, errorObj_type& errObj, statusObj_type& statusObj);
~AlgorithmLibraryWrapper();
};
#ifdef _TEES_USE_COMPILED_ALGORITHM_LIB
# ifdef _MSC_VER
#if _MSC_VER < 1400 // If VC 2003
#ifdef _DEBUG
#error No AlgorithmLibWrapper libraries compiled for this version of VC
#else
#error No AlgorithmLibWrapper libraries compiled for this version of VC
#endif
#elif defined(UNDER_CE) // Win CE
#ifdef _DEBUG
#pragma comment( lib, "AlgorithmLibWrapperCEd" )
#else
#pragma comment( lib, "AlgorithmLibWrapperCE" )
#endif
#else // If VC 2005
#ifdef _DEBUG
#pragma comment( lib, "AlgorithmLibWrapperd" )
#else
#pragma comment( lib, "AlgorithmLibWrapper" )
#endif
#endif
#endif
#endif
#endif //TEES_ALGORITHM_LIBRARY_WRAPPER_H
I am getting the following errors; I don't know why. I manually counted the preprocessor directives also.
AlgorithmLibraryWrapper.hpp:10:1: unterminated #ifdef
AlgorithmLibraryWrapper.hpp:7:1: unterminated #ifndef
I am using the poor vxWorks gcc compiler. Please let me know if the fault is mine or the compiler's.
It could be that the problem is in the included files (if there actually are unbalaced #if/#endifs.
I would try preprocessing with another compiler. You can use gcc for that, doesn't matter it wouldn't compile. Just get gcc (or MinGW if you're on Windows) and run
cpp -Iinclude_direcories your_file
Or, if you don't like gcc, get MSVC Express edition. Again, you can preprocess code that even doesn't compile, so no problem with nonworking library etc.
Most compilers have an option that will give you the output from the preprocessor so you can check what it's doing. For example,
gcc -E file.c >file.preproc
will give you the pre-processed source so you can check the balancing of #if against #endif.
At a guess, one of the files you are #including from this one has a mismatched #ifdef/#endif pair. You need to look at all the files (as the preprocesor does), not just this one.
As others have noted, this is most likely due to mismatched include guards.
If the files you are including are under your control (i.e. not part of a 3rd party closed source library), you could consider replacing the #ifndef et. al. guards (which are used to prevent multiple inclusion) with #pragma once. This will eliminate the possibility of having mismatched preprocessor directives.
One caveat of this is that pragma once is non-standard, so it will only work if your compiler supports it.
I have tried to compile your source using vs 6.0 but did not get the error you have mentioned. As others said may be the error is coming from the included header file . For me to get your code compiled i need to comment the above header.
Please check the above header once.
I'd debug this by commenting out sections one by one and trying to identify which section is causing the error.
It could be your compiler does not like the nested #ifdefs or does not interpret the syntax correctly. Maybe it doesn't like the #pragmas.
This is a long shot, but in your source file you have the following line:
# ifdef _MSC_VER
where there is whitespace between the '#' character and the directive name (ifdef). This is valid in C/C++; however, it's not too commonly seen so I wouldn't be very surprised if the odd compiler choked on it.