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