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