I understand that this error is typically a syntax problem. I've gone through this with a fine toothcomb and can't spot it. The example below is whittled down to a couple of files which display the problem. The header files describe an API that is provided as a couple of lib files which I've referenced in the Eclipse project, but just trying to compile the following from the command line gives the same error.
I have several chained includes before getting to the first function declaration which throws an "expected initializer" error, along with every other declaration that follows.
main.cpp
#include <iostream>
#include <string>
#include <windows.h>
#include "defn.h"
using namespace std;
int main()
{
cout << "hello world" << endl;
return 0;
}
defn.h
#ifndef GEO_DEFINITIONS_H_INCLUDED
#define GEO_DEFINITIONS_H_INCLUDED
#include <iostream>
#include <string>
#define C_MICROSOFT
#define _UNICODE
#include "gxlib.h"
#endif // GEO_DEFINITIONS_H_INCLUDED
gxlib.h
#pragma once
#include <windows.h>
#ifdef C_MICROSOFT
#define GX_WRAPPER_FUNC __declspec(dllexport)
#define GX_STANDARD_FUNC
#define GX_WRAPPER_CALL _cdecl
#define GX_STANDARD_CALL _stdcall
#define GX_OBJECT_PTR void*
#define GX_VAR
#define GX_CONST const
#define GX_VOID void
#define GX_LONG long
#define GX_DOUBLE double
#define GX_HANDLE long
#define GX_LONG_PTR long*
#define GX_DOUBLE_PTR double*
#define GX_HANDLE_PTR long*
#define GX_ASTR_PTR char*
#define GX_WSTR_PTR wchar_t*
#if defined(GEO_UTF8)
#define GX_STR_PTR GX_ASTR_PTR
#elif defined( _UNICODE)
#define GX_STR_PTR GX_WSTR_PTR
#else
#define GX_STR_PTR GX_ASTR_PTR
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*---------------- Copy_3DN[_public] ----------------*/
GX_WRAPPER_FUNC GX_LONG GX_WRAPPER_CALL
Copy_3DN(GX_VAR GX_OBJECT_PTR,
GX_CONST GX_HANDLE_PTR,
GX_CONST GX_HANDLE_PTR);
#ifdef __cplusplus
}
#endif
The command line and exact error is
c:\Code\CPP>g++ -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -o main.o main.cpp
In file included from defn.h:11:0,
from main.cpp:4:
gxlib.h:55:1: error: expected initializer before 'Copy_3DN'
Copy_3DN(GX_VAR GX_OBJECT_PTR,
As I mentioned above, this is just an excerpt from a larger project that I'm building in Eclipse Mars using the MinGW-64 5.3 toolchain. Within Eclipse I've defined all of the include files and linked to the libraries, but this simple commandline example with everything in the same directory demonstrates the error.
I was lead to the answer by #SamVarshavchik's comment and this thread. The problem is the MSVC specific syntax
#define GX_WRAPPER_FUNC __declspec(dllexport)
#define GX_STANDARD_FUNC
#define GX_WRAPPER_CALL _cdecl
#define GX_STANDARD_CALL _stdcall
In my case the MSVC definitions are wrapped within the C_MICROSOFT #ifdef block, and that is the ONLY occurence of that definition, so the simplest solution is to remove the C_MICROSOFT define in defn.h and replace it with:
#ifdef __GNUC__
#define GX_WRAPPER_FUNC __attribute__ ((dllexport))
#define GX_STANDARD_FUNC
#define GX_WRAPPER_CALL __attribute__((cdecl))
#define GX_STANDARD_CALL __attribute__((stdcall))
#define _stdcall __attribute__((stdcall))
#define _cdecl __attribute__((cdecl))
#define GX_OBJECT_PTR void*
#define GX_VAR
#define GX_CONST const
#define GX_VOID void
#define GX_LONG long
#define GX_DOUBLE double
#define GX_HANDLE long
#define GX_LONG_PTR long*
#define GX_DOUBLE_PTR double*
#define GX_HANDLE_PTR long*
#define GX_ASTR_PTR char*
#define GX_WSTR_PTR wchar_t*
#define GX_STR_PTR GX_WSTR_PTR
#else
#define C_MICROSOFT
#endif
Related
I am calling Matlab compiled DLLs from C++ code. I use Matab 2015b for development and Matlab 9.0 as runtime.
The following command was used in a Windows 10 64-bit machine to compile Matlab application
mcc -v -a .\+ismrmrd -W cpplib:libStdFourier -T link:lib StdFourier.m -d E:\dev\matlab\mfiles\StdFourier
The DLL call works fine in the development machine. But when I deploy it in another machine which runs on Windows 7 64-bit with Runtime 9.0 installed, the library fails to initialise. The runtime initialises successfully and following error occurs at library intialise method libStdFourierInitialize()
I use following code for initialising runtime and library:
mclmcrInitialize();
const char *rtOptions[3];
rtOptions[0] = "-singleCompThread";
rtOptions[1] = "-logfile";
rtOptions[2] = "matlogfile.txt";
if (!mclInitializeApplication(rtOptions,3))
{
std::cerr << "Could not initialize the application properly." << std::endl;
}
std::cout << "MCR initialized:" << mclIsMCRInitialized() << std::endl; //Returns true
std::cout << "Initialize libStdFourier" << << std::endl;
/* Call the library intialization routine and make sure that the
library was initialized properly. */
if(!libStdFourierInitialize())
{
fprintf(stderr,"Could not initialize the library.\n");
}
And the error console window
Code for the header:
#ifndef __libStdFourier_h
#define __libStdFourier_h 1
#if defined(__cplusplus) && !defined(mclmcrrt_h) && defined(__linux__)
# pragma implementation "mclmcrrt.h"
#endif
#include "mclmcrrt.h"
#include "mclcppclass.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__SUNPRO_CC)
/* Solaris shared libraries use __global, rather than mapfiles
* to define the API exported from a shared library. __global is
* only necessary when building the library -- files including
* this header file to use the library do not need the __global
* declaration; hence the EXPORTING_<library> logic.
*/
#ifdef EXPORTING_libStdFourier
#define PUBLIC_libStdFourier_C_API __global
#else
#define PUBLIC_libStdFourier_C_API /* No import statement needed. */
#endif
#define LIB_libStdFourier_C_API PUBLIC_libStdFourier_C_API
#elif defined(_HPUX_SOURCE)
#ifdef EXPORTING_libStdFourier
#define PUBLIC_libStdFourier_C_API __declspec(dllexport)
#else
#define PUBLIC_libStdFourier_C_API __declspec(dllimport)
#endif
#define LIB_libStdFourier_C_API PUBLIC_libStdFourier_C_API
#else
#define LIB_libStdFourier_C_API
#endif
/* This symbol is defined in shared libraries. Define it here
* (to nothing) in case this isn't a shared library.
*/
#ifndef LIB_libStdFourier_C_API
#define LIB_libStdFourier_C_API /* No special import/export declaration */
#endif
extern LIB_libStdFourier_C_API
bool MW_CALL_CONV libStdFourierInitializeWithHandlers(
mclOutputHandlerFcn error_handler,
mclOutputHandlerFcn print_handler);
extern LIB_libStdFourier_C_API
bool MW_CALL_CONV libStdFourierInitialize(void);
extern LIB_libStdFourier_C_API
void MW_CALL_CONV libStdFourierTerminate(void);
extern LIB_libStdFourier_C_API
void MW_CALL_CONV libStdFourierPrintStackTrace(void);
extern LIB_libStdFourier_C_API
bool MW_CALL_CONV mlxStdFourier(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
/* On Windows, use __declspec to control the exported API */
#if defined(_MSC_VER) || defined(__BORLANDC__)
#ifdef EXPORTING_libStdFourier
#define PUBLIC_libStdFourier_CPP_API __declspec(dllexport)
#else
#define PUBLIC_libStdFourier_CPP_API __declspec(dllimport)
#endif
#define LIB_libStdFourier_CPP_API PUBLIC_libStdFourier_CPP_API
#else
#if !defined(LIB_libStdFourier_CPP_API)
#if defined(LIB_libStdFourier_C_API)
#define LIB_libStdFourier_CPP_API LIB_libStdFourier_C_API
#else
#define LIB_libStdFourier_CPP_API /* empty! */
#endif
#endif
#endif
extern LIB_libStdFourier_CPP_API void MW_CALL_CONV StdFourier(int nargout, mwArray& bufferQ, mwArray& imageQ, const mwArray& xmlstr, const mwArray& recon_data);
#endif
#endif
Thanks.
I am trying to get started using mingw (MinGW-w64) and eclipse after working in C++Builder for a long time. I'm very confused.
My work mostly revolves around a vendor supplied API which is MSVC-centric. It consists of 3 header files and a couple of libs. I was able to use their headers unchanged in C++Builder but am running into lots of problems with g++.
#define GX_WRAPPER_FUNC __declspec(dllexport)
#define GX_STANDARD_FUNC
#define GX_WRAPPER_CALL _cdecl
#define GX_STANDARD_CALL _stdcall
#define GX_OBJECT_PTR void*
#define GX_VAR
#define GX_CONST const
#define GX_VOID void
#define GX_LONG long
#define GX_DOUBLE double
#define GX_HANDLE long
#define GX_LONG_PTR long*
#define GX_DOUBLE_PTR double*
#define GX_HANDLE_PTR long*
#define GX_ASTR_PTR char*
#define GX_WSTR_PTR wchar_t*
#if defined(GEO_UTF8)
#define GX_STR_PTR GX_ASTR_PTR
#elif defined( _UNICODE)
#define GX_STR_PTR GX_WSTR_PTR
#else
#define GX_STR_PTR GX_ASTR_PTR
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*---------------- Copy_3DN[_public] ----------------*/
GX_WRAPPER_FUNC GX_LONG GX_WRAPPER_CALL
Copy_3DN(GX_VAR GX_OBJECT_PTR,
GX_CONST GX_HANDLE_PTR,
GX_CONST GX_HANDLE_PTR);
GX_STANDARD_FUNC GX_LONG GX_STANDARD_CALL
Std_Copy_3DN(GX_VAR GX_OBJECT_PTR,
GX_CONST GX_HANDLE_PTR,
GX_CONST GX_HANDLE_PTR);
...hundreds more like this
This yields a whole bunch of "expected initializer before " errors.
I've had some success by redefining the first 4 defines like this:
#ifdef __GNUC__
#define GX_WRAPPER_FUNC __attribute__ ((dllexport))
#define GX_STANDARD_FUNC
#define GX_WRAPPER_CALL
#define GX_STANDARD_CALL
#else
#define GX_WRAPPER_FUNC __declspec(dllexport)
#define GX_STANDARD_FUNC
#define GX_WRAPPER_CALL _cdecl
#define GX_STANDARD_CALL _stdcall
#endif
but it barfs later on when it encounters
GX_WRAPPER_FUNC GX_LONG GX_WRAPPER_CALL
RegisterResourceTracking_GEO(GX_VAR GX_OBJECT_PTR,
GX_CONST GX_LONG_PTR,
GX_OBJECT_PTR,
void (_stdcall *param3)(void*));
I would really like to use these headers WITHOUT editing them, and I've seen some references that suggest the correct choice of gcc distro might support this syntax, but I've tried a number already with no luck. I've tried both the i686 and x86-64 variants of MinGW-w64 and Nuwen and TDM. I'm not concerned with cross platform issues as the host app is Windows only anyways, and for my own stubborn reasons I don't want to give up and switch to MSVC.
So, is there a gcc distro which will support this syntax? If not, what is the path of least resistance?
cheers
As a workaround, you can expand your set of macro definitions to cover the keywords gcc doesn't recognize:
#ifdef __GNUC__
#define _cdecl __attribute__((cdecl))
#define __cdecl __attribute__((cdecl))
#define _stdcall __attribute__((stdcall))
#define __stdcall __attribute__((stdcall))
#define GX_WRAPPER_FUNC __attribute__ ((dllexport))
#else
#define GX_WRAPPER_FUNC __declspec(dllexport)
#endif
As a bonus, those make the original definitions here work:
#define GX_STANDARD_FUNC
#define GX_WRAPPER_CALL _cdecl
#define GX_STANDARD_CALL _stdcall
(FWIW, note that this is possible because most MSVC extensions are new simple keywords, from the space of identifiers reserved to the implementation. gcc's multi-token __attribute__(()) magic makes mapping in the reverse direction completely impossible. So any time you write code using gcc non-portable features, hide them behind macros.)
What is the difference between the C++ macro VERIFY() and ATLVERIFY() ? And which one is better to use for COM objects?
There is some difference in how the errors are reported. ATLVERIFY is defined as
#ifndef ATLVERIFY
#ifdef _DEBUG
#define ATLVERIFY(expr) ATLASSERT(expr)
#else
#define ATLVERIFY(expr) (expr)
#endif // DEBUG
#endif // ATLVERIFY
And ATLASSERT is
#ifndef ATLASSERT
#define ATLASSERT(expr) _ASSERTE(expr)
#endif // ATLASSERT
So it ends up in _ASSERTE (see https://msdn.microsoft.com/en-us/library/ezb1wyez.aspx )
While VERIFY is
#ifdef _DEBUG
#define VERIFY(f) ASSERT(f)
#else // _DEBUG
#define VERIFY(f) ((void)(f))
#endif // !_DEBUG
So it ends up in ASSERT (see https://msdn.microsoft.com/en-us/library/aa297139(v=vs.60).aspx )
I have a problem where I can't seem to get conditional #define preprocessors to work correctly. For example:
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "stdafx.h"
#else
#define PCH "xyz.h"
#endif
#include PCH
If I use this form, the compiler tells me that it can't find 'stdafx.h'. OK, that seems odd, so if I change the code to....
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "xyz.h"
#else
#define PCH "stdafx.h"
#endif
#include PCH
Then the file defined in PCH gets picked up and everything compiles fine. This seems odd to me, almost like the preprocessor is ignoring the #if directives and just using all the #defines that it encounters.
Obviously I am doing something wrong, and I was hoping that someone could help me understand this.
When a project has the precompiled header feature turned on the preprocessor ignores everything that comes before #include "stdafx.h"
So your #define statements are ignored.
TL:DR; #define defines the symbol, #ifdef tests if the symbol is defined not whether it has a value.
#define WIN32_BUILD
This defines a pre-processor token, WIN32_BUILD. The token has no value. Anywhere you use the token 'WIN32_BUILD' the pre-processor will substitute the empty string, i.e. nothing.
#ifdef WIN32_BUILD
This checks if the pre-processor token WIN32_BUILD is defined. It is, you just defined it.
#ifdef WIN32_BUILD
// true - this code is included.
#define PCH "stdafx.h"
This defines the pre-processor token, PCH, and assigns it the value "stdafx.h"
#else
#define PCH "xyz.h"
#endif
This code is ignored, because WIN32_BUILD was defined.
It looks as though you were expecting 'ifdef' to only evaluate to true if the expression was not defined /to/ something.
#define a
#define b SOMETHING
#ifdef a
// you are expecting this to be ignored
#endif
#ifdef b
// and expecting this not to be ignored
#endif
#ifdef and #if defined(...) do the same thing.
#define a
#define b SOMETHING
#if defined(a) && defined(b)
// this code will be evaluated, both tokens are defined.
#endif
This feature of pre-processor tokens is often used to support conditional functionality:
#if HAVE_CPP11_OVERRIDE_KEYWORD
#define OVERRIDE_FN override
#else
#define OVERRIDE_FN
#endif
struct A {
virtual void foo() {}
};
struct B : public A {
void foo() OVERRIDE_FN {}
};
In the above code, the override keyword is only added if the system supports it (determined outside of the code).
So a compiler with override sees
struct B : public A {
void foo() override {}
};
a compiler without it sees
struct B : public A {
void foo() {}
};
Note: The opposite of "ifdef" is "ifndef":
#define a
#define b SOMETHING
#undef c
//#define d // << we didn't define it.
int main() {
#ifdef a
#pramga message("a is defined")
#else
#pramga message("a is UNdefined")
#endif
#ifdef b
#pragma message("b is defined")
#else
#pramga message("b is UNdefined")
#endif
#ifdef c
#pramga message("c is defined")
#endif
#else
#pramga message("c is UNdefined")
#endif
#ifdef d
#pramga message("d is defined")
#endif
#else
#pramga message("d is UNdefined")
#endif
#ifndef d
#pragma message("d is not defined")
#endif
#ifndef a
#pragma message("a is not defined")
#endif
return 0;
}
You can assign a pre-processor token numeric values and test them with #if
#if _MSC_VER
#define WIN32_BUILD 1
#else
#define WIN32_BUILD 0
#endif
#if WIN32_BUILD
#include <Windows.h>
#endif
But, especially when doing cross-platform programming, people tend to use ifdef variants rather than numeric checks, because the value checks require you to explicitly ensure all of the tokens are defined with a value. It's a lot easier just to only define them when you need them.
Maybe I'm missing something, but could some please explain the "logic" behind the following code?
#ifndef _PTRDIFF_T
#ifndef _T_PTRDIFF_
#ifndef _T_PTRDIFF
#ifndef __PTRDIFF_T
#ifndef _PTRDIFF_T_
#ifndef _BSD_PTRDIFF_T_
#ifndef ___int_ptrdiff_t_h
#ifndef _GCC_PTRDIFF_T
#define _PTRDIFF_T
#define _T_PTRDIFF_
#define _T_PTRDIFF
#define __PTRDIFF_T
#define _PTRDIFF_T_
#define _BSD_PTRDIFF_T_
#define ___int_ptrdiff_t_h
#define _GCC_PTRDIFF_T
#ifndef __PTRDIFF_TYPE__
#define __PTRDIFF_TYPE__ long int
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#endif /* _GCC_PTRDIFF_T */
#endif /* ___int_ptrdiff_t_h */
#endif /* _BSD_PTRDIFF_T_ */
#endif /* _PTRDIFF_T_ */
#endif /* __PTRDIFF_T */
#endif /* _T_PTRDIFF */
#endif /* _T_PTRDIFF_ */
#endif /* _PTRDIFF_T */
Why is this preferred over a simple:
#ifndef xyz
#define xyz
#endif
???
I can see they are nested, but it is very confusing. ...and btw, just what are they defining, as there are no values after the identifiers???
The logic is to only define the macros if none of them is defiend. However, I would certainly refactor it into:
#if !defined(_PTRDIFF_T) && !defined(_T_PTRDIFF_) && //... well, you get the idea
#define _PTRDIFF_T
#define _T_PTRDIFF_
//...
#ifndef __PTRDIFF_TYPE__
#define __PTRDIFF_TYPE__ long int
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#endif
As to the second question: you can define a macro without a replacement text (it would just expand to nothing if used). Such macros are often used for conditional inclusion of code based on #ifdef or #ifndef.
They're checking that all these identifiers have been defined which would be in other already included headers. If they're all defined then we define a few new identifiers.
You don't need to give a value to the identifier, for example you wouldn't give a value to your #include guards.