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
Related
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.
I have a project that I compile and it gives me following errors as:
In file included from c:/acrobatxsdk/Adobe/Acrobat 10 SDK/Version 1/PluginSupport/Headers/API/PIMain.c:21:0:
c:/acrobatxsdk/Adobe/Acrobat 10 SDK/Version 1/PluginSupport/Headers/API/Environ.h:37:2: error: #error You must define the PLATFORM macro
c:/acrobatxsdk/Adobe/Acrobat 10 SDK/Version 1/PluginSupport/Headers/API/Environ.h:41:10: error: #include expects "FILENAME" or <FILENAME>
c:/acrobatxsdk/Adobe/Acrobat 10 SDK/Version 1/PluginSupport/Headers/API/Environ.h:52:2: error: #error PLATFORM failed to #define ACCB1
The PIMain.c looks like this :
#if WIN_PLATFORM
#include "WinCalls.h"
#elif MAC_PLATFORM
#include "MacCalls.h"
#elif UNIX_PLATFORM
#include "UnixCalls.h"
#else
#error platform not defined
#endif
I have come to know that the only amendment if required is to be made in Environ.h , can some one suggest how?
Environ.h is looking for the PLATFORM directive and there is a preprocessor or compile time flag to "throw" an error if you do not define it. See how the #error directive works here (MSDN link).
I found the code for Environ.h:
#ifndef PLATFORM
#ifdef WIN_ENV
#define PLATFORM "winpltfm.h"
#elif __OS2__
#define PLATFORM "os2pltfm.h"
#elif defined(unix) || defined(__unix)
#define PLATFORM "UnixPlatform.h"
#else
#error You must define the PLATFORM macro
#endif
#endif
You apparently are not running on a supported platform.
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.
On a cross-platform project, I want to #include a header file whose name contains the name of the platform. I have a #define macro for the platform.
So for example, for
#define PLATFORM win32
I want
#include "engine\win32\devices_win32.h"
while for
#define PLATFORM linux
I want
#include "engine\linux\devices_linux.h"
I'm going with Richard Pennington's answer, minus one line of code - it works for me!
#define PLATFORM Linux
#define xstr(x) #x
#define str(x) xstr(x)
#define sub(x) x
#include str(sub(engine/PLATFORM/devices_)PLATFORM.h)
Usually, you would do something more like:
#ifdef WIN32
#include "devices_win32.h"
#endif
#ifdef LINUX
#include "devices_linux.h"
#endif
...rather than having a single PLATFORM definition which can be set differently depending on the platform.
#define PLATFORM Linux
#define xstr(x) #x
#define str(x) xstr(x)
#define sub(x) x
#define FILE str(sub(engine/PLATFORM/devices_)PLATFORM.h)
#include FILE
I'm not sure I'd use it, though. ;-)
I had to use Linux rather than linux because linux is defined as 1 in my compiler.
Well in practice, this could be achieved using something like
#define PLATFORM win32
#define INCLUDE_FILE devices_ ## PLATFORM
#define QUOTED_INCLUDE_FILE #INCLUDE_FILE
#include QUOTED_INCLUDE_FILE
but the the following rule would prevent you from doing this:
C comments and predefined macro names are not recognized inside a #include' directive in which the file name is delimited with <' and `>'.
C comments and predefined macro names are never recognized within a character or string constant. (Strictly speaking, this is the rule, not an exception, but it is worth noting here anyway.)
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.