xref: /petsc/include/petscmacros.h (revision df4cd43f92eaa320656440c40edb1046daee8f75)
1 #ifndef PETSC_PREPROCESSOR_MACROS_H
2 #define PETSC_PREPROCESSOR_MACROS_H
3 
4 #include <petscconf.h>
5 #include <petscconf_poison.h> /* for PetscDefined() error checking */
6 
7 /* SUBMANSEC = Sys */
8 
9 #if defined(__cplusplus)
10   #if __cplusplus <= 201103L
11     #define PETSC_CPP_VERSION 11
12   #elif __cplusplus <= 201402L
13     #define PETSC_CPP_VERSION 14
14   #elif __cplusplus <= 201703L
15     #define PETSC_CPP_VERSION 17
16   #elif __cplusplus <= 202002L
17     #define PETSC_CPP_VERSION 20
18   #else
19     #define PETSC_CPP_VERSION 22 // current year, or date of c++2b ratification
20   #endif
21 #endif // __cplusplus
22 
23 #ifndef PETSC_CPP_VERSION
24   #define PETSC_CPP_VERSION 0
25 #endif
26 
27 #if defined(__STDC_VERSION__)
28   #if __STDC_VERSION__ <= 199901L
29     // C99 except that 99 is >= 11 or 17 so we shorten it to 9 instead
30     #define PETSC_C_VERSION 9
31   #elif __STDC_VERSION__ <= 201112L
32     #define PETSC_C_VERSION 11
33   #elif __STDC_VERSION__ <= 201710L
34     #define PETSC_C_VERSION 17
35   #else
36     #define PETSC_C_VERSION 22 // current year, or date of c2b ratification
37   #endif
38 #endif // __STDC_VERSION__
39 
40 #ifndef PETSC_C_VERSION
41   #define PETSC_C_VERSION 0
42 #endif
43 
44 /* ========================================================================== */
45 /* This facilitates using the C version of PETSc from C++ and the C++ version from C. */
46 #if defined(__cplusplus)
47   #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_CXX
48 #else
49   #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_C
50 #endif
51 
52 /* ========================================================================== */
53 /* Since PETSc manages its own extern "C" handling users should never include PETSc include
54  * files within extern "C". This will generate a compiler error if a user does put the include
55  * file within an extern "C".
56  */
57 #if defined(__cplusplus)
58 void assert_never_put_petsc_headers_inside_an_extern_c(int);
59 void assert_never_put_petsc_headers_inside_an_extern_c(double);
60 #endif
61 
62 #if defined(__cplusplus)
63   #define PETSC_RESTRICT PETSC_CXX_RESTRICT
64 #else
65   #define PETSC_RESTRICT restrict
66 #endif
67 
68 #define PETSC_INLINE        PETSC_DEPRECATED_MACRO("GCC warning \"PETSC_INLINE is deprecated (since version 3.17)\"") inline
69 #define PETSC_STATIC_INLINE PETSC_DEPRECATED_MACRO("GCC warning \"PETSC_STATIC_INLINE is deprecated (since version 3.17)\"") static inline
70 
71 #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */
72   #define PETSC_DLLEXPORT __declspec(dllexport)
73   #define PETSC_DLLIMPORT __declspec(dllimport)
74   #define PETSC_VISIBILITY_INTERNAL
75 #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX)
76   #define PETSC_DLLEXPORT           __attribute__((visibility("default")))
77   #define PETSC_DLLIMPORT           __attribute__((visibility("default")))
78   #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden")))
79 #elif !defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_C)
80   #define PETSC_DLLEXPORT           __attribute__((visibility("default")))
81   #define PETSC_DLLIMPORT           __attribute__((visibility("default")))
82   #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden")))
83 #else
84   #define PETSC_DLLEXPORT
85   #define PETSC_DLLIMPORT
86   #define PETSC_VISIBILITY_INTERNAL
87 #endif
88 
89 #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */
90   #define PETSC_VISIBILITY_PUBLIC PETSC_DLLEXPORT
91 #else /* Win32 users need this to import symbols from petsc.dll */
92   #define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT
93 #endif
94 
95 /* Functions tagged with PETSC_EXTERN in the header files are always defined as extern "C" when
96  * compiled with C++ so they may be used from C and are always visible in the shared libraries
97  */
98 #if defined(__cplusplus)
99   #define PETSC_EXTERN         extern "C" PETSC_VISIBILITY_PUBLIC
100   #define PETSC_EXTERN_TYPEDEF extern "C"
101   #define PETSC_INTERN         extern "C" PETSC_VISIBILITY_INTERNAL
102 #else
103   #define PETSC_EXTERN extern PETSC_VISIBILITY_PUBLIC
104   #define PETSC_EXTERN_TYPEDEF
105   #define PETSC_INTERN extern PETSC_VISIBILITY_INTERNAL
106 #endif
107 
108 #if defined(PETSC_USE_SINGLE_LIBRARY)
109   #define PETSC_SINGLE_LIBRARY_INTERN PETSC_INTERN
110 #else
111   #define PETSC_SINGLE_LIBRARY_INTERN PETSC_EXTERN
112 #endif
113 
114 #if !defined(__has_feature)
115   #define __has_feature(x) 0
116 #endif
117 
118 /*MC
119   PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler
120 
121   Synopsis:
122   #include <petscmacros.h>
123   int PetscHasAttribute(name)
124 
125   Input Parameter:
126 . name - The name of the attribute to test
127 
128   Notes:
129   name should be identical to what you might pass to the __attribute__ declaration itself --
130   plain, unbroken text.
131 
132   As `PetscHasAttribute()` is wrapper over the function-like macro `__has_attribute()`, the
133   exact type and value returned is implementation defined. In practice however, it usually
134   returns `1` if the attribute is supported and `0` if the attribute is not supported.
135 
136   Example Usage:
137   Typical usage is using the preprocessor
138 
139 .vb
140   #if PetscHasAttribute(always_inline)
141   #  define MY_ALWAYS_INLINE __attribute__((always_inline))
142   #else
143   #  define MY_ALWAYS_INLINE
144   #endif
145 
146   void foo(void) MY_ALWAYS_INLINE;
147 .ve
148 
149   but it can also be used in regular code
150 
151 .vb
152   if (PetscHasAttribute(some_attribute)) {
153     foo();
154   } else {
155     bar();
156   }
157 .ve
158 
159   Level: intermediate
160 
161 .seealso: `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`,
162 `PETSC_ATTRIBUTE_FORMAT`
163 M*/
164 #if !defined(__has_attribute)
165   #define __has_attribute(x) 0
166 #endif
167 #define PetscHasAttribute(name) __has_attribute(name)
168 
169 /*MC
170   PetscHasBuiltin - Determine whether a particular builtin method is supported by the compiler
171 
172   Synopsis:
173   #include <petscmacros.h>
174   int PetscHasBuiltin(name)
175 
176   Input Parameter:
177 . name - the name of the builtin routine
178 
179   Notes:
180   Evaluates to `1` if the builtin is supported and `0` otherwise. Note the term "evaluates"
181   (vs "expands") is deliberate; even though `PetscHasBuiltin()` is a macro the underlying
182   detector is itself is a compiler extension with implementation-defined return type and
183   semantics. Some compilers implement it as a macro, others as a compiler function. In practice
184   however, all supporting compilers return an integer boolean as described.
185 
186   Example Usage:
187   Typical usage is in preprocessor directives
188 
189 .vb
190   #if PetscHasBuiltin(__builtin_trap)
191   __builtin_trap();
192   #else
193   abort();
194   #endif
195 .ve
196 
197   But it may also be used in regular code
198 
199 .vb
200   if (PetscHasBuiltin(__builtin_alloca)) {
201     foo();
202   } else {
203     bar();
204   }
205 .ve
206 
207   Level: intermediate
208 
209 .seealso: `PetscHasAttribute()`, `PetscAssume()`
210 M*/
211 #if !defined(__has_builtin)
212   #define __has_builtin(x) 0
213 #endif
214 // clangs __has_builtin prior to clang 10 did not properly handle non-function builtins such as
215 // __builtin_types_compatible_p which take types or other non-functiony things as
216 // arguments. The correct way to detect these then is to use __is_identifier (also a clang
217 // extension). GCC has always worked as expected. see https://stackoverflow.com/a/45043153
218 #if defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 10) && defined(__is_identifier)
219   #define PetscHasBuiltin(name) __is_identifier(name)
220 #else
221   #define PetscHasBuiltin(name) __has_builtin(name)
222 #endif
223 
224 #if !defined(PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG)
225   /*
226    Support for Clang (>=3.2) matching type tag arguments with void* buffer types.
227    This allows the compiler to detect cases where the MPI datatype argument passed to a MPI routine
228    does not match the actual type of the argument being passed in
229 */
230   #if PetscHasAttribute(pointer_with_type_tag)
231     #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) __attribute__((pointer_with_type_tag(MPI, bufno, typeno)))
232   #endif
233 
234   #if PetscHasAttribute(type_tag_for_datatype)
235     #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type)                   __attribute__((type_tag_for_datatype(MPI, type)))
236     #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type) __attribute__((type_tag_for_datatype(MPI, type, layout_compatible)))
237   #endif
238 #endif // PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG
239 
240 #ifndef PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE
241   #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno)
242 #endif
243 
244 #ifndef PETSC_ATTRIBUTE_MPI_TYPE_TAG
245   #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type)
246 #endif
247 
248 #ifndef PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE
249   #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type)
250 #endif
251 
252 /*MC
253   PETSC_ATTRIBUTE_FORMAT - Indicate to the compiler that specified arguments should be treated
254   as format specifiers and checked for validity
255 
256   Synopsis:
257   #include <petscmacros.h>
258   <attribute declaration> PETSC_ATTRIBUTE_FORMAT(int strIdx, int vaArgIdx)
259 
260   Input Parameters:
261 + strIdx   - The (1-indexed) location of the format string in the argument list
262 - vaArgIdx - The (1-indexed) location of the first formattable argument in the argument list
263 
264   Notes:
265   This function attribute causes the compiler to issue warnings when the format specifier does
266   not match the type of the variable that will be formatted, or when there exists a mismatch
267   between the number of format specifiers and variables to be formatted. It is safe to use this
268   macro if your compiler does not support format specifier checking (though this is
269   exceeedingly rare).
270 
271   Both strIdx and vaArgIdx must be compile-time constant integer literals and cannot have the
272   same value.
273 
274   The arguments to be formatted (and therefore checked by the compiler) must be "contiguous" in
275   the argument list, that is, there is no way to indicate gaps which should not be checked.
276 
277   Definition is suppressed by defining `PETSC_SKIP_ATTRIBUTE_FORMAT` prior to including PETSc
278   header files. In this case the macro will expand empty.
279 
280   Example Usage:
281 .vb
282   // format string is 2nd argument, variable argument list containing args is 3rd argument
283   void my_printf(void *obj, const char *fmt_string, ...) PETSC_ATTRIBUTE_FORMAT(2,3)
284 
285   int    x = 1;
286   double y = 50.0;
287 
288   my_printf(NULL,"%g",x);      // WARNING, format specifier does not match for 'int'!
289   my_printf(NULL,"%d",x,y);    // WARNING, more arguments than format specifiers!
290   my_printf(NULL,"%d %g",x,y); // OK
291 .ve
292 
293   Level: developer
294 
295 .seealso: `PETSC_ATTRIBUTE_COLD`, `PetscHasAttribute()`
296 M*/
297 #if PetscHasAttribute(format) && !defined(PETSC_SKIP_ATTRIBUTE_FORMAT)
298   #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) __attribute__((format(printf, strIdx, vaArgIdx)))
299 #else
300   #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx)
301 #endif
302 
303 /*MC
304   PETSC_ATTRIBUTE_COLD - Indicate to the compiler that a function is very unlikely to be
305   executed
306 
307   Notes:
308   The marked function is often optimized for size rather than speed and may be grouped alongside
309   other equally frigid routines improving code locality of lukewarm or hotter parts of program.
310 
311   The paths leading to cold functions are usually automatically marked as unlikely by the
312   compiler. It may thus be useful to mark functions used to handle unlikely conditions -- such
313   as error handlers -- as cold to improve optimization of the surrounding temperate functions.
314 
315   Example Usage:
316 .vb
317   void my_error_handler(...) PETSC_ATTRIBUTE_COLD;
318 
319   if (temperature < 0) {
320     return my_error_handler(...); // chilly!
321   }
322 .ve
323 
324   Level: intermediate
325 
326 .seealso: `PetscUnlikely()`, `PetscUnlikelyDebug()`, `PetscLikely()`, `PetscLikelyDebug()`,
327           `PetscUnreachable()`, `PETSC_ATTRIBUTE_FORMAT`
328 M*/
329 #if PetscHasAttribute(__cold__)
330   #define PETSC_ATTRIBUTE_COLD __attribute__((__cold__))
331 #elif PetscHasAttribute(cold) /* some implementations (old gcc) use no underscores */
332   #define PETSC_ATTRIBUTE_COLD __attribute__((cold))
333 #else
334   #define PETSC_ATTRIBUTE_COLD
335 #endif
336 
337 /*MC
338   PETSC_NULLPTR - Standard way of indicating a null value or pointer
339 
340   Notes:
341   Equivalent to NULL in C source, and nullptr in C++ source. Note that for the purposes of
342   interoperability between C and C++, setting a pointer to `PETSC_NULLPTR` in C++ is functonially
343   equivalent to setting the same pointer to NULL in C. That is to say that the following
344   expressions are equivalent\:
345 
346 .vb
347   ptr == PETSC_NULLPTR
348   ptr == NULL
349   ptr == 0
350   !ptr
351 
352   ptr = PETSC_NULLPTR
353   ptr = NULL
354   ptr = 0
355 .ve
356 
357   and for completeness' sake\:
358 
359 .vb
360   PETSC_NULLPTR == NULL
361 .ve
362 
363   Fortran Notes:
364   Not available in Fortran
365 
366   Example Usage:
367 .vb
368   // may be used in place of '\0' or other such teminators in the definition of char arrays
369   const char *const MyEnumTypes[] = {
370     "foo",
371     "bar",
372     PETSC_NULLPTR
373   };
374 
375   // may be used to nullify objects
376   PetscObject obj = PETSC_NULLPTR;
377 
378   // may be used in any function expecting NULL
379   PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor");
380 .ve
381 
382   Developer Notes:
383   `PETSC_NULLPTR` must be used in place of NULL in all C++ source files. Using NULL in source
384   files compiled with a C++ compiler may lead to unexpected side-effects in function overload
385   resolution and/or compiler warnings.
386 
387   Level: beginner
388 
389 .seealso: `PETSC_CONSTEXPR_14`, `PETSC_NODISCARD`
390 M*/
391 
392 /*MC
393   PETSC_CONSTEXPR_14 - C++14 constexpr
394 
395   Notes:
396   Equivalent to constexpr when using a C++ compiler that supports C++14. Expands to nothing
397   if the C++ compiler does not support C++14 or when not compiling with a C++ compiler. Note
398   that this cannot be used in cases where an empty expansion would result in invalid code. It
399   is safe to use this in C source files.
400 
401   Fortran Notes:
402   Not available in Fortran
403 
404   Example Usage:
405 .vb
406   PETSC_CONSTEXPR_14 int factorial(int n)
407   {
408     int r = 1;
409 
410     do {
411       r *= n;
412     } while (--n);
413     return r;
414   }
415 .ve
416 
417   Level: beginner
418 
419 .seealso: `PETSC_NULLPTR`, `PETSC_NODISCARD`
420 M*/
421 
422 /*MC
423   PETSC_NODISCARD - Mark the return value of a function as non-discardable
424 
425   Not available in Fortran
426 
427   Level: beginner
428 
429   Notes:
430   Hints to the compiler that the return value of a function must be captured. A diagnostic may
431   (but is not required to) be emitted if the value is discarded. It is safe to use this in both
432   C and C++ source files.
433 
434   Example Usage:
435 .vb
436   class Foo
437   {
438     int x;
439 
440   public:
441     PETSC_NODISCARD Foo(int y) : x(y) { }
442   };
443 
444   PETSC_NODISCARD int factorial(int n)
445   {
446     return n <= 1 ? 1 : (n * factorial(n - 1));
447   }
448 
449   auto x = factorial(10); // OK, capturing return value
450   factorial(10);          // Warning: ignoring return value of function declared 'nodiscard'
451 
452   auto f = Foo(x); // OK, capturing constructed object
453   Foo(x);          // Warning: Ignoring temporary created by a constructor declared 'nodiscard'
454 .ve
455 
456 .seealso: `PETSC_NULLPTR`, `PETSC_CONSTEXPR_14`
457 M*/
458 
459 /* C++11 features */
460 #if defined(__cplusplus) || (PETSC_C_VERSION >= 23)
461   #define PETSC_NULLPTR nullptr
462 #else
463   #define PETSC_NULLPTR NULL
464 #endif
465 
466 /* C++14 features */
467 #if PETSC_CPP_VERSION >= 14
468   #define PETSC_CONSTEXPR_14 constexpr
469 #else
470   #define PETSC_CONSTEXPR_14
471 #endif
472 
473 /* C++17 features */
474 #if PETSC_CPP_VERSION >= 17
475   #define PETSC_CONSTEXPR_17 constexpr
476 #else
477   #define PETSC_CONSTEXPR_17
478 #endif
479 
480 #if (PETSC_CPP_VERSION >= 17) || (PETSC_C_VERSION >= 23)
481   #define PETSC_NODISCARD [[nodiscard]]
482 #elif PetscHasAttribute(warn_unused_result)
483   #define PETSC_NODISCARD __attribute__((warn_unused_result))
484 #else
485   #define PETSC_NODISCARD
486 #endif
487 
488 #include <petscversion.h>
489 #define PETSC_AUTHOR_INFO "       The PETSc Team\n    petsc-maint@mcs.anl.gov\n https://petsc.org/\n"
490 
491 /* designated initializers since C99 and C++20, MSVC never supports them though */
492 #if defined(_MSC_VER) || (defined(__cplusplus) && (PETSC_CPP_VERSION < 20))
493   #define PetscDesignatedInitializer(name, ...) __VA_ARGS__
494 #else
495   #define PetscDesignatedInitializer(name, ...) .name = __VA_ARGS__
496 #endif
497 
498 /*MC
499   PetscUnlikely - Hints the compiler that the given condition is usually false
500 
501   Synopsis:
502   #include <petscmacros.h>
503   bool PetscUnlikely(bool cond)
504 
505   Not Collective
506 
507   Input Parameter:
508 . cond - Boolean expression
509 
510   Notes:
511   Not available from fortran.
512 
513   This returns the same truth value, it is only a hint to compilers that the result of cond is
514   unlikely to be true.
515 
516   Example usage:
517 .vb
518   if (PetscUnlikely(cond)) {
519     foo(); // cold path
520   } else {
521     bar(); // hot path
522   }
523 .ve
524 
525   Level: advanced
526 
527 .seealso: `PetscLikely()`, `PetscUnlikelyDebug()`, `PetscCall()`, `PetscDefined()`, `PetscHasAttribute()`,
528           `PETSC_ATTRIBUTE_COLD`
529 M*/
530 
531 /*MC
532   PetscLikely - Hints the compiler that the given condition is usually true
533 
534   Synopsis:
535   #include <petscmacros.h>
536   bool PetscLikely(bool cond)
537 
538   Not Collective
539 
540   Input Parameter:
541 . cond - Boolean expression
542 
543   Notes:
544   Not available from fortran.
545 
546   This returns the same truth value, it is only a hint to compilers that the result of cond is
547   likely to be true.
548 
549   Example usage:
550 .vb
551   if (PetscLikely(cond)) {
552     foo(); // hot path
553   } else {
554     bar(); // cold path
555   }
556 .ve
557 
558   Level: advanced
559 
560 .seealso: `PetscUnlikely()`, `PetscDefined()`, `PetscHasAttribute()`
561           `PETSC_ATTRIBUTE_COLD`
562 M*/
563 #if defined(PETSC_HAVE_BUILTIN_EXPECT)
564   #define PetscUnlikely(cond) __builtin_expect(!!(cond), 0)
565   #define PetscLikely(cond)   __builtin_expect(!!(cond), 1)
566 #else
567   #define PetscUnlikely(cond) (cond)
568   #define PetscLikely(cond)   (cond)
569 #endif
570 
571 /*MC
572   PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable
573 
574   Synopsis:
575   #include <petscmacros.h>
576   void PetscUnreachable(void)
577 
578   Notes:
579   Indicates to the compiler (usually via some built-in) that a particular code path is always
580   unreachable. Behavior is undefined if this function is ever executed, the user can expect an
581   unceremonious crash.
582 
583   Example usage:
584   Useful in situations such as switches over enums where not all enumeration values are
585   explicitly covered by the switch
586 
587 .vb
588   typedef enum {RED, GREEN, BLUE} Color;
589 
590   int foo(Color c)
591   {
592     // it is known to programmer (or checked previously) that c is either RED or GREEN
593     // but compiler may not be able to deduce this and/or emit spurious warnings
594     switch (c) {
595       case RED:
596         return bar();
597       case GREEN:
598         return baz();
599       default:
600         PetscUnreachable(); // program is ill-formed if executed
601     }
602   }
603 .ve
604 
605   Level: advanced
606 
607 .seealso: `SETERRABORT()`, `PETSCABORT()`, `PETSC_ATTRIBUTE_COLD`, `PetscAssume()`
608 M*/
609 #if PETSC_CPP_VERSION >= 23
610   #include <utility>
611   #define PetscUnreachable() std::unreachable()
612 #elif defined(__GNUC__)
613   /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */
614   #define PetscUnreachable() __builtin_unreachable()
615 #elif defined(_MSC_VER) /* MSVC */
616   #define PetscUnreachable() __assume(0)
617 #else /* ??? */
618   #define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Code path explicitly marked as unreachable executed")
619 #endif
620 
621 /*MC
622   PetscAssume - Indicate to the compiler a condition that is defined to be true
623 
624   Synopsis:
625   #include <petscmacros.h>
626   void PetscAssume(bool cond)
627 
628   Input Parameter:
629 . cond - Boolean expression
630 
631   Notes:
632   If supported by the compiler, `cond` is used to inform the optimizer of an invariant
633   truth. The argument itself is never evaluated, so any side effects of the expression will be
634   discarded. This macro is used in `PetscAssert()` to retain information gained from debug
635   checks that would be lost in optimized builds. For example\:
636 
637 .vb
638   PetscErrorCode foo(PetscInt x) {
639 
640     PetscAssert(x >= 0, ...);
641   }
642 .ve
643 
644   The assertion checks that `x` is positive when debugging is enabled (and returns from `foo()`
645   if it is not). This implicitly informs the optimizer that `x` cannot be negative. However,
646   when debugging is disabled any `PetscAssert()` checks are tautologically false, and hence the
647   optimizer cannot deduce any information from them.
648 
649   Due to compiler limitations `PetscAssume()` works best when `cond` involves
650   constants. Certain compilers do not yet propagate symbolic inequalities i.e.\:
651 
652 .vb
653   int a, b, var_five;
654 
655   // BEST, all supporting compilers will understand a cannot be >= 5
656   PetscAssume(a < 5);
657 
658    // OK, some compilers may understand that a cannot be >= 5
659   PetscAssume(a <= b && b < 5);
660 
661    // WORST, most compilers will not get the memo
662   PetscAssume(a <= b && b < var_five);
663 .ve
664 
665   If the condition is violated at runtime then behavior is wholly undefined. If the
666   condition is violated at compile-time, the condition "supersedes" the compile-time violation
667   and the program is ill-formed, no diagnostic required. For example consider the following\:
668 
669 .vb
670   PetscInt x = 0;
671 
672   PetscAssume(x != 0);
673   if (x == 0) {
674     x += 10;
675   } else {
676     popen("rm -rf /", "w");
677   }
678 .ve
679 
680   Even though `x` is demonstrably `0` the compiler may opt to\:
681 
682   - emit an unconditional `popen("rm -rf /", "w")`
683   - ignore `PetscAssume()` altogether and emit the correct path of `x += 10`
684   - reformat the primary disk partition
685 
686   Level: advanced
687 
688 .seealso: `PetscAssert()`
689 M*/
690 #if PETSC_CPP_VERSION >= 23
691   #define PetscAssume(...) [[assume(__VA_ARGS__)]]
692 #elif defined(_MSC_VER) // msvc
693   #define PetscAssume(...) __assume(__VA_ARGS__)
694 #elif defined(__clang__) && PetscHasBuiltin(__builtin_assume) // clang
695   #define PetscAssume(...) \
696     do { \
697       _Pragma("clang diagnostic push"); \
698       _Pragma("clang diagnostic ignored \"-Wassume\""); \
699       __builtin_assume(__VA_ARGS__); \
700       _Pragma("clang diagnostic pop"); \
701     } while (0)
702 #else // gcc (and really old clang)
703   // gcc does not have its own __builtin_assume() intrinsic. One could fake it via
704   //
705   // if (PetscUnlikely(!cond)) PetscUnreachable();
706   //
707   // but this it unsavory because the side effects of cond are not guaranteed to be
708   // discarded. Though in most circumstances gcc will optimize out the if (because any evaluation
709   // for which cond is false would be undefined results in undefined behavior anyway) it cannot
710   // always do so. This is especially the case for opaque or non-inline function calls:
711   //
712   // extern int bar(int);
713   //
714   // int foo(int x) {
715   //   PetscAssume(bar(x) == 2);
716   //   if (bar(x) == 2) {
717   //     return 1;
718   //   } else {
719   //     return 0;
720   //   }
721   // }
722   //
723   // Here gcc would (if just using builtin_expect()) emit 2 calls to bar(). Note we still have
724   // cond "tested" in the condition, but this is done to silence unused-but-set variable warnings
725   #define PetscAssume(...) \
726     do { \
727       if (0 && (__VA_ARGS__)) PetscUnreachable(); \
728     } while (0)
729 #endif
730 
731 /*MC
732   PetscExpand - Expand macro argument
733 
734   Synopsis:
735   #include <petscmacros.h>
736   <macro-expansion> PetscExpand(x)
737 
738   Input Parameter:
739 . x - The preprocessor token to expand
740 
741   Level: beginner
742 
743 .seealso: `PetscStringize()`, `PetscConcat()`
744 M*/
745 #define PetscExpand_(...) __VA_ARGS__
746 #define PetscExpand(...)  PetscExpand_(__VA_ARGS__)
747 
748 /*MC
749   PetscStringize - Stringize a token
750 
751   Synopsis:
752   #include <petscmacros.h>
753   const char* PetscStringize(x)
754 
755   Input Parameter:
756 . x - The token you would like to stringize
757 
758   Output Parameter:
759 . <return-value> - The string representation of x
760 
761   Notes:
762   Not available from Fortran.
763 
764   PetscStringize() expands x before stringizing it, if you do not wish to do so, use
765   PetscStringize_() instead.
766 
767   Example Usage:
768 .vb
769   #define MY_OTHER_VAR hello there
770   #define MY_VAR       MY_OTHER_VAR
771 
772   PetscStringize(MY_VAR)  -> "hello there"
773   PetscStringize_(MY_VAR) -> "MY_VAR"
774 
775   int foo;
776   PetscStringize(foo)  -> "foo"
777   PetscStringize_(foo) -> "foo"
778 .ve
779 
780   Level: beginner
781 
782 .seealso: `PetscConcat()`, `PetscExpandToNothing()`, `PetscExpand()`
783 M*/
784 #define PetscStringize_(...) #__VA_ARGS__
785 #define PetscStringize(...)  PetscStringize_(__VA_ARGS__)
786 
787 /*MC
788   PetscConcat - Concatenate two tokens
789 
790   Synopsis:
791   #include <petscmacros.h>
792   <macro-expansion> PetscConcat(x, y)
793 
794   Input Parameters:
795 + x - First token
796 - y - Second token
797 
798   Notes:
799   Not available from Fortran.
800 
801   PetscConcat() will expand both arguments before pasting them together, use PetscConcat_()
802   if you don't want to expand them.
803 
804   Example usage:
805 .vb
806   PetscConcat(hello,there) -> hellothere
807 
808   #define HELLO hello
809   PetscConcat(HELLO,there)  -> hellothere
810   PetscConcat_(HELLO,there) -> HELLOthere
811 .ve
812 
813   Level: beginner
814 
815 .seealso: `PetscStringize()`, `PetscExpand()`
816 M*/
817 #define PetscConcat_(x, y) x##y
818 #define PetscConcat(x, y)  PetscConcat_(x, y)
819 
820 #define PETSC_INTERNAL_COMPL_0 1
821 #define PETSC_INTERNAL_COMPL_1 0
822 
823 /*MC
824   PetscCompl - Expands to the integer complement of its argument
825 
826   Synopsis:
827   #include <petscmacros.h>
828   int PetscCompl(b)
829 
830   Input Parameter:
831 . b - Preprocessor variable, must expand to either integer literal 0 or 1
832 
833   Output Parameter:
834 . <return-value> - Either integer literal 0 or 1
835 
836   Notes:
837   Not available from Fortran.
838 
839   Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to
840   0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its
841   argument before returning the complement.
842 
843   This macro can be useful for negating PetscDefined() inside macros e.g.
844 
845 $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO))
846 
847   Example usage:
848 .vb
849   #define MY_VAR 1
850   PetscCompl(MY_VAR) -> 0
851 
852   #undef  MY_VAR
853   #define MY_VAR 0
854   PetscCompl(MY_VAR) -> 1
855 .ve
856 
857   Level: beginner
858 
859 .seealso: `PetscConcat()`, `PetscDefined()`
860 M*/
861 #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_, PetscExpand(b))
862 
863 #if !defined(PETSC_SKIP_VARIADIC_MACROS)
864   /*MC
865   PetscDefined - Determine whether a boolean macro is defined
866 
867   Synopsis:
868   #include <petscmacros.h>
869   int PetscDefined(def)
870 
871   Input Parameter:
872 . def - PETSc-style preprocessor variable (without PETSC_ prepended!)
873 
874   Output Parameter:
875 . <return-value> - Either integer literal 0 or 1
876 
877   Notes:
878   Not available from Fortran, requires variadic macro support, definition is disabled by
879   defining `PETSC_SKIP_VARIADIC_MACROS`.
880 
881   `PetscDefined()` returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to
882   integer literal 1. In all other cases, `PetscDefined()` returns integer literal 0. Therefore
883   this macro should not be used if its argument may be defined to a non-empty value other than
884   1.
885 
886   The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to
887   add custom checks in user code, one should use `PetscDefined_()`.
888 
889 $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d))
890 
891   Developer Notes:
892   Getting something that works in C and CPP for an arg that may or may not be defined is
893   tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define,
894   insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks
895   the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair,
896   and when the last step cherry picks the 2nd arg, we get a zero.
897 
898   Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a
899   nonconforming implementation of variadic macros.
900 
901   Example Usage:
902   Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG
903   is defined then
904 
905 .vb
906   #if PetscDefined(USE_DEBUG)
907     foo();
908   #else
909     bar();
910   #endif
911 
912   // or alternatively within normal code
913   if (PetscDefined(USE_DEBUG)) {
914     foo();
915   } else {
916     bar();
917   }
918 .ve
919 
920   is equivalent to
921 
922 .vb
923   #if defined(PETSC_USE_DEBUG)
924   #  if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro
925        foo();
926   #   elif PETSC_USE_DEBUG == 1
927        foo();
928   #   else
929        bar();
930   #  endif
931   #else
932   bar();
933   #endif
934 .ve
935 
936   Level: intermediate
937 
938 .seealso: `PetscHasAttribute()`, `PetscUnlikely()`, `PetscLikely()`, `PetscConcat()`,
939           `PetscExpandToNothing()`, `PetscCompl()`
940 M*/
941   #define PetscDefined_arg_1                                    shift,
942   #define PetscDefined_arg_                                     shift,
943   #define PetscDefined__take_second_expanded(ignored, val, ...) val
944   #define PetscDefined__take_second_expand(args)                PetscDefined__take_second_expanded args
945   #define PetscDefined__take_second(...)                        PetscDefined__take_second_expand((__VA_ARGS__))
946   #define PetscDefined__(arg1_or_junk)                          PetscDefined__take_second(arg1_or_junk 1, 0, at_)
947   #define PetscDefined_(value)                                  PetscDefined__(PetscConcat_(PetscDefined_arg_, value))
948   #define PetscDefined(def)                                     PetscDefined_(PetscConcat(PETSC_, def))
949 
950   /*MC
951   PetscUnlikelyDebug - Hints the compiler that the given condition is usually false, eliding
952   the check in optimized mode
953 
954   Synopsis:
955   #include <petscmacros.h>
956   bool PetscUnlikelyDebug(bool cond)
957 
958   Not Collective
959 
960   Input Parameters:
961 . cond - Boolean expression
962 
963   Notes:
964   Not available from Fortran, requires variadic macro support, definition is disabled by
965   defining `PETSC_SKIP_VARIADIC_MACROS`.
966 
967   This returns the same truth value, it is only a hint to compilers that the result of cond is
968   likely to be false. When PETSc is compiled in optimized mode this will always return
969   false. Additionally, cond is guaranteed to not be evaluated when PETSc is compiled in
970   optimized mode.
971 
972   Example usage:
973   This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG)
974   is true. So
975 
976 .vb
977   if (PetscUnlikelyDebug(cond)) {
978     foo();
979   } else {
980     bar();
981   }
982 .ve
983 
984   is equivalent to
985 
986 .vb
987   if (PetscDefined(USE_DEBUG)) {
988     if (PetscUnlikely(cond)) {
989       foo();
990     } else {
991       bar();
992     }
993   } else {
994     bar();
995   }
996 .ve
997 
998   Level: advanced
999 
1000 .seealso: `PetscUnlikely()`, `PetscLikely()`, `PetscCall()`, `SETERRQ`
1001 M*/
1002   #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond))
1003 
1004   #if defined(PETSC_CLANG_STATIC_ANALYZER)
1005     // silence compiler warnings when using -pedantic, this is only used by the linter and it cares
1006     // not what ISO C allows
1007     #define PetscMacroReturns_(retexpr, ...) \
1008       __extension__({ \
1009         __VA_ARGS__; \
1010         retexpr; \
1011       })
1012   #else
1013     #define PetscMacroReturns_(retexpr, ...) \
1014       retexpr; \
1015       do { \
1016         __VA_ARGS__; \
1017       } while (0)
1018   #endif
1019 
1020   /*MC
1021   PetscExpandToNothing - Expands to absolutely nothing at all
1022 
1023   Synopsis:
1024   #include <petscmacros.h>
1025   void PetscExpandToNothing(...)
1026 
1027   Input Parameter:
1028 . __VA_ARGS__ - Anything at all
1029 
1030   Notes:
1031   Not available from Fortran, requires variadic macro support, definition is disabled by
1032   defining `PETSC_SKIP_VARIADIC_MACROS`.
1033 
1034   Must have at least 1 parameter.
1035 
1036   Example usage:
1037 .vb
1038   PetscExpandToNothing(a,b,c) -> *nothing*
1039 .ve
1040 
1041   Level: beginner
1042 
1043 .seealso: `PetscConcat()`, `PetscDefined()`, `PetscStringize()`, `PetscExpand()`
1044 M*/
1045   #define PetscExpandToNothing(...)
1046 
1047   /*MC
1048   PetscMacroReturns - Define a macro body that returns a value
1049 
1050   Synopsis:
1051   #include <petscmacros.h>
1052   return_type PetscMacroReturns(return_type retexpr, ...)
1053 
1054   Input Parameters:
1055 + retexpr     - The value or expression that the macro should return
1056 - __VA_ARGS__ - The body of the macro
1057 
1058   Notes:
1059   Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the
1060   body of the macro and should not depend on values produced as a result of the expression. The
1061   user should not assume that the result of this macro is equivalent to a single logical source
1062   line. It is not portable to use macros defined using this one in conditional or loop bodies
1063   without enclosing them in curly braces\:
1064 
1065 .vb
1066   #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0
1067 
1068   int err,x = 10;
1069 
1070   if (...) err = FOO(x);      // ERROR, body of FOO() executed outside the if statement
1071   if (...) { err = FOO(x); }  // OK
1072 
1073   for (...) err = FOO(x);     // ERROR, body of FOO() executed outside the loop
1074   for (...) { err = FOO(x); } // OK
1075 .ve
1076 
1077   It is also not portable to use this macro directly inside function call, conditional, loop,
1078   or switch statements\:
1079 
1080 .vb
1081   extern void bar(int);
1082 
1083   int ret = FOO(x);
1084 
1085   bar(FOO(x)); // ERROR, may not compile
1086   bar(ret);    // OK
1087 
1088   if (FOO(x))  // ERROR, may not compile
1089   if (ret)     // OK
1090 .ve
1091 
1092   Example usage:
1093 .vb
1094   #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10)
1095 
1096   int x = 10;
1097   int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20
1098 
1099   // multiline macros allowed, but must declare with line continuation as usual
1100   #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \
1101     if (arg1 > 10) {                                            \
1102       puts("big int!");                                         \
1103     } else {                                                    \
1104       return 7355608;                                           \
1105     }                                                           \
1106   )
1107 
1108   // if retexpr contains commas, must enclose it with braces
1109   #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...)
1110   #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...)
1111 
1112   int x = 10;
1113   int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0
1114   int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20
1115 .ve
1116 
1117   Level: intermediate
1118 
1119 .seealso: `PetscExpand()`, `PetscConcat()`, `PetscStringize()`
1120 M*/
1121   #define PetscMacroReturns(retexpr, ...) PetscMacroReturns_(retexpr, __VA_ARGS__)
1122 
1123   #define PetscMacroReturnStandard(...) PetscMacroReturns(PETSC_SUCCESS, __VA_ARGS__)
1124 
1125 #endif /* !PETSC_SKIP_VARIADIC_MACROS */
1126 
1127 /*MC
1128   PETSC_STATIC_ARRAY_LENGTH - Return the length of a static array
1129 
1130   Level: intermediate
1131 M*/
1132 #define PETSC_STATIC_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
1133 
1134 /*
1135   These macros allow extracting out the first argument or all but the first argument from a macro __VAR_ARGS__ INSIDE another macro.
1136 
1137   Example usage:
1138 
1139   #define mymacro(obj,...) {
1140     PETSC_FIRST_ARG((__VA_ARGS__,unused));
1141     f(22 PETSC_REST_ARG(__VA_ARGS__));
1142   }
1143 
1144   Note you add a dummy extra argument to __VA_ARGS__ and enclose them in an extra set of () for PETSC_FIRST_ARG() and PETSC_REST_ARG(__VA_ARGS__) automatically adds a leading comma only if there are additional arguments
1145 
1146   Reference:
1147   https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick
1148 */
1149 #define PETSC_FIRST_ARG_(N, ...)                                                                      N
1150 #define PETSC_FIRST_ARG(args)                                                                         PETSC_FIRST_ARG_ args
1151 #define PETSC_SELECT_16TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16
1152 #define PETSC_NUM(...)                                                                                PETSC_SELECT_16TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
1153 #define PETSC_REST_HELPER_TWOORMORE(first, ...)                                                       , __VA_ARGS__
1154 #define PETSC_REST_HELPER_ONE(first)
1155 #define PETSC_REST_HELPER2(qty, ...) PETSC_REST_HELPER_##qty(__VA_ARGS__)
1156 #define PETSC_REST_HELPER(qty, ...)  PETSC_REST_HELPER2(qty, __VA_ARGS__)
1157 #define PETSC_REST_ARG(...)          PETSC_REST_HELPER(PETSC_NUM(__VA_ARGS__), __VA_ARGS__)
1158 
1159 #endif /* PETSC_PREPROCESSOR_MACROS_H */
1160