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