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