Gfortran pre-processor directives for Different Operating systems - preprocessor

Could you tell me please how can I do the following:
#if __unix__
#define path_sep='/'
#elif __windows__
#define path_sep='\'
#else
#error "path_sep not defined."
#endif
using gfortran compiler.

This can be done in combination with conditional compilation and using the "D" option on the command line. Here is some example code:
program test_Dopt
character (len=1) :: pathsep
pathsep = "?"
#ifdef WOS
pathsep = "\"
#endif
#ifdef UOS
pathsep = "/"
#endif
write (*, '( "pathsep is >", A1, "<")' ) pathsep
end program test_Dopt
Name the program with filetype F90 to cause gfortran to run the preprocessor or use -cpp on the compile line. Then pass options to the prepreprocessor by including them after D on the compile line, e.g., gfortran -DWOS. (This is more general then gfortran -- most Fortran compilers will process C-style pre-processor directives.) Then you can identify the OS outside of Fortran and pass the information to the Fortran program.
You can compile your code via using the filetype F90 or -cpp.

Related

Decide if is the user is using gfortran or ifort

I'm coding a code in modern Fortran, and I want to do some like:
IF (you are compiling the code with gfortran) Do something...
IF (you are compiling the code with ifort) Do other thing...
but I haven't found a way to verify those logic conditions in the IF statements inside the code.
The easiest way is to look at compiler-specific macros.
For gfortran, you can look at __GNUC__ as described here.
For ifort, you can look at __INTEL_COMPILER as described here.
If you have the file test.F90 (note the .F90 rather than .f90, it's important that this file is preprocessed), then you can have something like
program test
implicit none
#ifdef __GNUC__
logical, parameter :: gfortran = .true.
#else
logical, parameter :: gfortran = .false.
#endif
#ifdef __INTEL_COMPILER
logical, parameter :: ifort = .true.
#else
logical, parameter :: ifort = .false.
#endif
if (gfortran) then
write(*,*) 'gfortran'
elseif (ifort) then
write(*,*) 'ifort'
else
write(*,*) 'Unknown compiler'
endif
end program

QtCreator annotation compiler does not find stdbool.h

I'm using QtCreator 4.11.2 , installed via MSYS2, with ClangCodeModel enabled.
Here is my program (this is the result of creating a New Non-QT Plain C Application):
#include <stdio.h>
#include <stdbool.h>
_Bool a;
bool b;
int main()
{
printf("Hello World!\n");
return 0;
}
The .pro file is unchanged from the default:
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
main.c
The annotation compiler highlights an error saying stdbool.h cannot be found.
But it does not give an error for _Bool a; , so it is clearly running in C99 mode but has some problem with include paths. The "Follow symbol under cursor" option works, opening stdbool.h.
My question is: How do I configure include paths for the annotation compiler or otherwise fix this problem?
I have been unable to figure out how to set options for the annotation compiler or even which compiler binary it is using . Under Tools > Options > C++ > Code Model > Diagnostic Configuration it lets me add -W flags but does not let me add -I flags, a red message pops up saying the option is invalid.
Under Tools > Options > C++ Code Model inspector, there are no diagnostic messages, and the Code Model Inspecting Log shows stdbool.h being correctly found and parsed, as msys64/mingw64/lib/gcc/x86_64-w64-mingw32/9.3.0/include/stdbool.h.
If I disable the ClangCodeModel plugin then there are no errors , but I would like to use the clang version if it can be made to work as in general it has good diagnostics.
The result of clang --version in a shell prompt is:
clang version 10.0.0 (https://github.com/msys2/MINGW-packages.git 3f880aaba91a3d9cdfb222dc270274731a2119a9)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: F:\Prog\msys64\mingw64\bin
and if I compile this same source code using clang outside of QtCreator, it compiles and runs correctly with no diagnostics. So the annotation compiler is clearly not the same as the commandline clang?
The Kit I have selected in QtCreator is the autodetected Desktop Qt MinGW-w64 64bit (MSYS2)
The exact same symptoms occur if I make a Plain C++ project and try to include stdbool.h (which is required to exist by the C++ Standard, although deprecated), although interestingly it does accept <cstdbool>.
I have found a workaround of sorts: including in the .pro file the line:
INCLUDEPATH += F:/Prog/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/9.3.0/include/
causes the annotation compiler to work correctly, however this is undesirable as I'd have to keep changing it whenever I switch Kits because it also passes this to the actual build compiler, not just the annotation compiler.
Create file stdbool.h in C:\msys64\mingw64\x86_64-w64-mingw32\include and copy paste this code:
/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/*
* ISO C Standard: 7.16 Boolean type and values <stdbool.h>
*/
#ifndef _STDBOOL_H
#define _STDBOOL_H
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#else /* __cplusplus */
/* Supporting _Bool in C++ is a GCC extension. */
#define _Bool bool
#if __cplusplus < 201103L
/* Defining these macros in C++98 is a GCC extension. */
#define bool bool
#define false false
#define true true
#endif
#endif /* __cplusplus */
/* Signal that all the definitions are present. */
#define __bool_true_false_are_defined 1
#endif /* stdbool.h */
Note
Creating a manual file stdbool.h works for me but its a sketchy and a temporary solution for now. Don't use this if you feel its too sketcy. I would rather use a alternative solution than this hack if it exist. This solution might not be good but it still works for me.

Disabling conditional macro evaluation in clang

#define NUM 1
#if(NUM)
if(globalglobalInteger){
result = 1;
}
#else
result=2
#endif
Given the above code , the requirement is that the conditional macro #if should not be evaluated and all code under #if and #else should be passed for further processing.
Basically I want both the active and inactive part(code under #if and code under #else) to be present in the clang AST.
Is this possible in clang ?
Is there any pre-processor flag available
for doing this in clang?
Saw that there is flag called -fdirectives-only in gcc which disables macro expansion but could not find similar flag in clang
Preprocessing takes places before parsing and AST generation, so you can't have
non-expanded defines and macros in the AST.
However, there are means for handling non-preprocessed code - such as registering to clang preprocessor callbacks (the PPCallbacks interface) or through the pp-trace tool
(disclamer: I don't have experience with this myself).
References:
Clang AST dump doesn't show #defines
http://clang-developers.42468.n3.nabble.com/Preprocessor-Parser-interaction-td3754583.html
http://www.llvm.org/devmtg/2016-11/Slides/Trull-ExtendingClangASTMatchers.pdf
With regards to flags, clang has no equivalent to gcc's -fdirectives-only. For keeping both parts of the macro in output,
you could disable preprocessing altogether, similar to gcc's -fpreprocessed - which will effectively disable macro expansion (but still macros will be absent from the AST).
You could insepct the AST generated for non-preprocessed source files with these commands:
clang -xcpp-output -Xclang -ast-dump -c foo.c
clang -xc++-cpp-output -Xclang -ast-dump -c foo.cpp
HTH - good luck!

Where can I find the definition of the macro __insn_dword_align that occurs in memcmp.c of the glibc source code project?

The implementation of function memcmp in glibc uses the macro DBLALIGN(eg, DBLALIG(a3, a0, srcli)) to compare two unsinged int integer. DBLALIGN is delcared as follows. However, the definition of __insn_dword_align is not found in glibc source codes. Where can I find it. Thank you!
#ifdef __tilegx__
#define DBLALIGN __insn_dblalign
#define REVBYTES __insn_revbytes
#else
#define DBLALIGN __insn_dword_align
#define REVBYTES __insn_bytex
#endif
It's a gcc builtin. See e.g. here.
I cannot find the definition
You wouldn't find a definition for any builtin. That's what "builtin" means: the compiler recognizes builtin by name and emits required instructions directly to assembly.

XC8 warning: (107) illegal # directive "foo"

I have a fair bit of code written to compile under various build systems (e.g. CCS, Visual C, Embarcadero CBuilder, Microchip XCn). Since the various compilers differ in how they define things like inline or interrupt routines, I use #if/#elif/#else constructs to satisfy their requirements. The GCC preprocessor documentation even suggests this as a good use for #if etc.
In the case of my microprocessor build tools, the CCS family of compilers, and XC16 (gcc-based) deal with this just fine, but XC8 insists on looking inside a non-active #if blocks and generating warnings.
For example, the code
#ifdef _COMPILER_CCS
#INT_RDA
void RDA_ISR(void)
#elif defined (_COMPILER_MCHIP_XC16)
void __attribute__((__interrupt__(_ISR_SPECIAL_SAVE), __auto_psv__)) _U1RXInterrupt(void)
#elif defined (_COMPILER_MCHIP_XC8)
void vU1RXInterruptHandler(void)
#else
#error Problem with defines
#endif
{
...
}
generates the warning
warning: (107) illegal # directive "INT_RDA"
There are hundreds of these warnings generated, making it hard to see legitimate warnings and/or errors.
Does anyone have suggestions on how to make XC8 shut up about things it's not even supposed to be parsing? I cannot find a flag to turn off this warning.
I use macros with xc8, but use #if
not just #ifdef as it seems to sometimes think undefined 'C'
macros are simply 0. Also I never give a compiler option the value 0.
Bit scary, but I tend to do stuff like:
//#define COMP_OPT 1
//#define COMP_OPT 2
#define COMP_OPT 3
then in the code
#if ( COMP_OPT == 0 )
#error COMP_OPT NOT DEFINED
#endif
#if ( COMP_OPT == 2 )
{
// code for compile option 2
// blah blah
}
#endif
That way I don't unintentionally produce code compiled for the wrong option (or none)

Resources