gcc: -Dvar=value not working as expected - gcc

I am trying to compile a library that has these lines:
#if AE_OS==AE_WINDOWS
#include windows.h
//stuff
#elif AE_OS==AE_POSIX
//other stuff
#endif
When I use cpp -DAE_OS=AE_POSIX I get
cpp/src/ap.cpp:63:21: fatal error: windows.h: No such file or directory
#include <windows.h>
^
Adding a space after the -D does not work, nor does putting AE_OS=AE_POSIX in single or double quotes, putting only AE_POSIX in single or double quotes, and trying all of these combinations with the quotes escaped.
Putting AE_POSIX in escaped single quotes at least does something different, but it is apparently still not correct:
cpp/src/ap.cpp:59:5: warning: character constant too long for its type [enabled by default]
#if AE_OS==AE_WINDOWS
^
I have also tried -D"AE_OS AE_POSIX" thinking that would be the same as #define "AE_OS AE_POSIX" but apparently it ignores the quotes since it defines AE_OS as 1:
<command-line>:0:16: error: missing binary operator before token "1"
cpp/src/ap.cpp:65:7: note: in expansion of macro ‘AE_OS’
#elif AE_OS==AE_POSIX
What is the correct way to do this?

The preprocessor understands expressions of integer type, not strings.
AE_POSIX and AE_WINDOWS are defined as different integers:
/*
* definitions
*/
#define AE_UNKNOWN 0
#define AE_MSVC 1
#define AE_GNUC 2
#define AE_SUNC 3
#define AE_INTEL 1
#define AE_SPARC 2
#define AE_WINDOWS 1
#define AE_POSIX 2
So for POSIX do this:
cpp -DAE_OS=2

Related

Error installing perl on Win10 using MinGW

If this is the wrong place for this question I apologise and please redirect me to the suitable section.
I'm somewhat rusty on installing from command line, especially on Windows. I decided to install the latest Perl version on my PC, running under Windows 10. I had previously installed it using Strawberry Perl download, but as it was a few versions out of date I decided to remove it and refresh my skills (ha) by installing it manually. I downloaded the lastest Perl release from https://www.perl.org/get.html#win32 and have been reading the README.win32 to make sure I install it correctly.
As I need a compiler, I decided to use Gcc and dmake. I installed and can run them successfully so went back to installing Perl. As per instructions I tried running dmake in the win32 subdirectory in the Perl download folder. Before this I edited makefile.mk, where these variables are uncommented from the Build configuration section:
INST_DRV/INST_TOP (left as is)
INST_VER *= \5.26.0
USE_MULTI *= define
USE_ITHREADS *= define
USE_IMP_SYS *= define
USE_LARGE_FILES *= define
USE_64_BIT_INT *= define
USE_LONG_DOUBLE *= define
DEFAULT_INC_EXCLUDES_DOT *= define
CCTYPE = GCC
GCCWRAPV *=define
CCHOME *= C:\MinGW
(nothing else changed after this)
When I run dmake in the directory, it quickly comes to this error:
gcc -c -I.\include -I. -I.. -DWIN32 -DPERLDLL -DPERL_CORE -s -O2 -
D__USE_MINGW_ANSI_STDIO -fwrapv -fno-strict-aliasing
-DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -omini\toke.o ..\toke.c
In file included from ..\perl.h:3220:0,
from ..\toke.c:40:
./win32.h:417:13: error: conflicting types for 'mkstemp'
extern int mkstemp(const char *path);
^~~~~~~
In file included from ..\perl.h:790:0,
from ..\toke.c:40:
c:\mingw\include\stdlib.h:809:30: note: previous definition of 'mkstemp' was here
__cdecl __MINGW_NOTHROW int mkstemp (char *__filename_template)
^~~~~~~
In file included from ..\toke.c:40:0:
..\toke.c: In function 'Perl_filter_add':
..\perl.h:1756:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
#define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */
^
..\perl.h:1769:28: note: in expansion of macro 'PTR2nat'
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^~~~~~~
..\toke.c:4397:21: note: in expansion of macro 'FPTR2DPTR'
IoANY(datasv) = FPTR2DPTR(void *, funcp); /* stash funcp into spare field */
^~~~~~~~~
..\perl.h:1769:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^
..\toke.c:4397:21: note: in expansion of macro 'FPTR2DPTR'
IoANY(datasv) = FPTR2DPTR(void *, funcp); /* stash funcp into spare field */
^~~~~~~~~
..\toke.c: In function 'Perl_filter_del':
..\perl.h:1756:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
#define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */
^
..\perl.h:1769:28: note: in expansion of macro 'PTR2nat'
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^~~~~~~
..\toke.c:4463:26: note: in expansion of macro 'FPTR2DPTR'
if (IoANY(datasv) == FPTR2DPTR(void *, funcp)) {
^~~~~~~~~
..\perl.h:1769:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^
..\toke.c:4463:26: note: in expansion of macro 'FPTR2DPTR'
if (IoANY(datasv) == FPTR2DPTR(void *, funcp)) {
^~~~~~~~~
..\toke.c: In function 'Perl_filter_read':
..\perl.h:1756:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
#define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */
^
..\perl.h:1768:28: note: in expansion of macro 'PTR2nat'
#define DPTR2FPTR(t,p) ((t)PTR2nat(p)) /* data pointer to function pointer */
^~~~~~~
..\toke.c:4554:13: note: in expansion of macro 'DPTR2FPTR'
funcp = DPTR2FPTR(filter_t, IoANY(datasv));
^~~~~~~~~
..\perl.h:1768:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#define DPTR2FPTR(t,p) ((t)PTR2nat(p)) /* data pointer to function pointer */
^
..\toke.c:4554:13: note: in expansion of macro 'DPTR2FPTR'
funcp = DPTR2FPTR(filter_t, IoANY(datasv));
^~~~~~~~~
In file included from ..\perl.h:5644:0,
from ..\toke.c:40:
..\toke.c: In function 'S_pending_ident':
..\perl.h:1734:26: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
# define INT2PTR(any,d) (any)(d)
^
..\embed.h:427:59: note: in definition of macro 'newUNOP_AUX'
#define newUNOP_AUX(a,b,c,d) Perl_newUNOP_AUX(aTHX_ a,b,c,d)
^
..\toke.c:8912:37: note: in expansion of macro 'INT2PTR'
INT2PTR(UNOP_AUX_item *,
^~~~~~~
I get a bunch of warnings beforehand about casting from pointers to integers of different sizes, but this is the bit where it stops and produces an error. Am I missing something obvious? I haven't done this for a while, so I'm hoping it is a silly user error on my part! Thanks.
Try obtaining the MinGW source packages, and installing using makepkg-mingw to build them.
Most if not all have patches applied to customize (or fix) them for the MSYS2/MinGW environment.
Stock source downloaded from its author may not compile directly in that environment the way it would on Linux, or OS X using "configure" and "make".
Instructions are available, and there may be other similar instructions out there associated with Arch Linux.

Handling large volume of boost unit test related warnings with clang-tidy

I'm in the process of setting up a project. I have skeleton tests in place using boost unit-test. Unfortunately a large number of warnings are spawned from the macro expansions. Is there a way to disable these, without have to specify individual line numbers?.
This occurs even when I have a // NOLINT.
An example:
/home/peter/checkouts/canopen-gateway/./unittests/projs/server/exe/testunit-tcp-socket.cpp:12:1: warning: construction of 'end_suite12_registrar12' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
BOOST_AUTO_TEST_SUITE_END() // NOLINT
^
/usr/include/boost/test/unit_test_suite.hpp:62:73: note: expanded from macro 'BOOST_AUTO_TEST_SUITE_END'
#define BOOST_AUTO_TEST_SUITE_END() \
^
/usr/include/boost/test/unit_test_suite.hpp:209:62: note: expanded from macro '\BOOST_AUTO_TU_REGISTRAR'
static boost::unit_test::ut_detail::auto_test_unit_registrar BOOST_JOIN( BOOST_JOIN( test_name, _registrar ), __LINE__ )
^
/usr/include/boost/config/suffix.hpp:544:28: note: expanded from macro 'BOOST_JOIN'
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
^
/usr/include/boost/config/suffix.hpp:545:31: note: expanded from macro 'BOOST_DO_JOIN'
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
^
/usr/include/boost/config/suffix.hpp:546:32: note: expanded from macro 'BOOST_DO_JOIN2'
#define BOOST_DO_JOIN2( X, Y ) X##Y
^
note: expanded from here
/usr/include/boost/test/unit_test_suite_impl.hpp:284:17: note: possibly throwing constructor declared here
explicit auto_test_unit_registrar( int );
You probably didn't paste the entire error message, but somewhere in there should be a line that says
warning: disabled expansion of recursive macro
[-Wdisabled-macro-expansion]
You can disable this by passing -Wno-disabled-macro-expansion to the clang command line.
Try wrapping the offending code thus:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
// your code here
#pragma clang diagnostic pop

Macro substitution in #include directive

I would like to use an #include directive with a file name that is passed as an externally defined macro.
E.g.
#include #FILE".h"
where FILE would be defined as the string MyFile (without quotes), resulting in
#include "MyFile.h"
The stringizing operator # cannot be used here as the symbol FILE is not a macro argument. I have tried other approaches, to no avail.
Do you see a solution ?
String literal concatenation happens two translation phases after #include-directives are resolved; your approach cannot work. Instead, try something along the lines of
#define STRINGIZE_(a) #a
#define STRINGIZE(a) STRINGIZE_(a)
#define MYFILE stdio
#include STRINGIZE(MYFILE.h)
int main() {
printf("asdf");
}
Demo.

"elif" in gcc: #elif with no expression error

I'm trying to do something like this:
#define RELEASE_TEST
#if RELEASE
// code1
#elif RELEASE_TEST
// code2
#else
// code3
#endif
gcc claims about #elif: "error: #elif with no expression".
I do not understand this error, because I provide "RELEASE_TEST" expression to "elif".
How to make my code working?
RELEASE_TEST is defined, but with no value, so this expands to just #elif, which isn't valid.
You could either use #elif defined(RELEASE_TEST) to test if it's defined at all, or #define RELEASE_TEST 1, which would cause that line to expand to #elif 1.

Warning C4091: ' __declspec(dllexport)'

I have the following code where I am trying to export a function called "Interface_API" out of my dll.
#ifdef INTERFACEDLL_EXPORTS
#define UserApp_API __declspec(dllexport);
#else
#define UserApp_API __declspec(dllimport);
#endif
UserApp_API int Interface_API(int *, int *, int *);
When I compile this code it gives the following warning and the function is not getting exported.
warning C4091: ' __declspec(dllexport)' : ignored on left of 'int' when no variable is declared
When I change the declaration as given below I don't get the warning and it exports properly.
__declspec(dllexport) int Interface_API(int *, int *, int *);
I am little confused because I have used it in different dll and it works fine. Any clue?
#define UserApp_API __declspec(dllimport);
^ Semicolon.

Resources