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