xref: /petsc/include/petscmacros.h (revision cff5ee9494c9bfebcdd04cb8a6074a9b102fd2b0)
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   Notes:
426   Hints to the compiler that the return value of a function must be captured. A diagnostic may
427   (but is not required) be emitted if the value is discarded. It is safe to use this in C
428   and C++ source files.
429 
430   Fortran Notes:
431   Not available in Fortran
432 
433   Example Usage:
434 .vb
435   class Foo
436   {
437     int x;
438 
439   public:
440     PETSC_NODISCARD Foo(int y) : x(y) { }
441   };
442 
443   PETSC_NODISCARD int factorial(int n)
444   {
445     return n <= 1 ? 1 : (n * factorial(n - 1));
446   }
447 
448   auto x = factorial(10); // OK, capturing return value
449   factorial(10);          // Warning: ignoring return value of function declared 'nodiscard'
450 
451   auto f = Foo(x); // OK, capturing constructed object
452   Foo(x);          // Warning: Ignoring temporary created by a constructor declared 'nodiscard'
453 .ve
454 
455   Developer Notes:
456   It is highly recommended if not downright required that any PETSc routines written in C++
457   returning a PetscErrorCode be marked `PETSC_NODISCARD`. Ignoring the return value of PETSc
458   routines is not supported; unhandled errors may leave PETSc in an unrecoverable state.
459 
460   Level: beginner
461 
462 .seealso: `PETSC_NULLPTR`, `PETSC_CONSTEXPR_14`
463 M*/
464 
465 /* C++11 features */
466 #if defined(__cplusplus)
467   #define PETSC_NULLPTR nullptr
468 #else
469   #define PETSC_NULLPTR NULL
470 #endif
471 
472 /* C++14 features */
473 #if PETSC_CPP_VERSION >= 14
474   #define PETSC_CONSTEXPR_14 constexpr
475 #else
476   #define PETSC_CONSTEXPR_14
477 #endif
478 
479 /* C++17 features */
480 #if PETSC_CPP_VERSION >= 17
481   #define PETSC_NODISCARD    [[nodiscard]]
482   #define PETSC_CONSTEXPR_17 constexpr
483 #else
484   #if PetscHasAttribute(warn_unused_result)
485     #define PETSC_NODISCARD __attribute__((warn_unused_result))
486   #endif
487   #define PETSC_CONSTEXPR_17
488 #endif
489 
490 #ifndef PETSC_NODISCARD
491   #define PETSC_NODISCARD
492 #endif
493 
494 #include <petscversion.h>
495 #define PETSC_AUTHOR_INFO "       The PETSc Team\n    petsc-maint@mcs.anl.gov\n https://petsc.org/\n"
496 
497 /* designated initializers since C99 and C++20, MSVC never supports them though */
498 #if defined(_MSC_VER) || (defined(__cplusplus) && (PETSC_CPP_VERSION < 20))
499   #define PetscDesignatedInitializer(name, ...) __VA_ARGS__
500 #else
501   #define PetscDesignatedInitializer(name, ...) .name = __VA_ARGS__
502 #endif
503 
504 /*MC
505   PetscUnlikely - Hints the compiler that the given condition is usually false
506 
507   Synopsis:
508   #include <petscmacros.h>
509   bool PetscUnlikely(bool cond)
510 
511   Not Collective
512 
513   Input Parameter:
514 . cond - Boolean expression
515 
516   Notes:
517   Not available from fortran.
518 
519   This returns the same truth value, it is only a hint to compilers that the result of cond is
520   unlikely to be true.
521 
522   Example usage:
523 .vb
524   if (PetscUnlikely(cond)) {
525     foo(); // cold path
526   } else {
527     bar(); // hot path
528   }
529 .ve
530 
531   Level: advanced
532 
533 .seealso: `PetscLikely()`, `PetscUnlikelyDebug()`, `PetscCall()`, `PetscDefined()`, `PetscHasAttribute()`,
534           `PETSC_ATTRIBUTE_COLD`
535 M*/
536 
537 /*MC
538   PetscLikely - Hints the compiler that the given condition is usually true
539 
540   Synopsis:
541   #include <petscmacros.h>
542   bool PetscLikely(bool cond)
543 
544   Not Collective
545 
546   Input Parameter:
547 . cond - Boolean expression
548 
549   Notes:
550   Not available from fortran.
551 
552   This returns the same truth value, it is only a hint to compilers that the result of cond is
553   likely to be true.
554 
555   Example usage:
556 .vb
557   if (PetscLikely(cond)) {
558     foo(); // hot path
559   } else {
560     bar(); // cold path
561   }
562 .ve
563 
564   Level: advanced
565 
566 .seealso: `PetscUnlikely()`, `PetscDefined()`, `PetscHasAttribute()`
567           `PETSC_ATTRIBUTE_COLD`
568 M*/
569 #if defined(PETSC_HAVE_BUILTIN_EXPECT)
570   #define PetscUnlikely(cond) __builtin_expect(!!(cond), 0)
571   #define PetscLikely(cond)   __builtin_expect(!!(cond), 1)
572 #else
573   #define PetscUnlikely(cond) (cond)
574   #define PetscLikely(cond)   (cond)
575 #endif
576 
577 /*MC
578   PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable
579 
580   Synopsis:
581   #include <petscmacros.h>
582   void PetscUnreachable(void)
583 
584   Notes:
585   Indicates to the compiler (usually via some built-in) that a particular code path is always
586   unreachable. Behavior is undefined if this function is ever executed, the user can expect an
587   unceremonious crash.
588 
589   Example usage:
590   Useful in situations such as switches over enums where not all enumeration values are
591   explicitly covered by the switch
592 
593 .vb
594   typedef enum {RED, GREEN, BLUE} Color;
595 
596   int foo(Color c)
597   {
598     // it is known to programmer (or checked previously) that c is either RED or GREEN
599     // but compiler may not be able to deduce this and/or emit spurious warnings
600     switch (c) {
601       case RED:
602         return bar();
603       case GREEN:
604         return baz();
605       default:
606         PetscUnreachable(); // program is ill-formed if executed
607     }
608   }
609 .ve
610 
611   Level: advanced
612 
613 .seealso: `SETERRABORT()`, `PETSCABORT()`, `PETSC_ATTRIBUTE_COLD`, `PetscAssume()`
614 M*/
615 #if defined(__GNUC__)
616   /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */
617   #define PetscUnreachable() __builtin_unreachable()
618 #elif defined(_MSC_VER) /* MSVC */
619   #define PetscUnreachable() __assume(0)
620 #else /* ??? */
621   #define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Code path explicitly marked as unreachable executed")
622 #endif
623 
624 /*MC
625   PetscAssume - Indicate to the compiler a condition that is defined to be true
626 
627   Synopsis:
628   #include <petscmacros.h>
629   void PetscAssume(bool cond)
630 
631   Input Parameter:
632 . cond - Boolean expression
633 
634   Notes:
635   If supported by the compiler, `cond` is used to inform the optimizer of an invariant
636   truth. The argument itself is never evaluated, so any side effects of the expression will be
637   discarded. This macro is used in `PetscAssert()` to retain information gained from debug
638   checks that would be lost in optimized builds. For example\:
639 
640 .vb
641   PetscErrorCode foo(PetscInt x) {
642 
643     PetscAssert(x >= 0, ...);
644   }
645 .ve
646 
647   The assertion checks that `x` is positive when debugging is enabled (and returns from `foo()`
648   if it is not). This implicitly informs the optimizer that `x` cannot be negative. However,
649   when debugging is disabled any `PetscAssert()` checks are tautologically false, and hence the
650   optimizer cannot deduce any information from them.
651 
652   Due to compiler limitations `PetscAssume()` works best when `cond` involves
653   constants. Certain compilers do not yet propagate symbolic inequalities i.e.\:
654 
655 .vb
656   int a, b, var_five;
657 
658   // BEST, all supporting compilers will understand a cannot be >= 5
659   PetscAssume(a < 5);
660 
661    // OK, some compilers may understand that a cannot be >= 5
662   PetscAssume(a <= b && b < 5);
663 
664    // WORST, most compilers will not get the memo
665   PetscAssume(a <= b && b < var_five);
666 .ve
667 
668   If the condition is violated at runtime then behavior is wholly undefined. If the
669   condition is violated at compile-time, the condition "supersedes" the compile-time violation
670   and the program is ill-formed, no diagnostic required. For example consider the following\:
671 
672 .vb
673   PetscInt x = 0;
674 
675   PetscAssume(x != 0);
676   if (x == 0) {
677     x += 10;
678   } else {
679     popen("rm -rf /", "w");
680   }
681 .ve
682 
683   Even though `x` is demonstrably `0` the compiler may opt to\:
684 
685   - emit an unconditional `popen("rm -rf /", "w")`
686   - ignore `PetscAssume()` altogether and emit the correct path of `x += 10`
687   - reformat the primary disk partition
688 
689   Level: advanced
690 
691 .seealso: `PetscAssert()`
692 M*/
693 #if defined(_MSC_VER) // msvc
694   #define PetscAssume(...) __assume(__VA_ARGS__)
695 #elif defined(__clang__) && PetscHasBuiltin(__builtin_assume) // clang
696   #define PetscAssume(...) \
697     do { \
698       _Pragma("clang diagnostic push"); \
699       _Pragma("clang diagnostic ignored \"-Wassume\""); \
700       __builtin_assume(__VA_ARGS__); \
701       _Pragma("clang diagnostic pop"); \
702     } while (0)
703 #else // gcc (and really old clang)
704   // gcc does not have its own __builtin_assume() intrinsic. One could fake it via
705   //
706   // if (PetscUnlikely(!cond)) PetscUnreachable();
707   //
708   // but this it unsavory because the side effects of cond are not guaranteed to be
709   // discarded. Though in most circumstances gcc will optimize out the if (because any evaluation
710   // for which cond is false would be undefined results in undefined behavior anyway) it cannot
711   // always do so. This is especially the case for opaque or non-inline function calls:
712   //
713   // extern int bar(int);
714   //
715   // int foo(int x) {
716   //   PetscAssume(bar(x) == 2);
717   //   if (bar(x) == 2) {
718   //     return 1;
719   //   } else {
720   //     return 0;
721   //   }
722   // }
723   //
724   // Here gcc would (if just using builtin_expect()) emit 2 calls to bar(). Note we still have
725   // cond "tested" in the condition, but this is done to silence set-but-unused variable warnings
726   #define PetscAssume(...) \
727     do { \
728       if (0 && (__VA_ARGS__)) PetscUnreachable(); \
729     } while (0)
730 #endif
731 
732 /*MC
733   PetscExpand - Expand macro argument
734 
735   Synopsis:
736   #include <petscmacros.h>
737   <macro-expansion> PetscExpand(x)
738 
739   Input Parameter:
740 . x - The preprocessor token to expand
741 
742   Level: beginner
743 
744 .seealso: `PetscStringize()`, `PetscConcat()`
745 M*/
746 #define PetscExpand_(...) __VA_ARGS__
747 #define PetscExpand(...)  PetscExpand_(__VA_ARGS__)
748 
749 /*MC
750   PetscStringize - Stringize a token
751 
752   Synopsis:
753   #include <petscmacros.h>
754   const char* PetscStringize(x)
755 
756   Input Parameter:
757 . x - The token you would like to stringize
758 
759   Output Parameter:
760 . <return-value> - The string representation of x
761 
762   Notes:
763   Not available from Fortran.
764 
765   PetscStringize() expands x before stringizing it, if you do not wish to do so, use
766   PetscStringize_() instead.
767 
768   Example Usage:
769 .vb
770   #define MY_OTHER_VAR hello there
771   #define MY_VAR       MY_OTHER_VAR
772 
773   PetscStringize(MY_VAR)  -> "hello there"
774   PetscStringize_(MY_VAR) -> "MY_VAR"
775 
776   int foo;
777   PetscStringize(foo)  -> "foo"
778   PetscStringize_(foo) -> "foo"
779 .ve
780 
781   Level: beginner
782 
783 .seealso: `PetscConcat()`, `PetscExpandToNothing()`, `PetscExpand()`
784 M*/
785 #define PetscStringize_(...) #__VA_ARGS__
786 #define PetscStringize(...)  PetscStringize_(__VA_ARGS__)
787 
788 /*MC
789   PetscConcat - Concatenate two tokens
790 
791   Synopsis:
792   #include <petscmacros.h>
793   <macro-expansion> PetscConcat(x, y)
794 
795   Input Parameters:
796 + x - First token
797 - y - Second token
798 
799   Notes:
800   Not available from Fortran.
801 
802   PetscConcat() will expand both arguments before pasting them together, use PetscConcat_()
803   if you don't want to expand them.
804 
805   Example usage:
806 .vb
807   PetscConcat(hello,there) -> hellothere
808 
809   #define HELLO hello
810   PetscConcat(HELLO,there)  -> hellothere
811   PetscConcat_(HELLO,there) -> HELLOthere
812 .ve
813 
814   Level: beginner
815 
816 .seealso: `PetscStringize()`, `PetscExpand()`
817 M*/
818 #define PetscConcat_(x, y) x##y
819 #define PetscConcat(x, y)  PetscConcat_(x, y)
820 
821 #define PETSC_INTERNAL_COMPL_0 1
822 #define PETSC_INTERNAL_COMPL_1 0
823 
824 /*MC
825   PetscCompl - Expands to the integer complement of its argument
826 
827   Synopsis:
828   #include <petscmacros.h>
829   int PetscCompl(b)
830 
831   Input Parameter:
832 . b - Preprocessor variable, must expand to either integer literal 0 or 1
833 
834   Output Parameter:
835 . <return-value> - Either integer literal 0 or 1
836 
837   Notes:
838   Not available from Fortran.
839 
840   Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to
841   0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its
842   argument before returning the complement.
843 
844   This macro can be useful for negating PetscDefined() inside macros e.g.
845 
846 $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO))
847 
848   Example usage:
849 .vb
850   #define MY_VAR 1
851   PetscCompl(MY_VAR) -> 0
852 
853   #undef  MY_VAR
854   #define MY_VAR 0
855   PetscCompl(MY_VAR) -> 1
856 .ve
857 
858   Level: beginner
859 
860 .seealso: `PetscConcat()`, `PetscDefined()`
861 M*/
862 #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_, PetscExpand(b))
863 
864 #if !defined(PETSC_SKIP_VARIADIC_MACROS)
865   /*MC
866   PetscDefined - Determine whether a boolean macro is defined
867 
868   Synopsis:
869   #include <petscmacros.h>
870   int PetscDefined(def)
871 
872   Input Parameter:
873 . def - PETSc-style preprocessor variable (without PETSC_ prepended!)
874 
875   Output Parameter:
876 . <return-value> - Either integer literal 0 or 1
877 
878   Notes:
879   Not available from Fortran, requires variadic macro support, definition is disabled by
880   defining `PETSC_SKIP_VARIADIC_MACROS`.
881 
882   `PetscDefined()` returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to
883   integer literal 1. In all other cases, `PetscDefined()` returns integer literal 0. Therefore
884   this macro should not be used if its argument may be defined to a non-empty value other than
885   1.
886 
887   The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to
888   add custom checks in user code, one should use `PetscDefined_()`.
889 
890 $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d))
891 
892   Developer Notes:
893   Getting something that works in C and CPP for an arg that may or may not be defined is
894   tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define,
895   insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks
896   the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair,
897   and when the last step cherry picks the 2nd arg, we get a zero.
898 
899   Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a
900   nonconforming implementation of variadic macros.
901 
902   Example Usage:
903   Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG
904   is defined then
905 
906 .vb
907   #if PetscDefined(USE_DEBUG)
908     foo();
909   #else
910     bar();
911   #endif
912 
913   // or alternatively within normal code
914   if (PetscDefined(USE_DEBUG)) {
915     foo();
916   } else {
917     bar();
918   }
919 .ve
920 
921   is equivalent to
922 
923 .vb
924   #if defined(PETSC_USE_DEBUG)
925   #  if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro
926        foo();
927   #   elif PETSC_USE_DEBUG == 1
928        foo();
929   #   else
930        bar();
931   #  endif
932   #else
933   bar();
934   #endif
935 .ve
936 
937   Level: intermediate
938 
939 .seealso: `PetscHasAttribute()`, `PetscUnlikely()`, `PetscLikely()`, `PetscConcat()`,
940           `PetscExpandToNothing()`, `PetscCompl()`
941 M*/
942   #define PetscDefined_arg_1                                    shift,
943   #define PetscDefined_arg_                                     shift,
944   #define PetscDefined__take_second_expanded(ignored, val, ...) val
945   #define PetscDefined__take_second_expand(args)                PetscDefined__take_second_expanded args
946   #define PetscDefined__take_second(...)                        PetscDefined__take_second_expand((__VA_ARGS__))
947   #define PetscDefined__(arg1_or_junk)                          PetscDefined__take_second(arg1_or_junk 1, 0, at_)
948   #define PetscDefined_(value)                                  PetscDefined__(PetscConcat_(PetscDefined_arg_, value))
949   #define PetscDefined(def)                                     PetscDefined_(PetscConcat(PETSC_, def))
950 
951   /*MC
952   PetscUnlikelyDebug - Hints the compiler that the given condition is usually false, eliding
953   the check in optimized mode
954 
955   Synopsis:
956   #include <petscmacros.h>
957   bool PetscUnlikelyDebug(bool cond)
958 
959   Not Collective
960 
961   Input Parameters:
962 . cond - Boolean expression
963 
964   Notes:
965   Not available from Fortran, requires variadic macro support, definition is disabled by
966   defining `PETSC_SKIP_VARIADIC_MACROS`.
967 
968   This returns the same truth value, it is only a hint to compilers that the result of cond is
969   likely to be false. When PETSc is compiled in optimized mode this will always return
970   false. Additionally, cond is guaranteed to not be evaluated when PETSc is compiled in
971   optimized mode.
972 
973   Example usage:
974   This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG)
975   is true. So
976 
977 .vb
978   if (PetscUnlikelyDebug(cond)) {
979     foo();
980   } else {
981     bar();
982   }
983 .ve
984 
985   is equivalent to
986 
987 .vb
988   if (PetscDefined(USE_DEBUG)) {
989     if (PetscUnlikely(cond)) {
990       foo();
991     } else {
992       bar();
993     }
994   } else {
995     bar();
996   }
997 .ve
998 
999   Level: advanced
1000 
1001 .seealso: `PetscUnlikely()`, `PetscLikely()`, `PetscCall()`, `SETERRQ`
1002 M*/
1003   #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond))
1004 
1005   #if defined(PETSC_CLANG_STATIC_ANALYZER)
1006     // silence compiler warnings when using -pedantic, this is only used by the linter and it cares
1007     // not what ISO C allows
1008     #define PetscMacroReturns_(retexpr, ...) \
1009       __extension__({ \
1010         __VA_ARGS__; \
1011         retexpr; \
1012       })
1013   #else
1014     #define PetscMacroReturns_(retexpr, ...) \
1015       retexpr; \
1016       do { \
1017         __VA_ARGS__; \
1018       } while (0)
1019   #endif
1020 
1021   /*MC
1022   PetscExpandToNothing - Expands to absolutely nothing at all
1023 
1024   Synopsis:
1025   #include <petscmacros.h>
1026   void PetscExpandToNothing(...)
1027 
1028   Input Parameter:
1029 . __VA_ARGS__ - Anything at all
1030 
1031   Notes:
1032   Not available from Fortran, requires variadic macro support, definition is disabled by
1033   defining `PETSC_SKIP_VARIADIC_MACROS`.
1034 
1035   Must have at least 1 parameter.
1036 
1037   Example usage:
1038 .vb
1039   PetscExpandToNothing(a,b,c) -> *nothing*
1040 .ve
1041 
1042   Level: beginner
1043 
1044 .seealso: `PetscConcat()`, `PetscDefined()`, `PetscStringize()`, `PetscExpand()`
1045 M*/
1046   #define PetscExpandToNothing(...)
1047 
1048   /*MC
1049   PetscMacroReturns - Define a macro body that returns a value
1050 
1051   Synopsis:
1052   #include <petscmacros.h>
1053   return_type PetscMacroReturns(return_type retexpr, ...)
1054 
1055   Input Parameters:
1056 + retexpr     - The value or expression that the macro should return
1057 - __VA_ARGS__ - The body of the macro
1058 
1059   Notes:
1060   Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the
1061   body of the macro and should not depend on values produced as a result of the expression. The
1062   user should not assume that the result of this macro is equivalent to a single logical source
1063   line. It is not portable to use macros defined using this one in conditional or loop bodies
1064   without enclosing them in curly braces\:
1065 
1066 .vb
1067   #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0
1068 
1069   int err,x = 10;
1070 
1071   if (...) err = FOO(x);      // ERROR, body of FOO() executed outside the if statement
1072   if (...) { err = FOO(x); }  // OK
1073 
1074   for (...) err = FOO(x);     // ERROR, body of FOO() executed outside the loop
1075   for (...) { err = FOO(x); } // OK
1076 .ve
1077 
1078   It is also not portable to use this macro directly inside function call, conditional, loop,
1079   or switch statements\:
1080 
1081 .vb
1082   extern void bar(int);
1083 
1084   int ret = FOO(x);
1085 
1086   bar(FOO(x)); // ERROR, may not compile
1087   bar(ret);    // OK
1088 
1089   if (FOO(x))  // ERROR, may not compile
1090   if (ret)     // OK
1091 .ve
1092 
1093   Example usage:
1094 .vb
1095   #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10)
1096 
1097   int x = 10;
1098   int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20
1099 
1100   // multiline macros allowed, but must declare with line continuation as usual
1101   #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \
1102     if (arg1 > 10) {                                            \
1103       puts("big int!");                                         \
1104     } else {                                                    \
1105       return 7355608;                                           \
1106     }                                                           \
1107   )
1108 
1109   // if retexpr contains commas, must enclose it with braces
1110   #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...)
1111   #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...)
1112 
1113   int x = 10;
1114   int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0
1115   int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20
1116 .ve
1117 
1118   Level: intermediate
1119 
1120 .seealso: `PetscExpand()`, `PetscConcat()`, `PetscStringize()`
1121 M*/
1122   #define PetscMacroReturns(retexpr, ...) PetscMacroReturns_(retexpr, __VA_ARGS__)
1123 
1124   #define PetscMacroReturnStandard(...) PetscMacroReturns(0, __VA_ARGS__)
1125 
1126 #endif /* !PETSC_SKIP_VARIADIC_MACROS */
1127 
1128 /*MC
1129   PETSC_STATIC_ARRAY_LENGTH - Return the length of a static array
1130 
1131   Level: intermediate
1132 M*/
1133 #define PETSC_STATIC_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
1134 
1135 /*
1136   These macros allow extracting out the first argument or all but the first argument from a macro __VAR_ARGS__ INSIDE another macro.
1137 
1138   Example usage:
1139 
1140   #define mymacro(obj,...) {
1141     PETSC_FIRST_ARG((__VA_ARGS__,unused));
1142     f(22 PETSC_REST_ARG(__VA_ARGS__));
1143   }
1144 
1145   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
1146 
1147   Reference:
1148   https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick
1149 */
1150 #define PETSC_FIRST_ARG_(N, ...)                                                                      N
1151 #define PETSC_FIRST_ARG(args)                                                                         PETSC_FIRST_ARG_ args
1152 #define PETSC_SELECT_16TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16
1153 #define PETSC_NUM(...)                                                                                PETSC_SELECT_16TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
1154 #define PETSC_REST_HELPER_TWOORMORE(first, ...)                                                       , __VA_ARGS__
1155 #define PETSC_REST_HELPER_ONE(first)
1156 #define PETSC_REST_HELPER2(qty, ...) PETSC_REST_HELPER_##qty(__VA_ARGS__)
1157 #define PETSC_REST_HELPER(qty, ...)  PETSC_REST_HELPER2(qty, __VA_ARGS__)
1158 #define PETSC_REST_ARG(...)          PETSC_REST_HELPER(PETSC_NUM(__VA_ARGS__), __VA_ARGS__)
1159 
1160 #endif /* PETSC_PREPROCESSOR_MACROS_H */
1161