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