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