1bde483f2SJacob Faibussowitsch #ifndef PETSC_PREPROCESSOR_MACROS_H 2bde483f2SJacob Faibussowitsch #define PETSC_PREPROCESSOR_MACROS_H 3bde483f2SJacob Faibussowitsch 4bde483f2SJacob Faibussowitsch #include <petscconf.h> 5bde483f2SJacob Faibussowitsch #include <petscconf_poison.h> /* for PetscDefined() error checking */ 6bde483f2SJacob Faibussowitsch 7ac09b921SBarry Smith /* SUBMANSEC = Sys */ 8ac09b921SBarry Smith 9*0e6b6b59SJacob Faibussowitsch #if defined(__cplusplus) 10*0e6b6b59SJacob Faibussowitsch #if __cplusplus <= 201103L 11*0e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 11 12*0e6b6b59SJacob Faibussowitsch #elif __cplusplus <= 201402L 13*0e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 14 14*0e6b6b59SJacob Faibussowitsch #elif __cplusplus <= 201703L 15*0e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 17 16*0e6b6b59SJacob Faibussowitsch #elif __cplusplus <= 202002L 17*0e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 20 18*0e6b6b59SJacob Faibussowitsch #else 19*0e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 22 // current year, or date of c++2b ratification 20*0e6b6b59SJacob Faibussowitsch #endif 21*0e6b6b59SJacob Faibussowitsch #endif // __cplusplus 22*0e6b6b59SJacob Faibussowitsch 23*0e6b6b59SJacob Faibussowitsch #ifndef PETSC_CPP_VERSION 24*0e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 0 25*0e6b6b59SJacob Faibussowitsch #endif 26*0e6b6b59SJacob Faibussowitsch 27bde483f2SJacob Faibussowitsch /* ========================================================================== */ 28bde483f2SJacob Faibussowitsch /* This facilitates using the C version of PETSc from C++ and the C++ version from C. */ 29bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 30bde483f2SJacob Faibussowitsch #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_CXX 31bde483f2SJacob Faibussowitsch #else 32bde483f2SJacob Faibussowitsch #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_C 33bde483f2SJacob Faibussowitsch #endif 34bde483f2SJacob Faibussowitsch 35bde483f2SJacob Faibussowitsch /* ========================================================================== */ 36bde483f2SJacob Faibussowitsch /* Since PETSc manages its own extern "C" handling users should never include PETSc include 37bde483f2SJacob Faibussowitsch * files within extern "C". This will generate a compiler error if a user does put the include 38bde483f2SJacob Faibussowitsch * file within an extern "C". 39bde483f2SJacob Faibussowitsch */ 40bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 419371c9d4SSatish Balay void assert_never_put_petsc_headers_inside_an_extern_c(int); 429371c9d4SSatish Balay void assert_never_put_petsc_headers_inside_an_extern_c(double); 43bde483f2SJacob Faibussowitsch #endif 44bde483f2SJacob Faibussowitsch 45bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 46bde483f2SJacob Faibussowitsch #define PETSC_RESTRICT PETSC_CXX_RESTRICT 47bde483f2SJacob Faibussowitsch #else 486ee8c794SJacob Faibussowitsch #define PETSC_RESTRICT restrict 49bde483f2SJacob Faibussowitsch #endif 50bde483f2SJacob Faibussowitsch 516ee8c794SJacob Faibussowitsch #define PETSC_INLINE PETSC_DEPRECATED_MACRO("GCC warning \"PETSC_INLINE is deprecated (since version 3.17)\"") inline 529fbee547SJacob Faibussowitsch #define PETSC_STATIC_INLINE PETSC_DEPRECATED_MACRO("GCC warning \"PETSC_STATIC_INLINE is deprecated (since version 3.17)\"") static inline 53bde483f2SJacob Faibussowitsch 54bde483f2SJacob Faibussowitsch #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */ 55bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT __declspec(dllexport) 56bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT __declspec(dllimport) 57bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL 58bde483f2SJacob Faibussowitsch #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX) 59bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT __attribute__((visibility("default"))) 60bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT __attribute__((visibility("default"))) 61bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden"))) 62bde483f2SJacob Faibussowitsch #elif !defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_C) 63bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT __attribute__((visibility("default"))) 64bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT __attribute__((visibility("default"))) 65bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden"))) 66bde483f2SJacob Faibussowitsch #else 67bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT 68bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT 69bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL 70bde483f2SJacob Faibussowitsch #endif 71bde483f2SJacob Faibussowitsch 72bde483f2SJacob Faibussowitsch #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */ 73bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_PUBLIC PETSC_DLLEXPORT 74bde483f2SJacob Faibussowitsch #else /* Win32 users need this to import symbols from petsc.dll */ 75bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT 76bde483f2SJacob Faibussowitsch #endif 77bde483f2SJacob Faibussowitsch 78bde483f2SJacob Faibussowitsch /* Functions tagged with PETSC_EXTERN in the header files are always defined as extern "C" when 79bde483f2SJacob Faibussowitsch * compiled with C++ so they may be used from C and are always visible in the shared libraries 80bde483f2SJacob Faibussowitsch */ 81bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 82bde483f2SJacob Faibussowitsch #define PETSC_EXTERN extern "C" PETSC_VISIBILITY_PUBLIC 83bde483f2SJacob Faibussowitsch #define PETSC_EXTERN_TYPEDEF extern "C" 84bde483f2SJacob Faibussowitsch #define PETSC_INTERN extern "C" PETSC_VISIBILITY_INTERNAL 85bde483f2SJacob Faibussowitsch #else 86bde483f2SJacob Faibussowitsch #define PETSC_EXTERN extern PETSC_VISIBILITY_PUBLIC 87bde483f2SJacob Faibussowitsch #define PETSC_EXTERN_TYPEDEF 88bde483f2SJacob Faibussowitsch #define PETSC_INTERN extern PETSC_VISIBILITY_INTERNAL 89bde483f2SJacob Faibussowitsch #endif 90bde483f2SJacob Faibussowitsch 91bde483f2SJacob Faibussowitsch #if defined(PETSC_USE_SINGLE_LIBRARY) 92bde483f2SJacob Faibussowitsch #define PETSC_SINGLE_LIBRARY_INTERN PETSC_INTERN 93bde483f2SJacob Faibussowitsch #else 94bde483f2SJacob Faibussowitsch #define PETSC_SINGLE_LIBRARY_INTERN PETSC_EXTERN 95bde483f2SJacob Faibussowitsch #endif 96bde483f2SJacob Faibussowitsch 97bde483f2SJacob Faibussowitsch /*MC 98bde483f2SJacob Faibussowitsch PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler 99bde483f2SJacob Faibussowitsch 100bde483f2SJacob Faibussowitsch Synopsis: 101bde483f2SJacob Faibussowitsch #include <petscmacros.h> 102bde483f2SJacob Faibussowitsch boolean PetscHasAttribute(name) 103bde483f2SJacob Faibussowitsch 104bde483f2SJacob Faibussowitsch Input Parameter: 105bde483f2SJacob Faibussowitsch . name - The name of the attribute to test 106bde483f2SJacob Faibussowitsch 107bde483f2SJacob Faibussowitsch Notes: 108bde483f2SJacob Faibussowitsch name should be identical to what you might pass to the __attribute__ declaration itself -- 109bde483f2SJacob Faibussowitsch plain, unbroken text. 110bde483f2SJacob Faibussowitsch 11187497f52SBarry Smith As `PetscHasAttribute()` is wrapper over the function-like macro __has_attribute(), the exact 112bde483f2SJacob Faibussowitsch type and value returned is implementation defined. In practice however, it usually returns 113bde483f2SJacob Faibussowitsch the integer literal 1 if the attribute is supported, and integer literal 0 if the attribute 114bde483f2SJacob Faibussowitsch is not supported. 115bde483f2SJacob Faibussowitsch 116bde483f2SJacob Faibussowitsch Example Usage: 117bde483f2SJacob Faibussowitsch Typical usage is using the preprocessor 118bde483f2SJacob Faibussowitsch 119bde483f2SJacob Faibussowitsch .vb 120bde483f2SJacob Faibussowitsch #if PetscHasAttribute(always_inline) 121bde483f2SJacob Faibussowitsch # define MY_ALWAYS_INLINE __attribute__((always_inline)) 122bde483f2SJacob Faibussowitsch #else 123bde483f2SJacob Faibussowitsch # define MY_ALWAYS_INLINE 124bde483f2SJacob Faibussowitsch #endif 125bde483f2SJacob Faibussowitsch 126bde483f2SJacob Faibussowitsch void foo(void) MY_ALWAYS_INLINE; 127bde483f2SJacob Faibussowitsch .ve 128bde483f2SJacob Faibussowitsch 129bde483f2SJacob Faibussowitsch but it can also be used in regular code 130bde483f2SJacob Faibussowitsch 131bde483f2SJacob Faibussowitsch .vb 132bde483f2SJacob Faibussowitsch if (PetscHasAttribute(some_attribute)) { 133bde483f2SJacob Faibussowitsch foo(); 134bde483f2SJacob Faibussowitsch } else { 135bde483f2SJacob Faibussowitsch bar(); 136bde483f2SJacob Faibussowitsch } 137bde483f2SJacob Faibussowitsch .ve 138bde483f2SJacob Faibussowitsch 139bde483f2SJacob Faibussowitsch Level: intermediate 140bde483f2SJacob Faibussowitsch 141db781477SPatrick Sanan .seealso: `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`, `PETSC_ATTRIBUTE_FORMAT` 142bde483f2SJacob Faibussowitsch M*/ 143bde483f2SJacob Faibussowitsch #if !defined(__has_attribute) 144bde483f2SJacob Faibussowitsch #define __has_attribute(x) 0 145bde483f2SJacob Faibussowitsch #endif 146bde483f2SJacob Faibussowitsch #define PetscHasAttribute(name) __has_attribute(name) 147bde483f2SJacob Faibussowitsch 148bde483f2SJacob Faibussowitsch /*MC 14963a3b9bcSJacob Faibussowitsch PETSC_ATTRIBUTE_FORMAT - Indicate to the compiler that specified arguments should be treated 15063a3b9bcSJacob Faibussowitsch as format specifiers and checked for validity 15163a3b9bcSJacob Faibussowitsch 15263a3b9bcSJacob Faibussowitsch Synopsis: 15363a3b9bcSJacob Faibussowitsch #include <petscmacros.h> 15463a3b9bcSJacob Faibussowitsch <attribute declaration> PETSC_ATTRIBUTE_FORMAT(int strIdx, int vaArgIdx) 15563a3b9bcSJacob Faibussowitsch 15663a3b9bcSJacob Faibussowitsch Input Parameters: 15763a3b9bcSJacob Faibussowitsch + strIdx - The (1-indexed) location of the format string in the argument list 15863a3b9bcSJacob Faibussowitsch - vaArgIdx - The (1-indexed) location of the first formattable argument in the argument list 15963a3b9bcSJacob Faibussowitsch 16063a3b9bcSJacob Faibussowitsch Notes: 16163a3b9bcSJacob Faibussowitsch This function attribute causes the compiler to issue warnings when the format specifier does 16263a3b9bcSJacob Faibussowitsch not match the type of the variable that will be formatted, or when there exists a mismatch 16363a3b9bcSJacob Faibussowitsch between the number of format specifiers and variables to be formatted. It is safe to use this 16463a3b9bcSJacob Faibussowitsch macro if your compiler does not support format specifier checking (though this is 16563a3b9bcSJacob Faibussowitsch exceeedingly rare). 16663a3b9bcSJacob Faibussowitsch 16763a3b9bcSJacob Faibussowitsch Both strIdx and vaArgIdx must be compile-time constant integer literals and cannot have the 16863a3b9bcSJacob Faibussowitsch same value. 16963a3b9bcSJacob Faibussowitsch 17063a3b9bcSJacob Faibussowitsch The arguments to be formatted (and therefore checked by the compiler) must be "contiguous" in 17163a3b9bcSJacob Faibussowitsch the argument list, that is, there is no way to indicate gaps which should not be checked. 17263a3b9bcSJacob Faibussowitsch 17387497f52SBarry Smith Definition is suppressed by defining `PETSC_SKIP_ATTRIBUTE_FORMAT` prior to including PETSc 17463a3b9bcSJacob Faibussowitsch header files. In this case the macro will expand empty. 17563a3b9bcSJacob Faibussowitsch 17663a3b9bcSJacob Faibussowitsch Example Usage: 17763a3b9bcSJacob Faibussowitsch .vb 17863a3b9bcSJacob Faibussowitsch // format string is 2nd argument, variable argument list containing args is 3rd argument 17963a3b9bcSJacob Faibussowitsch void my_printf(void *obj, const char *fmt_string, ...) PETSC_ATTRIBUTE_FORMAT(2,3) 18063a3b9bcSJacob Faibussowitsch 18163a3b9bcSJacob Faibussowitsch int x = 1; 18263a3b9bcSJacob Faibussowitsch double y = 50.0; 18363a3b9bcSJacob Faibussowitsch 18463a3b9bcSJacob Faibussowitsch my_printf(NULL,"%g",x); // WARNING, format specifier does not match for 'int'! 18563a3b9bcSJacob Faibussowitsch my_printf(NULL,"%d",x,y); // WARNING, more arguments than format specifiers! 18663a3b9bcSJacob Faibussowitsch my_printf(NULL,"%d %g",x,y); // OK 18763a3b9bcSJacob Faibussowitsch .ve 18863a3b9bcSJacob Faibussowitsch 18963a3b9bcSJacob Faibussowitsch Level: developer 19063a3b9bcSJacob Faibussowitsch 191db781477SPatrick Sanan .seealso: `PETSC_ATTRIBUTE_COLD`, `PetscHasAttribute()` 19263a3b9bcSJacob Faibussowitsch M*/ 19363a3b9bcSJacob Faibussowitsch #if PetscHasAttribute(format) && !defined(PETSC_SKIP_ATTRIBUTE_FORMAT) 19463a3b9bcSJacob Faibussowitsch #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) __attribute__((format(printf, strIdx, vaArgIdx))) 19563a3b9bcSJacob Faibussowitsch #else 19663a3b9bcSJacob Faibussowitsch #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) 19763a3b9bcSJacob Faibussowitsch #endif 19863a3b9bcSJacob Faibussowitsch 19963a3b9bcSJacob Faibussowitsch /*MC 200d8e4614bSJacob Faibussowitsch PETSC_ATTRIBUTE_COLD - Indicate to the compiler that a function is very unlikely to be 201d8e4614bSJacob Faibussowitsch executed 202d8e4614bSJacob Faibussowitsch 203d8e4614bSJacob Faibussowitsch Notes: 204d8e4614bSJacob Faibussowitsch The marked function is often optimized for size rather than speed and may be grouped alongside 205d8e4614bSJacob Faibussowitsch other equally frigid routines improving code locality of lukewarm or hotter parts of program. 206d8e4614bSJacob Faibussowitsch 207d8e4614bSJacob Faibussowitsch The paths leading to cold functions are usually automatically marked as unlikely by the 208d8e4614bSJacob Faibussowitsch compiler. It may thus be useful to mark functions used to handle unlikely conditions -- such 209d8e4614bSJacob Faibussowitsch as error handlers -- as cold to improve optimization of the surrounding temperate functions. 210d8e4614bSJacob Faibussowitsch 211d8e4614bSJacob Faibussowitsch Example Usage: 212d8e4614bSJacob Faibussowitsch .vb 213d8e4614bSJacob Faibussowitsch void my_error_handler(...) PETSC_ATTRIBUTE_COLD; 214d8e4614bSJacob Faibussowitsch 215d8e4614bSJacob Faibussowitsch if (temperature < 0) { 216d8e4614bSJacob Faibussowitsch return my_error_handler(...); // chilly! 217d8e4614bSJacob Faibussowitsch } 218d8e4614bSJacob Faibussowitsch .ve 219d8e4614bSJacob Faibussowitsch 220d8e4614bSJacob Faibussowitsch Level: intermediate 221d8e4614bSJacob Faibussowitsch 222db781477SPatrick Sanan .seealso: `PetscUnlikely()`, `PetscUnlikelyDebug()`, `PetscLikely()`, `PetscLikelyDebug()`, 223db781477SPatrick Sanan `PetscUnreachable()`, `PETSC_ATTRIBUTE_FORMAT` 224d8e4614bSJacob Faibussowitsch M*/ 225d8e4614bSJacob Faibussowitsch #if PetscHasAttribute(__cold__) 226d8e4614bSJacob Faibussowitsch #define PETSC_ATTRIBUTE_COLD __attribute__((__cold__)) 227d8e4614bSJacob Faibussowitsch #elif PetscHasAttribute(cold) /* some implementations (old gcc) use no underscores */ 228d8e4614bSJacob Faibussowitsch #define PETSC_ATTRIBUTE_COLD __attribute__((cold)) 229d8e4614bSJacob Faibussowitsch #else 230d8e4614bSJacob Faibussowitsch #define PETSC_ATTRIBUTE_COLD 231d8e4614bSJacob Faibussowitsch #endif 232d8e4614bSJacob Faibussowitsch 233d8e4614bSJacob Faibussowitsch /*MC 234bde483f2SJacob Faibussowitsch PETSC_NULLPTR - Standard way of indicating a null value or pointer 235bde483f2SJacob Faibussowitsch 236bde483f2SJacob Faibussowitsch Notes: 237bde483f2SJacob Faibussowitsch Equivalent to NULL in C source, and nullptr in C++ source. Note that for the purposes of 23887497f52SBarry Smith interoperability between C and C++, setting a pointer to `PETSC_NULLPTR` in C++ is functonially 239bde483f2SJacob Faibussowitsch equivalent to setting the same pointer to NULL in C. That is to say that the following 240bde483f2SJacob Faibussowitsch expressions are equivalent\: 241bde483f2SJacob Faibussowitsch 242bde483f2SJacob Faibussowitsch .vb 243bde483f2SJacob Faibussowitsch ptr == PETSC_NULLPTR 244bde483f2SJacob Faibussowitsch ptr == NULL 245bde483f2SJacob Faibussowitsch ptr == 0 246bde483f2SJacob Faibussowitsch !ptr 247bde483f2SJacob Faibussowitsch 248bde483f2SJacob Faibussowitsch ptr = PETSC_NULLPTR 249bde483f2SJacob Faibussowitsch ptr = NULL 250bde483f2SJacob Faibussowitsch ptr = 0 251bde483f2SJacob Faibussowitsch .ve 252bde483f2SJacob Faibussowitsch 253bde483f2SJacob Faibussowitsch and for completeness' sake\: 254bde483f2SJacob Faibussowitsch 255bde483f2SJacob Faibussowitsch .vb 256bde483f2SJacob Faibussowitsch PETSC_NULLPTR == NULL 257bde483f2SJacob Faibussowitsch .ve 258bde483f2SJacob Faibussowitsch 259bde483f2SJacob Faibussowitsch Fortran Notes: 260bde483f2SJacob Faibussowitsch Not available in Fortran 261bde483f2SJacob Faibussowitsch 262bde483f2SJacob Faibussowitsch Example Usage: 263bde483f2SJacob Faibussowitsch .vb 264bde483f2SJacob Faibussowitsch // may be used in place of '\0' or other such teminators in the definition of char arrays 265bde483f2SJacob Faibussowitsch const char *const MyEnumTypes[] = { 266bde483f2SJacob Faibussowitsch "foo", 267bde483f2SJacob Faibussowitsch "bar", 268bde483f2SJacob Faibussowitsch PETSC_NULLPTR 269bde483f2SJacob Faibussowitsch }; 270bde483f2SJacob Faibussowitsch 271bde483f2SJacob Faibussowitsch // may be used to nullify objects 272bde483f2SJacob Faibussowitsch PetscObject obj = PETSC_NULLPTR; 273bde483f2SJacob Faibussowitsch 274bde483f2SJacob Faibussowitsch // may be used in any function expecting NULL 275bde483f2SJacob Faibussowitsch PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor"); 276bde483f2SJacob Faibussowitsch .ve 277bde483f2SJacob Faibussowitsch 278bde483f2SJacob Faibussowitsch Developer Notes: 27987497f52SBarry Smith `PETSC_NULLPTR` must be used in place of NULL in all C++ source files. Using NULL in source 280bde483f2SJacob Faibussowitsch files compiled with a C++ compiler may lead to unexpected side-effects in function overload 281bde483f2SJacob Faibussowitsch resolution and/or compiler warnings. 282bde483f2SJacob Faibussowitsch 283bde483f2SJacob Faibussowitsch Level: beginner 284bde483f2SJacob Faibussowitsch 285db781477SPatrick Sanan .seealso: `PETSC_CONSTEXPR_14`, `PETSC_NODISCARD` 286817da375SSatish Balay M*/ 287bde483f2SJacob Faibussowitsch 288bde483f2SJacob Faibussowitsch /*MC 289bde483f2SJacob Faibussowitsch PETSC_CONSTEXPR_14 - C++14 constexpr 290bde483f2SJacob Faibussowitsch 291bde483f2SJacob Faibussowitsch Notes: 292bde483f2SJacob Faibussowitsch Equivalent to constexpr when using a C++ compiler that supports C++14. Expands to nothing 293bde483f2SJacob Faibussowitsch if the C++ compiler does not suppport C++14 or when not compiling with a C++ compiler. Note 294bde483f2SJacob Faibussowitsch that this cannot be used in cases where an empty expansion would result in invalid code. It 295bde483f2SJacob Faibussowitsch is safe to use this in C source files. 296bde483f2SJacob Faibussowitsch 297bde483f2SJacob Faibussowitsch Fortran Notes: 298bde483f2SJacob Faibussowitsch Not available in Fortran 299bde483f2SJacob Faibussowitsch 300bde483f2SJacob Faibussowitsch Example Usage: 301bde483f2SJacob Faibussowitsch .vb 302bde483f2SJacob Faibussowitsch PETSC_CONSTEXPR_14 int factorial(int n) 303bde483f2SJacob Faibussowitsch { 304bde483f2SJacob Faibussowitsch int r = 1; 305bde483f2SJacob Faibussowitsch 306bde483f2SJacob Faibussowitsch do { 307bde483f2SJacob Faibussowitsch r *= n; 308bde483f2SJacob Faibussowitsch } while (--n); 309bde483f2SJacob Faibussowitsch return r; 310bde483f2SJacob Faibussowitsch } 311bde483f2SJacob Faibussowitsch .ve 312bde483f2SJacob Faibussowitsch 313bde483f2SJacob Faibussowitsch Level: beginner 314bde483f2SJacob Faibussowitsch 315db781477SPatrick Sanan .seealso: `PETSC_NULLPTR`, `PETSC_NODISCARD` 316817da375SSatish Balay M*/ 317bde483f2SJacob Faibussowitsch 318bde483f2SJacob Faibussowitsch /*MC 319bde483f2SJacob Faibussowitsch PETSC_NODISCARD - Mark the return value of a function as non-discardable 320bde483f2SJacob Faibussowitsch 321bde483f2SJacob Faibussowitsch Notes: 322bde483f2SJacob Faibussowitsch Hints to the compiler that the return value of a function must be captured. A diagnostic may 323bde483f2SJacob Faibussowitsch (but is not required) be emitted if the value is discarded. It is safe to use this in C 324bde483f2SJacob Faibussowitsch and C++ source files. 325bde483f2SJacob Faibussowitsch 326bde483f2SJacob Faibussowitsch Fortran Notes: 327bde483f2SJacob Faibussowitsch Not available in Fortran 328bde483f2SJacob Faibussowitsch 329bde483f2SJacob Faibussowitsch Example Usage: 330bde483f2SJacob Faibussowitsch .vb 331bde483f2SJacob Faibussowitsch class Foo 332bde483f2SJacob Faibussowitsch { 333bde483f2SJacob Faibussowitsch int x; 334bde483f2SJacob Faibussowitsch 335bde483f2SJacob Faibussowitsch public: 336bde483f2SJacob Faibussowitsch PETSC_NODISCARD Foo(int y) : x(y) { } 337bde483f2SJacob Faibussowitsch }; 338bde483f2SJacob Faibussowitsch 339bde483f2SJacob Faibussowitsch PETSC_NODISCARD int factorial(int n) 340bde483f2SJacob Faibussowitsch { 341bde483f2SJacob Faibussowitsch return n <= 1 ? 1 : (n * factorial(n - 1)); 342bde483f2SJacob Faibussowitsch } 343bde483f2SJacob Faibussowitsch 344bde483f2SJacob Faibussowitsch auto x = factorial(10); // OK, capturing return value 345bde483f2SJacob Faibussowitsch factorial(10); // Warning: ignoring return value of function declared 'nodiscard' 346bde483f2SJacob Faibussowitsch 347bde483f2SJacob Faibussowitsch auto f = Foo(x); // OK, capturing constructed object 348bde483f2SJacob Faibussowitsch Foo(x); // Warning: Ignoring temporary created by a constructor declared 'nodiscard' 349bde483f2SJacob Faibussowitsch .ve 350bde483f2SJacob Faibussowitsch 351bde483f2SJacob Faibussowitsch Developer Notes: 352bde483f2SJacob Faibussowitsch It is highly recommended if not downright required that any PETSc routines written in C++ 35387497f52SBarry Smith returning a PetscErrorCode be marked `PETSC_NODISCARD`. Ignoring the return value of PETSc 354bde483f2SJacob Faibussowitsch routines is not supported; unhandled errors may leave PETSc in an unrecoverable state. 355bde483f2SJacob Faibussowitsch 356bde483f2SJacob Faibussowitsch Level: beginner 357bde483f2SJacob Faibussowitsch 358db781477SPatrick Sanan .seealso: `PETSC_NULLPTR`, `PETSC_CONSTEXPR_14` 359817da375SSatish Balay M*/ 360bde483f2SJacob Faibussowitsch 361bde483f2SJacob Faibussowitsch /* C++11 features */ 3626ee8c794SJacob Faibussowitsch #if defined(__cplusplus) 363bde483f2SJacob Faibussowitsch #define PETSC_NULLPTR nullptr 364bde483f2SJacob Faibussowitsch #else 365bde483f2SJacob Faibussowitsch #define PETSC_NULLPTR NULL 366bde483f2SJacob Faibussowitsch #endif 367bde483f2SJacob Faibussowitsch 368bde483f2SJacob Faibussowitsch /* C++14 features */ 369*0e6b6b59SJacob Faibussowitsch #if PETSC_CPP_VERSION >= 14 3706ee8c794SJacob Faibussowitsch #define PETSC_CONSTEXPR_14 constexpr 371bde483f2SJacob Faibussowitsch #else 372bde483f2SJacob Faibussowitsch #define PETSC_CONSTEXPR_14 373bde483f2SJacob Faibussowitsch #endif 374bde483f2SJacob Faibussowitsch 375bde483f2SJacob Faibussowitsch /* C++17 features */ 376*0e6b6b59SJacob Faibussowitsch #if PETSC_CPP_VERSION >= 17 377bde483f2SJacob Faibussowitsch #define PETSC_NODISCARD [[nodiscard]] 378*0e6b6b59SJacob Faibussowitsch #define PETSC_CONSTEXPR_17 constexpr 379bde483f2SJacob Faibussowitsch #else 380bde483f2SJacob Faibussowitsch #if PetscHasAttribute(warn_unused_result) 381bde483f2SJacob Faibussowitsch #define PETSC_NODISCARD __attribute__((warn_unused_result)) 382bde483f2SJacob Faibussowitsch #endif 383*0e6b6b59SJacob Faibussowitsch #define PETSC_CONSTEXPR_17 384*0e6b6b59SJacob Faibussowitsch #endif 385*0e6b6b59SJacob Faibussowitsch 386*0e6b6b59SJacob Faibussowitsch #ifndef PETSC_NODISCARD 387*0e6b6b59SJacob Faibussowitsch #define PETSC_NODISCARD 388bde483f2SJacob Faibussowitsch #endif 389bde483f2SJacob Faibussowitsch 390bde483f2SJacob Faibussowitsch #include <petscversion.h> 391bde483f2SJacob Faibussowitsch #define PETSC_AUTHOR_INFO " The PETSc Team\n petsc-maint@mcs.anl.gov\n https://petsc.org/\n" 392bde483f2SJacob Faibussowitsch 393267267bdSJacob Faibussowitsch /* designated initializers since C99 and C++20, MSVC never supports them though */ 394*0e6b6b59SJacob Faibussowitsch #if defined(_MSC_VER) || (defined(__cplusplus) && (PETSC_CPP_VERSION < 20)) 395267267bdSJacob Faibussowitsch #define PetscDesignatedInitializer(name, ...) __VA_ARGS__ 396267267bdSJacob Faibussowitsch #else 397267267bdSJacob Faibussowitsch #define PetscDesignatedInitializer(name, ...) .name = __VA_ARGS__ 398267267bdSJacob Faibussowitsch #endif 399267267bdSJacob Faibussowitsch 400bde483f2SJacob Faibussowitsch /*MC 40187497f52SBarry Smith PetscUnlikely - Hints the compiler that the given condition is usually false 402bde483f2SJacob Faibussowitsch 403bde483f2SJacob Faibussowitsch Synopsis: 404bde483f2SJacob Faibussowitsch #include <petscmacros.h> 405bde483f2SJacob Faibussowitsch bool PetscUnlikely(bool cond) 406bde483f2SJacob Faibussowitsch 407bde483f2SJacob Faibussowitsch Not Collective 408bde483f2SJacob Faibussowitsch 409bde483f2SJacob Faibussowitsch Input Parameter: 410bde483f2SJacob Faibussowitsch . cond - Boolean expression 411bde483f2SJacob Faibussowitsch 412bde483f2SJacob Faibussowitsch Notes: 413bde483f2SJacob Faibussowitsch Not available from fortran. 414bde483f2SJacob Faibussowitsch 415bde483f2SJacob Faibussowitsch This returns the same truth value, it is only a hint to compilers that the result of cond is 416bde483f2SJacob Faibussowitsch unlikely to be true. 417bde483f2SJacob Faibussowitsch 418bde483f2SJacob Faibussowitsch Example usage: 419bde483f2SJacob Faibussowitsch .vb 420bde483f2SJacob Faibussowitsch if (PetscUnlikely(cond)) { 421bde483f2SJacob Faibussowitsch foo(); // cold path 422bde483f2SJacob Faibussowitsch } else { 423bde483f2SJacob Faibussowitsch bar(); // hot path 424bde483f2SJacob Faibussowitsch } 425bde483f2SJacob Faibussowitsch .ve 426bde483f2SJacob Faibussowitsch 427bde483f2SJacob Faibussowitsch Level: advanced 428bde483f2SJacob Faibussowitsch 429db781477SPatrick Sanan .seealso: `PetscLikely()`, `PetscUnlikelyDebug()`, `PetscCall()`, `PetscDefined()`, `PetscHasAttribute()`, 430db781477SPatrick Sanan `PETSC_ATTRIBUTE_COLD` 431bde483f2SJacob Faibussowitsch M*/ 432bde483f2SJacob Faibussowitsch 433bde483f2SJacob Faibussowitsch /*MC 43487497f52SBarry Smith PetscLikely - Hints the compiler that the given condition is usually true 435bde483f2SJacob Faibussowitsch 436bde483f2SJacob Faibussowitsch Synopsis: 437bde483f2SJacob Faibussowitsch #include <petscmacros.h> 438bde483f2SJacob Faibussowitsch bool PetscLikely(bool cond) 439bde483f2SJacob Faibussowitsch 440bde483f2SJacob Faibussowitsch Not Collective 441bde483f2SJacob Faibussowitsch 442bde483f2SJacob Faibussowitsch Input Parameter: 443bde483f2SJacob Faibussowitsch . cond - Boolean expression 444bde483f2SJacob Faibussowitsch 445bde483f2SJacob Faibussowitsch Notes: 446bde483f2SJacob Faibussowitsch Not available from fortran. 447bde483f2SJacob Faibussowitsch 448bde483f2SJacob Faibussowitsch This returns the same truth value, it is only a hint to compilers that the result of cond is 449bde483f2SJacob Faibussowitsch likely to be true. 450bde483f2SJacob Faibussowitsch 451bde483f2SJacob Faibussowitsch Example usage: 452bde483f2SJacob Faibussowitsch .vb 453bde483f2SJacob Faibussowitsch if (PetscLikely(cond)) { 454bde483f2SJacob Faibussowitsch foo(); // hot path 455bde483f2SJacob Faibussowitsch } else { 456bde483f2SJacob Faibussowitsch bar(); // cold path 457bde483f2SJacob Faibussowitsch } 458bde483f2SJacob Faibussowitsch .ve 459bde483f2SJacob Faibussowitsch 460bde483f2SJacob Faibussowitsch Level: advanced 461bde483f2SJacob Faibussowitsch 462db781477SPatrick Sanan .seealso: `PetscUnlikely()`, `PetscDefined()`, `PetscHasAttribute()` 463db781477SPatrick Sanan `PETSC_ATTRIBUTE_COLD` 464bde483f2SJacob Faibussowitsch M*/ 465bde483f2SJacob Faibussowitsch #if defined(PETSC_HAVE_BUILTIN_EXPECT) 466bde483f2SJacob Faibussowitsch #define PetscUnlikely(cond) __builtin_expect(!!(cond), 0) 467bde483f2SJacob Faibussowitsch #define PetscLikely(cond) __builtin_expect(!!(cond), 1) 468bde483f2SJacob Faibussowitsch #else 469bde483f2SJacob Faibussowitsch #define PetscUnlikely(cond) (cond) 470bde483f2SJacob Faibussowitsch #define PetscLikely(cond) (cond) 471bde483f2SJacob Faibussowitsch #endif 472bde483f2SJacob Faibussowitsch 473bde483f2SJacob Faibussowitsch /*MC 474817da375SSatish Balay PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable 475bde483f2SJacob Faibussowitsch 476bde483f2SJacob Faibussowitsch Synopsis: 477bde483f2SJacob Faibussowitsch #include <petscmacros.h> 478bde483f2SJacob Faibussowitsch void PetscUnreachable(void) 479bde483f2SJacob Faibussowitsch 480bde483f2SJacob Faibussowitsch Notes: 481bde483f2SJacob Faibussowitsch Indicates to the compiler (usually via some built-in) that a particular code path is always 482bde483f2SJacob Faibussowitsch unreachable. Behavior is undefined if this function is ever executed, the user can expect an 483bde483f2SJacob Faibussowitsch unceremonious crash. 484bde483f2SJacob Faibussowitsch 485bde483f2SJacob Faibussowitsch Example usage: 486bde483f2SJacob Faibussowitsch Useful in situations such as switches over enums where not all enumeration values are 487bde483f2SJacob Faibussowitsch explicitly covered by the switch 488bde483f2SJacob Faibussowitsch 489bde483f2SJacob Faibussowitsch .vb 490bde483f2SJacob Faibussowitsch typedef enum {RED, GREEN, BLUE} Color; 491bde483f2SJacob Faibussowitsch 492bde483f2SJacob Faibussowitsch int foo(Color c) 493bde483f2SJacob Faibussowitsch { 494bde483f2SJacob Faibussowitsch // it is known to programmer (or checked previously) that c is either RED or GREEN 495bde483f2SJacob Faibussowitsch // but compiler may not be able to deduce this and/or emit spurious warnings 496bde483f2SJacob Faibussowitsch switch (c) { 497bde483f2SJacob Faibussowitsch case RED: 498bde483f2SJacob Faibussowitsch return bar(); 499bde483f2SJacob Faibussowitsch case GREEN: 500bde483f2SJacob Faibussowitsch return baz(); 501bde483f2SJacob Faibussowitsch default: 502bde483f2SJacob Faibussowitsch PetscUnreachable(); // program is ill-formed if executed 503bde483f2SJacob Faibussowitsch } 504bde483f2SJacob Faibussowitsch } 505bde483f2SJacob Faibussowitsch .ve 506bde483f2SJacob Faibussowitsch 507bde483f2SJacob Faibussowitsch Level: advanced 508bde483f2SJacob Faibussowitsch 509db781477SPatrick Sanan .seealso: `SETERRABORT()`, `PETSCABORT()`, `PETSC_ATTRIBUTE_COLD` 510817da375SSatish Balay M*/ 511e58a63e1SJacob Faibussowitsch #if defined(__GNUC__) 512e58a63e1SJacob Faibussowitsch /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */ 513e58a63e1SJacob Faibussowitsch #define PetscUnreachable() __builtin_unreachable() 514e58a63e1SJacob Faibussowitsch #elif defined(_MSC_VER) /* MSVC */ 515e58a63e1SJacob Faibussowitsch #define PetscUnreachable() __assume(0) 516e58a63e1SJacob Faibussowitsch #else /* ??? */ 517e58a63e1SJacob Faibussowitsch #define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Code path explicitly marked as unreachable executed") 518e58a63e1SJacob Faibussowitsch #endif 519bde483f2SJacob Faibussowitsch 520bde483f2SJacob Faibussowitsch /*MC 521bde483f2SJacob Faibussowitsch PetscExpand - Expand macro argument 522bde483f2SJacob Faibussowitsch 523bde483f2SJacob Faibussowitsch Synopsis: 524bde483f2SJacob Faibussowitsch #include <petscmacros.h> 525bde483f2SJacob Faibussowitsch <macro-expansion> PetscExpand(x) 526bde483f2SJacob Faibussowitsch 5276aad120cSJose E. Roman Input Parameter: 528bde483f2SJacob Faibussowitsch . x - The preprocessor token to expand 529bde483f2SJacob Faibussowitsch 53049762cbcSSatish Balay Level: beginner 53149762cbcSSatish Balay 532db781477SPatrick Sanan .seealso: `PetscStringize()`, `PetscConcat()` 533817da375SSatish Balay M*/ 534e58a63e1SJacob Faibussowitsch #define PetscExpand_(...) __VA_ARGS__ 535e58a63e1SJacob Faibussowitsch #define PetscExpand(...) PetscExpand_(__VA_ARGS__) 536bde483f2SJacob Faibussowitsch 537bde483f2SJacob Faibussowitsch /*MC 538bde483f2SJacob Faibussowitsch PetscStringize - Stringize a token 539bde483f2SJacob Faibussowitsch 540bde483f2SJacob Faibussowitsch Synopsis: 541bde483f2SJacob Faibussowitsch #include <petscmacros.h> 542bde483f2SJacob Faibussowitsch const char* PetscStringize(x) 543bde483f2SJacob Faibussowitsch 544bde483f2SJacob Faibussowitsch Input Parameter: 545bde483f2SJacob Faibussowitsch . x - The token you would like to stringize 546bde483f2SJacob Faibussowitsch 547bde483f2SJacob Faibussowitsch Output Parameter: 548bde483f2SJacob Faibussowitsch . <return-value> - The string representation of x 549bde483f2SJacob Faibussowitsch 550bde483f2SJacob Faibussowitsch Notes: 551bde483f2SJacob Faibussowitsch Not available from Fortran. 552bde483f2SJacob Faibussowitsch 553bde483f2SJacob Faibussowitsch PetscStringize() expands x before stringizing it, if you do not wish to do so, use 554bde483f2SJacob Faibussowitsch PetscStringize_() instead. 555bde483f2SJacob Faibussowitsch 556bde483f2SJacob Faibussowitsch Example Usage: 557bde483f2SJacob Faibussowitsch .vb 558bde483f2SJacob Faibussowitsch #define MY_OTHER_VAR hello there 559bde483f2SJacob Faibussowitsch #define MY_VAR MY_OTHER_VAR 560bde483f2SJacob Faibussowitsch 561bde483f2SJacob Faibussowitsch PetscStringize(MY_VAR) -> "hello there" 562bde483f2SJacob Faibussowitsch PetscStringize_(MY_VAR) -> "MY_VAR" 563bde483f2SJacob Faibussowitsch 564bde483f2SJacob Faibussowitsch int foo; 565bde483f2SJacob Faibussowitsch PetscStringize(foo) -> "foo" 566bde483f2SJacob Faibussowitsch PetscStringize_(foo) -> "foo" 567bde483f2SJacob Faibussowitsch .ve 568bde483f2SJacob Faibussowitsch 569bde483f2SJacob Faibussowitsch Level: beginner 570bde483f2SJacob Faibussowitsch 571db781477SPatrick Sanan .seealso: `PetscConcat()`, `PetscExpandToNothing()`, `PetscExpand()` 572817da375SSatish Balay M*/ 573*0e6b6b59SJacob Faibussowitsch #define PetscStringize_(...) #__VA_ARGS__ 574*0e6b6b59SJacob Faibussowitsch #define PetscStringize(...) PetscStringize_(__VA_ARGS__) 575bde483f2SJacob Faibussowitsch 576bde483f2SJacob Faibussowitsch /*MC 577bde483f2SJacob Faibussowitsch PetscConcat - Concatenate two tokens 578bde483f2SJacob Faibussowitsch 579bde483f2SJacob Faibussowitsch Synopsis: 580bde483f2SJacob Faibussowitsch #include <petscmacros.h> 581bde483f2SJacob Faibussowitsch <macro-expansion> PetscConcat(x, y) 582bde483f2SJacob Faibussowitsch 583bde483f2SJacob Faibussowitsch Input Parameters: 584bde483f2SJacob Faibussowitsch + x - First token 585bde483f2SJacob Faibussowitsch - y - Second token 586bde483f2SJacob Faibussowitsch 587bde483f2SJacob Faibussowitsch Notes: 588bde483f2SJacob Faibussowitsch Not available from Fortran. 589bde483f2SJacob Faibussowitsch 590bde483f2SJacob Faibussowitsch PetscConcat() will expand both arguments before pasting them together, use PetscConcat_() 591bde483f2SJacob Faibussowitsch if you don't want to expand them. 592bde483f2SJacob Faibussowitsch 593bde483f2SJacob Faibussowitsch Example usage: 594bde483f2SJacob Faibussowitsch .vb 595bde483f2SJacob Faibussowitsch PetscConcat(hello,there) -> hellothere 596bde483f2SJacob Faibussowitsch 597bde483f2SJacob Faibussowitsch #define HELLO hello 598bde483f2SJacob Faibussowitsch PetscConcat(HELLO,there) -> hellothere 599bde483f2SJacob Faibussowitsch PetscConcat_(HELLO,there) -> HELLOthere 600bde483f2SJacob Faibussowitsch .ve 601bde483f2SJacob Faibussowitsch 602bde483f2SJacob Faibussowitsch Level: beginner 603bde483f2SJacob Faibussowitsch 604db781477SPatrick Sanan .seealso: `PetscStringize()`, `PetscExpand()` 605817da375SSatish Balay M*/ 606bde483f2SJacob Faibussowitsch #define PetscConcat_(x, y) x##y 607bde483f2SJacob Faibussowitsch #define PetscConcat(x, y) PetscConcat_(x, y) 608bde483f2SJacob Faibussowitsch 609bde483f2SJacob Faibussowitsch #define PETSC_INTERNAL_COMPL_0 1 610bde483f2SJacob Faibussowitsch #define PETSC_INTERNAL_COMPL_1 0 611bde483f2SJacob Faibussowitsch 612bde483f2SJacob Faibussowitsch /*MC 613bde483f2SJacob Faibussowitsch PetscCompl - Expands to the integer complement of its argument 614bde483f2SJacob Faibussowitsch 615bde483f2SJacob Faibussowitsch Synopsis: 616bde483f2SJacob Faibussowitsch #include <petscmacros.h> 617bde483f2SJacob Faibussowitsch int PetscCompl(b) 618bde483f2SJacob Faibussowitsch 619bde483f2SJacob Faibussowitsch Input Parameter: 620bde483f2SJacob Faibussowitsch . b - Preprocessor variable, must expand to either integer literal 0 or 1 621bde483f2SJacob Faibussowitsch 6226aad120cSJose E. Roman Output Parameter: 623bde483f2SJacob Faibussowitsch . <return-value> - Either integer literal 0 or 1 624bde483f2SJacob Faibussowitsch 625bde483f2SJacob Faibussowitsch Notes: 626bde483f2SJacob Faibussowitsch Not available from Fortran. 627bde483f2SJacob Faibussowitsch 628bde483f2SJacob Faibussowitsch Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to 629bde483f2SJacob Faibussowitsch 0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its 630bde483f2SJacob Faibussowitsch argument before returning the complement. 631bde483f2SJacob Faibussowitsch 632bde483f2SJacob Faibussowitsch This macro can be useful for negating PetscDefined() inside macros e.g. 633bde483f2SJacob Faibussowitsch 634bde483f2SJacob Faibussowitsch $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO)) 635bde483f2SJacob Faibussowitsch 636bde483f2SJacob Faibussowitsch Example usage: 637bde483f2SJacob Faibussowitsch .vb 638bde483f2SJacob Faibussowitsch #define MY_VAR 1 639bde483f2SJacob Faibussowitsch PetscCompl(MY_VAR) -> 0 640bde483f2SJacob Faibussowitsch 641bde483f2SJacob Faibussowitsch #undef MY_VAR 642bde483f2SJacob Faibussowitsch #define MY_VAR 0 643bde483f2SJacob Faibussowitsch PetscCompl(MY_VAR) -> 1 644bde483f2SJacob Faibussowitsch .ve 645bde483f2SJacob Faibussowitsch 646bde483f2SJacob Faibussowitsch Level: beginner 647bde483f2SJacob Faibussowitsch 648db781477SPatrick Sanan .seealso: `PetscConcat()`, `PetscDefined()` 649817da375SSatish Balay M*/ 650bde483f2SJacob Faibussowitsch #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_, PetscExpand(b)) 651bde483f2SJacob Faibussowitsch 652bde483f2SJacob Faibussowitsch #if !defined(PETSC_SKIP_VARIADIC_MACROS) 653bde483f2SJacob Faibussowitsch /*MC 654bde483f2SJacob Faibussowitsch PetscDefined - Determine whether a boolean macro is defined 655bde483f2SJacob Faibussowitsch 656bde483f2SJacob Faibussowitsch Synopsis: 657bde483f2SJacob Faibussowitsch #include <petscmacros.h> 658bde483f2SJacob Faibussowitsch int PetscDefined(def) 659bde483f2SJacob Faibussowitsch 660bde483f2SJacob Faibussowitsch Input Parameter: 661bde483f2SJacob Faibussowitsch . def - PETSc-style preprocessor variable (without PETSC_ prepended!) 662bde483f2SJacob Faibussowitsch 663bde483f2SJacob Faibussowitsch Outut Parameter: 664bde483f2SJacob Faibussowitsch . <return-value> - Either integer literal 0 or 1 665bde483f2SJacob Faibussowitsch 666bde483f2SJacob Faibussowitsch Notes: 667bde483f2SJacob Faibussowitsch Not available from Fortran, requires variadic macro support, definition is disabled by 66887497f52SBarry Smith defining `PETSC_SKIP_VARIADIC_MACROS`. 669bde483f2SJacob Faibussowitsch 67087497f52SBarry Smith `PetscDefined()` returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to 67187497f52SBarry Smith integer literal 1. In all other cases, `PetscDefined()` returns integer literal 0. Therefore 672bde483f2SJacob Faibussowitsch this macro should not be used if its argument may be defined to a non-empty value other than 673bde483f2SJacob Faibussowitsch 1. 674bde483f2SJacob Faibussowitsch 675bde483f2SJacob Faibussowitsch The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to 67687497f52SBarry Smith add custom checks in user code, one should use `PetscDefined_()`. 677bde483f2SJacob Faibussowitsch 678bde483f2SJacob Faibussowitsch $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d)) 679bde483f2SJacob Faibussowitsch 680bde483f2SJacob Faibussowitsch Developer Notes: 681bde483f2SJacob Faibussowitsch Getting something that works in C and CPP for an arg that may or may not be defined is 682bde483f2SJacob Faibussowitsch tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define, 683bde483f2SJacob Faibussowitsch insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks 684bde483f2SJacob Faibussowitsch the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair, 685bde483f2SJacob Faibussowitsch and when the last step cherry picks the 2nd arg, we get a zero. 686bde483f2SJacob Faibussowitsch 687bde483f2SJacob Faibussowitsch Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a 688bde483f2SJacob Faibussowitsch nonconforming implementation of variadic macros. 689bde483f2SJacob Faibussowitsch 690bde483f2SJacob Faibussowitsch Example Usage: 691bde483f2SJacob Faibussowitsch Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG 692bde483f2SJacob Faibussowitsch is defined then 693bde483f2SJacob Faibussowitsch 694bde483f2SJacob Faibussowitsch .vb 695bde483f2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG) 696bde483f2SJacob Faibussowitsch foo(); 697bde483f2SJacob Faibussowitsch #else 698bde483f2SJacob Faibussowitsch bar(); 699bde483f2SJacob Faibussowitsch #endif 700bde483f2SJacob Faibussowitsch 701bde483f2SJacob Faibussowitsch // or alternatively within normal code 702bde483f2SJacob Faibussowitsch if (PetscDefined(USE_DEBUG)) { 703bde483f2SJacob Faibussowitsch foo(); 704bde483f2SJacob Faibussowitsch } else { 705bde483f2SJacob Faibussowitsch bar(); 706bde483f2SJacob Faibussowitsch } 707bde483f2SJacob Faibussowitsch .ve 708bde483f2SJacob Faibussowitsch 709bde483f2SJacob Faibussowitsch is equivalent to 710bde483f2SJacob Faibussowitsch 711bde483f2SJacob Faibussowitsch .vb 712bde483f2SJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) 713bde483f2SJacob Faibussowitsch # if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro 714bde483f2SJacob Faibussowitsch foo(); 715bde483f2SJacob Faibussowitsch # elif PETSC_USE_DEBUG == 1 716bde483f2SJacob Faibussowitsch foo(); 717bde483f2SJacob Faibussowitsch # else 718bde483f2SJacob Faibussowitsch bar(); 719bde483f2SJacob Faibussowitsch # endif 720bde483f2SJacob Faibussowitsch #else 721bde483f2SJacob Faibussowitsch bar(); 722bde483f2SJacob Faibussowitsch #endif 723bde483f2SJacob Faibussowitsch .ve 724bde483f2SJacob Faibussowitsch 725bde483f2SJacob Faibussowitsch Level: intermediate 726bde483f2SJacob Faibussowitsch 727db781477SPatrick Sanan .seealso: `PetscHasAttribute()`, `PetscUnlikely()`, `PetscLikely()`, `PetscConcat()`, 728db781477SPatrick Sanan `PetscExpandToNothing()`, `PetscCompl()` 729817da375SSatish Balay M*/ 730bde483f2SJacob Faibussowitsch #define PetscDefined_arg_1 shift, 731bde483f2SJacob Faibussowitsch #define PetscDefined_arg_ shift, 732bde483f2SJacob Faibussowitsch #define PetscDefined__take_second_expanded(ignored, val, ...) val 733bde483f2SJacob Faibussowitsch #define PetscDefined__take_second_expand(args) PetscDefined__take_second_expanded args 734bde483f2SJacob Faibussowitsch #define PetscDefined__take_second(...) PetscDefined__take_second_expand((__VA_ARGS__)) 735bde483f2SJacob Faibussowitsch #define PetscDefined__(arg1_or_junk) PetscDefined__take_second(arg1_or_junk 1, 0, at_) 736bde483f2SJacob Faibussowitsch #define PetscDefined_(value) PetscDefined__(PetscConcat_(PetscDefined_arg_, value)) 737bde483f2SJacob Faibussowitsch #define PetscDefined(def) PetscDefined_(PetscConcat(PETSC_, def)) 738bde483f2SJacob Faibussowitsch 739bde483f2SJacob Faibussowitsch /*MC 74087497f52SBarry Smith PetscUnlikelyDebug - Hints the compiler that the given condition is usually false, eliding 741bde483f2SJacob Faibussowitsch the check in optimized mode 742bde483f2SJacob Faibussowitsch 743bde483f2SJacob Faibussowitsch Synopsis: 744bde483f2SJacob Faibussowitsch #include <petscmacros.h> 745bde483f2SJacob Faibussowitsch bool PetscUnlikelyDebug(bool cond) 746bde483f2SJacob Faibussowitsch 747bde483f2SJacob Faibussowitsch Not Collective 748bde483f2SJacob Faibussowitsch 749bde483f2SJacob Faibussowitsch Input Parameters: 750bde483f2SJacob Faibussowitsch . cond - Boolean expression 751bde483f2SJacob Faibussowitsch 752bde483f2SJacob Faibussowitsch Notes: 753bde483f2SJacob Faibussowitsch Not available from Fortran, requires variadic macro support, definition is disabled by 75487497f52SBarry Smith defining `PETSC_SKIP_VARIADIC_MACROS`. 755bde483f2SJacob Faibussowitsch 756bde483f2SJacob Faibussowitsch This returns the same truth value, it is only a hint to compilers that the result of cond is 757bde483f2SJacob Faibussowitsch likely to be false. When PETSc is compiled in optimized mode this will always return 758bde483f2SJacob Faibussowitsch false. Additionally, cond is guaranteed to not be evaluated when PETSc is compiled in 759bde483f2SJacob Faibussowitsch optimized mode. 760bde483f2SJacob Faibussowitsch 761bde483f2SJacob Faibussowitsch Example usage: 762bde483f2SJacob Faibussowitsch This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG) 763bde483f2SJacob Faibussowitsch is true. So 764bde483f2SJacob Faibussowitsch 765bde483f2SJacob Faibussowitsch .vb 766bde483f2SJacob Faibussowitsch if (PetscUnlikelyDebug(cond)) { 767bde483f2SJacob Faibussowitsch foo(); 768bde483f2SJacob Faibussowitsch } else { 769bde483f2SJacob Faibussowitsch bar(); 770bde483f2SJacob Faibussowitsch } 771bde483f2SJacob Faibussowitsch .ve 772bde483f2SJacob Faibussowitsch 773bde483f2SJacob Faibussowitsch is equivalent to 774bde483f2SJacob Faibussowitsch 775bde483f2SJacob Faibussowitsch .vb 776bde483f2SJacob Faibussowitsch if (PetscDefined(USE_DEBUG)) { 777bde483f2SJacob Faibussowitsch if (PetscUnlikely(cond)) { 778bde483f2SJacob Faibussowitsch foo(); 779bde483f2SJacob Faibussowitsch } else { 780bde483f2SJacob Faibussowitsch bar(); 781bde483f2SJacob Faibussowitsch } 782bde483f2SJacob Faibussowitsch } else { 783bde483f2SJacob Faibussowitsch bar(); 784bde483f2SJacob Faibussowitsch } 785bde483f2SJacob Faibussowitsch .ve 786bde483f2SJacob Faibussowitsch 787bde483f2SJacob Faibussowitsch Level: advanced 788bde483f2SJacob Faibussowitsch 789db781477SPatrick Sanan .seealso: `PetscUnlikely()`, `PetscLikely()`, `PetscCall()`, `SETERRQ` 790bde483f2SJacob Faibussowitsch M*/ 791bde483f2SJacob Faibussowitsch #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond)) 792bde483f2SJacob Faibussowitsch 793f7e3c444SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER) 794f7e3c444SJacob Faibussowitsch // silence compiler warnings when using -pedantic, this is only used by the linter and it cares 795f7e3c444SJacob Faibussowitsch // not what ISO C allows 7969371c9d4SSatish Balay #define PetscMacroReturns_(retexpr, ...) \ 7979371c9d4SSatish Balay __extension__({ \ 7989371c9d4SSatish Balay __VA_ARGS__; \ 7999371c9d4SSatish Balay retexpr; \ 8009371c9d4SSatish Balay }) 801f7e3c444SJacob Faibussowitsch #else 8029371c9d4SSatish Balay #define PetscMacroReturns_(retexpr, ...) \ 8039371c9d4SSatish Balay retexpr; \ 8049371c9d4SSatish Balay do { __VA_ARGS__; } while (0) 805f7e3c444SJacob Faibussowitsch #endif 806f7e3c444SJacob Faibussowitsch 807bde483f2SJacob Faibussowitsch /*MC 808bde483f2SJacob Faibussowitsch PetscExpandToNothing - Expands to absolutely nothing at all 809bde483f2SJacob Faibussowitsch 810bde483f2SJacob Faibussowitsch Synopsis: 811bde483f2SJacob Faibussowitsch #include <petscmacros.h> 812bde483f2SJacob Faibussowitsch void PetscExpandToNothing(...) 813bde483f2SJacob Faibussowitsch 814bde483f2SJacob Faibussowitsch Input Parameter: 815bde483f2SJacob Faibussowitsch . __VA_ARGS__ - Anything at all 816bde483f2SJacob Faibussowitsch 817bde483f2SJacob Faibussowitsch Notes: 818bde483f2SJacob Faibussowitsch Not available from Fortran, requires variadic macro support, definition is disabled by 81987497f52SBarry Smith defining `PETSC_SKIP_VARIADIC_MACROS`. 820bde483f2SJacob Faibussowitsch 821bde483f2SJacob Faibussowitsch Must have at least 1 parameter. 822bde483f2SJacob Faibussowitsch 823bde483f2SJacob Faibussowitsch Example usage: 824bde483f2SJacob Faibussowitsch .vb 825bde483f2SJacob Faibussowitsch PetscExpandToNothing(a,b,c) -> *nothing* 826bde483f2SJacob Faibussowitsch .ve 827bde483f2SJacob Faibussowitsch 828bde483f2SJacob Faibussowitsch Level: beginner 829bde483f2SJacob Faibussowitsch 830db781477SPatrick Sanan .seealso: `PetscConcat()`, `PetscDefined()`, `PetscStringize()`, `PetscExpand()` 831817da375SSatish Balay M*/ 832bde483f2SJacob Faibussowitsch #define PetscExpandToNothing(...) 833f7e3c444SJacob Faibussowitsch 834f7e3c444SJacob Faibussowitsch /*MC 835f7e3c444SJacob Faibussowitsch PetscMacroReturns - Define a macro body that returns a value 836f7e3c444SJacob Faibussowitsch 837f7e3c444SJacob Faibussowitsch Synopsis: 838f7e3c444SJacob Faibussowitsch #include <petscmacros.h> 839f7e3c444SJacob Faibussowitsch return_type PetscMacroReturns(return_type retexpr, ...) 840f7e3c444SJacob Faibussowitsch 841f7e3c444SJacob Faibussowitsch Input Parameters: 842f7e3c444SJacob Faibussowitsch + retexpr - The value or expression that the macro should return 843f7e3c444SJacob Faibussowitsch - __VA_ARGS__ - The body of the macro 844f7e3c444SJacob Faibussowitsch 845f7e3c444SJacob Faibussowitsch Notes: 846f7e3c444SJacob Faibussowitsch Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the 847f7e3c444SJacob Faibussowitsch body of the macro and should not depend on values produced as a result of the expression. The 848f7e3c444SJacob Faibussowitsch user should not assume that the result of this macro is equivalent to a single logical source 849f7e3c444SJacob Faibussowitsch line. It is not portable to use macros defined using this one in conditional or loop bodies 850f7e3c444SJacob Faibussowitsch without enclosing them in curly braces\: 851f7e3c444SJacob Faibussowitsch 852f7e3c444SJacob Faibussowitsch .vb 853f7e3c444SJacob Faibussowitsch #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0 854f7e3c444SJacob Faibussowitsch 855f7e3c444SJacob Faibussowitsch int err,x = 10; 856f7e3c444SJacob Faibussowitsch 857f7e3c444SJacob Faibussowitsch if (...) err = FOO(x); // ERROR, body of FOO() executed outside the if statement 858f7e3c444SJacob Faibussowitsch if (...) { err = FOO(x); } // OK 859f7e3c444SJacob Faibussowitsch 860f7e3c444SJacob Faibussowitsch for (...) err = FOO(x); // ERROR, body of FOO() executed outside the loop 861f7e3c444SJacob Faibussowitsch for (...) { err = FOO(x); } // OK 862f7e3c444SJacob Faibussowitsch .ve 863f7e3c444SJacob Faibussowitsch 864f7e3c444SJacob Faibussowitsch It is also not portable to use this macro directly inside function call, conditional, loop, 865f7e3c444SJacob Faibussowitsch or switch statements\: 866f7e3c444SJacob Faibussowitsch 867f7e3c444SJacob Faibussowitsch .vb 868f7e3c444SJacob Faibussowitsch extern void bar(int); 869f7e3c444SJacob Faibussowitsch 870f7e3c444SJacob Faibussowitsch int ret = FOO(x); 871f7e3c444SJacob Faibussowitsch 872f7e3c444SJacob Faibussowitsch bar(FOO(x)); // ERROR, may not compile 873f7e3c444SJacob Faibussowitsch bar(ret); // OK 874f7e3c444SJacob Faibussowitsch 875f7e3c444SJacob Faibussowitsch if (FOO(x)) // ERROR, may not compile 876f7e3c444SJacob Faibussowitsch if (ret) // OK 877f7e3c444SJacob Faibussowitsch .ve 878f7e3c444SJacob Faibussowitsch 879f7e3c444SJacob Faibussowitsch Example usage: 880f7e3c444SJacob Faibussowitsch .vb 881f7e3c444SJacob Faibussowitsch #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10) 882f7e3c444SJacob Faibussowitsch 883f7e3c444SJacob Faibussowitsch int x = 10; 884f7e3c444SJacob Faibussowitsch int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20 885f7e3c444SJacob Faibussowitsch 886f7e3c444SJacob Faibussowitsch // multiline macros allowed, but must declare with line continuation as usual 887f7e3c444SJacob Faibussowitsch #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \ 888f7e3c444SJacob Faibussowitsch if (arg1 > 10) { \ 889f7e3c444SJacob Faibussowitsch puts("big int!"); \ 890f7e3c444SJacob Faibussowitsch } else { \ 891f7e3c444SJacob Faibussowitsch return 7355608; \ 892f7e3c444SJacob Faibussowitsch } \ 893f7e3c444SJacob Faibussowitsch ) 894f7e3c444SJacob Faibussowitsch 895f7e3c444SJacob Faibussowitsch // if retexpr contains commas, must enclose it with braces 896f7e3c444SJacob Faibussowitsch #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...) 897f7e3c444SJacob Faibussowitsch #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...) 898f7e3c444SJacob Faibussowitsch 899f7e3c444SJacob Faibussowitsch int x = 10; 900f7e3c444SJacob Faibussowitsch int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0 901f7e3c444SJacob Faibussowitsch int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20 902f7e3c444SJacob Faibussowitsch .ve 903f7e3c444SJacob Faibussowitsch 904f7e3c444SJacob Faibussowitsch Level: intermediate 905f7e3c444SJacob Faibussowitsch 906db781477SPatrick Sanan .seealso: `PetscExpand()`, `PetscConcat()`, `PetscStringize()` 907f7e3c444SJacob Faibussowitsch M*/ 908f7e3c444SJacob Faibussowitsch #define PetscMacroReturns(retexpr, ...) PetscMacroReturns_(retexpr, __VA_ARGS__) 909f7e3c444SJacob Faibussowitsch 910f7e3c444SJacob Faibussowitsch #define PetscMacroReturnStandard(...) PetscMacroReturns(0, __VA_ARGS__) 911f7e3c444SJacob Faibussowitsch 912bde483f2SJacob Faibussowitsch #endif /* !PETSC_SKIP_VARIADIC_MACROS */ 913bde483f2SJacob Faibussowitsch 914dd39110bSPierre Jolivet /*MC 915dd39110bSPierre Jolivet PETSC_STATIC_ARRAY_LENGTH - Return the length of a static array 916dd39110bSPierre Jolivet 917dd39110bSPierre Jolivet Level: intermediate 918dd39110bSPierre Jolivet M*/ 919dd39110bSPierre Jolivet #define PETSC_STATIC_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) 920dd39110bSPierre Jolivet 921296d8154SBarry Smith /* 922296d8154SBarry Smith These macros allow extracting out the first argument or all but the first argument from a macro __VAR_ARGS__ INSIDE another macro. 923296d8154SBarry Smith 924296d8154SBarry Smith Example usage: 925296d8154SBarry Smith 926296d8154SBarry Smith #define mymacro(obj,...) { 927296d8154SBarry Smith PETSC_FIRST_ARG((__VA_ARGS__,unused)); 928296d8154SBarry Smith f(22 PETSC_REST_ARG(__VA_ARGS__)); 929296d8154SBarry Smith } 930296d8154SBarry Smith 931296d8154SBarry Smith Note you add a dummy extra argument to __VA_ARGS__ and enclose them in an extra set of () for PETSC_FIRST_ARG() and PETSC_REST_ARG(__VA_ARGS__) automatically adds a leading comma only if there are additional arguments 932296d8154SBarry Smith 933296d8154SBarry Smith Reference: 934296d8154SBarry Smith https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick 935296d8154SBarry Smith */ 936296d8154SBarry Smith #define PETSC_FIRST_ARG_(N, ...) N 937296d8154SBarry Smith #define PETSC_FIRST_ARG(args) PETSC_FIRST_ARG_ args 938296d8154SBarry Smith #define PETSC_SELECT_16TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16 939296d8154SBarry Smith #define PETSC_NUM(...) PETSC_SELECT_16TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) 940296d8154SBarry Smith #define PETSC_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__ 941296d8154SBarry Smith #define PETSC_REST_HELPER_ONE(first) 942296d8154SBarry Smith #define PETSC_REST_HELPER2(qty, ...) PETSC_REST_HELPER_##qty(__VA_ARGS__) 943296d8154SBarry Smith #define PETSC_REST_HELPER(qty, ...) PETSC_REST_HELPER2(qty, __VA_ARGS__) 944296d8154SBarry Smith #define PETSC_REST_ARG(...) PETSC_REST_HELPER(PETSC_NUM(__VA_ARGS__), __VA_ARGS__) 945296d8154SBarry Smith 946bde483f2SJacob Faibussowitsch #endif /* PETSC_PREPROCESSOR_MACROS_H */ 947