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