Actual source code: petscmacros.h

  1: #ifndef PETSC_PREPROCESSOR_MACROS_H
  2: #define PETSC_PREPROCESSOR_MACROS_H

  4: #include <petscconf.h>
  5: #include <petscconf_poison.h> /* for PetscDefined() error checking */

  7: /* SUBMANSEC = Sys */

  9: #if defined(__cplusplus)
 10:   #if __cplusplus <= 201103L
 11:     #define PETSC_CPP_VERSION 11
 12:   #elif __cplusplus <= 201402L
 13:     #define PETSC_CPP_VERSION 14
 14:   #elif __cplusplus <= 201703L
 15:     #define PETSC_CPP_VERSION 17
 16:   #elif __cplusplus <= 202002L
 17:     #define PETSC_CPP_VERSION 20
 18:   #else
 19:     #define PETSC_CPP_VERSION 22 // current year, or date of c++2b ratification
 20:   #endif
 21: #endif // __cplusplus

 23: #ifndef PETSC_CPP_VERSION
 24:   #define PETSC_CPP_VERSION 0
 25: #endif

 27: #if defined(__STDC_VERSION__)
 28:   #if __STDC_VERSION__ <= 199901L
 29:     // C99 except that 99 is >= 11 or 17 so we shorten it to 9 instead
 30:     #define PETSC_C_VERSION 9
 31:   #elif __STDC_VERSION__ <= 201112L
 32:     #define PETSC_C_VERSION 11
 33:   #elif __STDC_VERSION__ <= 201710L
 34:     #define PETSC_C_VERSION 17
 35:   #else
 36:     #define PETSC_C_VERSION 22 // current year, or date of c2b ratification
 37:   #endif
 38: #endif // __STDC_VERSION__

 40: #ifndef PETSC_C_VERSION
 41:   #define PETSC_C_VERSION 0
 42: #endif

 44: /* ========================================================================== */
 45: /* This facilitates using the C version of PETSc from C++ and the C++ version from C. */
 46: #if defined(__cplusplus)
 47:   #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_CXX
 48: #else
 49:   #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_C
 50: #endif

 52: /* ========================================================================== */
 53: /* Since PETSc manages its own extern "C" handling users should never include PETSc include
 54:  * files within extern "C". This will generate a compiler error if a user does put the include
 55:  * file within an extern "C".
 56:  */
 57: #if defined(__cplusplus)
 58: void assert_never_put_petsc_headers_inside_an_extern_c(int);
 59: void assert_never_put_petsc_headers_inside_an_extern_c(double);
 60: #endif

 62: #if defined(__cplusplus)
 63:   #define PETSC_RESTRICT PETSC_CXX_RESTRICT
 64: #else
 65:   #define PETSC_RESTRICT restrict
 66: #endif

 68: #define PETSC_INLINE        PETSC_DEPRECATED_MACRO("GCC warning \"PETSC_INLINE is deprecated (since version 3.17)\"") inline
 69: #define PETSC_STATIC_INLINE PETSC_DEPRECATED_MACRO("GCC warning \"PETSC_STATIC_INLINE is deprecated (since version 3.17)\"") static inline

 71: #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */
 72:   #define  __declspec(dllexport)
 73:   #define PETSC_DLLIMPORT __declspec(dllimport)
 74:   #define PETSC_VISIBILITY_INTERNAL
 75: #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX)
 76:   #define            __attribute__((visibility("default")))
 77:   #define PETSC_DLLIMPORT           __attribute__((visibility("default")))
 78:   #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden")))
 79: #elif !defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_C)
 80:   #define            __attribute__((visibility("default")))
 81:   #define PETSC_DLLIMPORT           __attribute__((visibility("default")))
 82:   #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden")))
 83: #else
 84:   #define 
 85:   #define PETSC_DLLIMPORT
 86:   #define PETSC_VISIBILITY_INTERNAL
 87: #endif

 89: #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */
 90:   #define PETSC_VISIBILITY_PUBLIC 
 91: #else /* Win32 users need this to import symbols from petsc.dll */
 92:   #define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT
 93: #endif

 95: /* Functions tagged with PETSC_EXTERN in the header files are always defined as extern "C" when
 96:  * compiled with C++ so they may be used from C and are always visible in the shared libraries
 97:  */
 98: #if defined(__cplusplus)
 99:   #define PETSC_EXTERN         extern "C" PETSC_VISIBILITY_PUBLIC
100:   #define PETSC_EXTERN_TYPEDEF extern "C"
101:   #define PETSC_INTERN         extern "C" PETSC_VISIBILITY_INTERNAL
102: #else
103:   #define PETSC_EXTERN extern PETSC_VISIBILITY_PUBLIC
104:   #define PETSC_EXTERN_TYPEDEF
105:   #define PETSC_INTERN extern PETSC_VISIBILITY_INTERNAL
106: #endif

108: #if defined(PETSC_USE_SINGLE_LIBRARY)
109:   #define PETSC_SINGLE_LIBRARY_INTERN PETSC_INTERN
110: #else
111:   #define PETSC_SINGLE_LIBRARY_INTERN PETSC_EXTERN
112: #endif

114: /*MC
115:   PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler

117:   Synopsis:
118: #include <petscmacros.h>
119:   int PetscHasAttribute(name)

121:   Input Parameter:
122: . name - The name of the attribute to test

124:   Notes:
125:   name should be identical to what you might pass to the __attribute__ declaration itself --
126:   plain, unbroken text.

128:   As `PetscHasAttribute()` is wrapper over the function-like macro `__has_attribute()`, the
129:   exact type and value returned is implementation defined. In practice however, it usually
130:   returns `1` if the attribute is supported and `0` if the attribute is not supported.

132:   Example Usage:
133:   Typical usage is using the preprocessor

135: .vb
136:   #if PetscHasAttribute(always_inline)
137:   #  define MY_ALWAYS_INLINE __attribute__((always_inline))
138:   #else
139:   #  define MY_ALWAYS_INLINE
140:   #endif

142:   void foo(void) MY_ALWAYS_INLINE;
143: .ve

145:   but it can also be used in regular code

147: .vb
148:   if (PetscHasAttribute(some_attribute)) {
149:     foo();
150:   } else {
151:     bar();
152:   }
153: .ve

155:   Level: intermediate

157: .seealso: `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`,
158: `PETSC_ATTRIBUTE_FORMAT`
159: M*/
162: #endif
163: #define PetscHasAttribute(name) __has_attribute(name)

165: /*MC
166:   PetscHasBuiltin - Determine whether a particular builtin method is supported by the compiler

168:   Synopsis:
169: #include <petscmacros.h>
170:   int PetscHasBuiltin(name)

172:   Input Parameter:
173: . name - the name of the builtin routine

175:   Notes:
176:   Evaluates to `1` if the builtin is supported and `0` otherwise. Note the term "evaluates"
177:   (vs "expands") is deliberate; even though `PetscHasBuiltin()` is a macro the underlying
178:   detector is itself is a compiler extension with implementation-defined return type and
179:   semantics. Some compilers implement it as a macro, others as a compiler function. In practice
180:   however, all supporting compilers return an integer boolean as described.

182:   Example Usage:
183:   Typical usage is in preprocessor directives

185: .vb
186:   #if PetscHasBuiltin(__builtin_trap)
187:   __builtin_trap();
188:   #else
189:   abort();
190:   #endif
191: .ve

193:   But it may also be used in regular code

195: .vb
196:   if (PetscHasBuiltin(__builtin_alloca)) {
197:     foo();
198:   } else {
199:     bar();
200:   }
201: .ve

203:   Level: intermediate

205: .seealso: `PetscHasAttribute()`, `PetscAssume()`
206: M*/
209: #endif
210: // clangs __has_builtin prior to clang 10 did not properly handle non-function builtins such as
211: // __builtin_types_compatible_p which take types or other non-functiony things as
212: // arguments. The correct way to detect these then is to use __is_identifier (also a clang
213: // extension). GCC has always worked as expected. see https://stackoverflow.com/a/45043153
214: #if defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 10) && defined(__is_identifier)
215:   #define PetscHasBuiltin(name) __is_identifier(name)
216: #else
217:   #define PetscHasBuiltin(name) __has_builtin(name)
218: #endif

220: #if !defined(PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG)
221:   /*
222:    Support for Clang (>=3.2) matching type tag arguments with void* buffer types.
223:    This allows the compiler to detect cases where the MPI datatype argument passed to a MPI routine
224:    does not match the actual type of the argument being passed in
225: */
226:   #if PetscHasAttribute(pointer_with_type_tag)
227:     #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) __attribute__((pointer_with_type_tag(MPI, bufno, typeno)))
228:   #endif

230:   #if PetscHasAttribute(type_tag_for_datatype)
231:     #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type)                   __attribute__((type_tag_for_datatype(MPI, type)))
232:     #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type) __attribute__((type_tag_for_datatype(MPI, type, layout_compatible)))
233:   #endif
234: #endif // PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG

236: #ifndef PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE
237:   #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno)
238: #endif

240: #ifndef PETSC_ATTRIBUTE_MPI_TYPE_TAG
241:   #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type)
242: #endif

244: #ifndef PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE
245:   #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type)
246: #endif

248: /*MC
249:   PETSC_ATTRIBUTE_FORMAT - Indicate to the compiler that specified arguments should be treated
250:   as format specifiers and checked for validity

252:   Synopsis:
253: #include <petscmacros.h>
254:   <attribute declaration> PETSC_ATTRIBUTE_FORMAT(int strIdx, int vaArgIdx)

256:   Input Parameters:
257: + strIdx   - The (1-indexed) location of the format string in the argument list
258: - vaArgIdx - The (1-indexed) location of the first formattable argument in the argument list

260:   Notes:
261:   This function attribute causes the compiler to issue warnings when the format specifier does
262:   not match the type of the variable that will be formatted, or when there exists a mismatch
263:   between the number of format specifiers and variables to be formatted. It is safe to use this
264:   macro if your compiler does not support format specifier checking (though this is
265:   exceeedingly rare).

267:   Both strIdx and vaArgIdx must be compile-time constant integer literals and cannot have the
268:   same value.

270:   The arguments to be formatted (and therefore checked by the compiler) must be "contiguous" in
271:   the argument list, that is, there is no way to indicate gaps which should not be checked.

273:   Definition is suppressed by defining `PETSC_SKIP_ATTRIBUTE_FORMAT` prior to including PETSc
274:   header files. In this case the macro will expand empty.

276:   Example Usage:
277: .vb
278:   // format string is 2nd argument, variable argument list containing args is 3rd argument
279:   void my_printf(void *obj, const char *fmt_string, ...) PETSC_ATTRIBUTE_FORMAT(2,3)

281:   int    x = 1;
282:   double y = 50.0;

284:   my_printf(NULL,"%g",x);      // WARNING, format specifier does not match for 'int'!
285:   my_printf(NULL,"%d",x,y);    // WARNING, more arguments than format specifiers!
286:   my_printf(NULL,"%d %g",x,y); // OK
287: .ve

289:   Level: developer

291: .seealso: `PETSC_ATTRIBUTE_COLD`, `PetscHasAttribute()`
292: M*/
293: #if PetscHasAttribute(format) && !defined(PETSC_SKIP_ATTRIBUTE_FORMAT)
294:   #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) __attribute__((format(printf, strIdx, vaArgIdx)))
295: #else
296:   #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx)
297: #endif

299: /*MC
300:   PETSC_ATTRIBUTE_COLD - Indicate to the compiler that a function is very unlikely to be
301:   executed

303:   Notes:
304:   The marked function is often optimized for size rather than speed and may be grouped alongside
305:   other equally frigid routines improving code locality of lukewarm or hotter parts of program.

307:   The paths leading to cold functions are usually automatically marked as unlikely by the
308:   compiler. It may thus be useful to mark functions used to handle unlikely conditions -- such
309:   as error handlers -- as cold to improve optimization of the surrounding temperate functions.

311:   Example Usage:
312: .vb
313:   void my_error_handler(...) PETSC_ATTRIBUTE_COLD;

315:   if (temperature < 0) {
316:     return my_error_handler(...); // chilly!
317:   }
318: .ve

320:   Level: intermediate

322: .seealso: `PetscUnlikely()`, `PetscUnlikelyDebug()`, `PetscLikely()`, `PetscLikelyDebug()`,
323:           `PetscUnreachable()`, `PETSC_ATTRIBUTE_FORMAT`
324: M*/
325: #if PetscHasAttribute(__cold__)
326:   #define PETSC_ATTRIBUTE_COLD __attribute__((__cold__))
327: #elif PetscHasAttribute(cold) /* some implementations (old gcc) use no underscores */
328:   #define PETSC_ATTRIBUTE_COLD __attribute__((cold))
329: #else
330:   #define PETSC_ATTRIBUTE_COLD
331: #endif

333: /*MC
334:   PETSC_NULLPTR - Standard way of indicating a null value or pointer

336:   Notes:
337:   Equivalent to NULL in C source, and nullptr in C++ source. Note that for the purposes of
338:   interoperability between C and C++, setting a pointer to `PETSC_NULLPTR` in C++ is functonially
339:   equivalent to setting the same pointer to NULL in C. That is to say that the following
340:   expressions are equivalent\:

342: .vb
343:   ptr == PETSC_NULLPTR
344:   ptr == NULL
345:   ptr == 0
346:   !ptr

348:   ptr = PETSC_NULLPTR
349:   ptr = NULL
350:   ptr = 0
351: .ve

353:   and for completeness' sake\:

355: .vb
356:   PETSC_NULLPTR == NULL
357: .ve

359:   Fortran Notes:
360:   Not available in Fortran

362:   Example Usage:
363: .vb
364:   // may be used in place of '\0' or other such teminators in the definition of char arrays
365:   const char *const MyEnumTypes[] = {
366:     "foo",
367:     "bar",
368:     PETSC_NULLPTR
369:   };

371:   // may be used to nullify objects
372:   PetscObject obj = PETSC_NULLPTR;

374:   // may be used in any function expecting NULL
375:   PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor");
376: .ve

378:   Developer Notes:
379:   `PETSC_NULLPTR` must be used in place of NULL in all C++ source files. Using NULL in source
380:   files compiled with a C++ compiler may lead to unexpected side-effects in function overload
381:   resolution and/or compiler warnings.

383:   Level: beginner

385: .seealso: `PETSC_CONSTEXPR_14`, `PETSC_NODISCARD`
386: M*/

388: /*MC
389:   PETSC_CONSTEXPR_14 - C++14 constexpr

391:   Notes:
392:   Equivalent to constexpr when using a C++ compiler that supports C++14. Expands to nothing
393:   if the C++ compiler does not support C++14 or when not compiling with a C++ compiler. Note
394:   that this cannot be used in cases where an empty expansion would result in invalid code. It
395:   is safe to use this in C source files.

397:   Fortran Notes:
398:   Not available in Fortran

400:   Example Usage:
401: .vb
402:   PETSC_CONSTEXPR_14 int factorial(int n)
403:   {
404:     int r = 1;

406:     do {
407:       r *= n;
408:     } while (--n);
409:     return r;
410:   }
411: .ve

413:   Level: beginner

415: .seealso: `PETSC_NULLPTR`, `PETSC_NODISCARD`
416: M*/

418: /*MC
419:   PETSC_NODISCARD - Mark the return value of a function as non-discardable

421:   Notes:
422:   Hints to the compiler that the return value of a function must be captured. A diagnostic may
423:   (but is not required) be emitted if the value is discarded. It is safe to use this in C
424:   and C++ source files.

426:   Fortran Notes:
427:   Not available in Fortran

429:   Example Usage:
430: .vb
431:   class Foo
432:   {
433:     int x;

435:   public:
436:     PETSC_NODISCARD Foo(int y) : x(y) { }
437:   };

439:   PETSC_NODISCARD int factorial(int n)
440:   {
441:     return n <= 1 ? 1 : (n * factorial(n - 1));
442:   }

444:   auto x = factorial(10); // OK, capturing return value
445:   factorial(10);          // Warning: ignoring return value of function declared 'nodiscard'

447:   auto f = Foo(x); // OK, capturing constructed object
448:   Foo(x);          // Warning: Ignoring temporary created by a constructor declared 'nodiscard'
449: .ve

451:   Developer Notes:
452:   It is highly recommended if not downright required that any PETSc routines written in C++
453:   returning a PetscErrorCode be marked `PETSC_NODISCARD`. Ignoring the return value of PETSc
454:   routines is not supported; unhandled errors may leave PETSc in an unrecoverable state.

456:   Level: beginner

458: .seealso: `PETSC_NULLPTR`, `PETSC_CONSTEXPR_14`
459: M*/

461: /* C++11 features */
462: #if defined(__cplusplus)
463:   #define PETSC_NULLPTR nullptr
464: #else
465:   #define PETSC_NULLPTR NULL
466: #endif

468: /* C++14 features */
469: #if PETSC_CPP_VERSION >= 14
470:   #define PETSC_CONSTEXPR_14 constexpr
471: #else
472:   #define PETSC_CONSTEXPR_14
473: #endif

475: /* C++17 features */
476: #if PETSC_CPP_VERSION >= 17
477:   #define PETSC_NODISCARD    [[nodiscard]]
478:   #define PETSC_CONSTEXPR_17 constexpr
479: #else
480:   #if PetscHasAttribute(warn_unused_result)
481:     #define PETSC_NODISCARD __attribute__((warn_unused_result))
482:   #endif
483:   #define PETSC_CONSTEXPR_17
484: #endif

486: #ifndef PETSC_NODISCARD
487:   #define PETSC_NODISCARD
488: #endif

490: #include <petscversion.h>
491: #define PETSC_AUTHOR_INFO "       The PETSc Team\n    petsc-maint@mcs.anl.gov\n https://petsc.org/\n"

493: /* designated initializers since C99 and C++20, MSVC never supports them though */
494: #if defined(_MSC_VER) || (defined(__cplusplus) && (PETSC_CPP_VERSION < 20))
495:   #define PetscDesignatedInitializer(name, ...) __VA_ARGS__
496: #else
497:   #define PetscDesignatedInitializer(name, ...) .name = __VA_ARGS__
498: #endif

500: /*MC
501:   PetscUnlikely - Hints the compiler that the given condition is usually false

503:   Synopsis:
504: #include <petscmacros.h>
505:   bool PetscUnlikely(bool cond)

507:   Not Collective

509:   Input Parameter:
510: . cond - Boolean expression

512:   Notes:
513:   Not available from fortran.

515:   This returns the same truth value, it is only a hint to compilers that the result of cond is
516:   unlikely to be true.

518:   Example usage:
519: .vb
520:   if (PetscUnlikely(cond)) {
521:     foo(); // cold path
522:   } else {
523:     bar(); // hot path
524:   }
525: .ve

527:   Level: advanced

529: .seealso: `PetscLikely()`, `PetscUnlikelyDebug()`, `PetscCall()`, `PetscDefined()`, `PetscHasAttribute()`,
530:           `PETSC_ATTRIBUTE_COLD`
531: M*/

533: /*MC
534:   PetscLikely - Hints the compiler that the given condition is usually true

536:   Synopsis:
537: #include <petscmacros.h>
538:   bool PetscLikely(bool cond)

540:   Not Collective

542:   Input Parameter:
543: . cond - Boolean expression

545:   Notes:
546:   Not available from fortran.

548:   This returns the same truth value, it is only a hint to compilers that the result of cond is
549:   likely to be true.

551:   Example usage:
552: .vb
553:   if (PetscLikely(cond)) {
554:     foo(); // hot path
555:   } else {
556:     bar(); // cold path
557:   }
558: .ve

560:   Level: advanced

562: .seealso: `PetscUnlikely()`, `PetscDefined()`, `PetscHasAttribute()`
563:           `PETSC_ATTRIBUTE_COLD`
564: M*/
565: #if defined(PETSC_HAVE_BUILTIN_EXPECT)
566:   #define PetscUnlikely(cond) __builtin_expect(!!(cond), 0)
567:   #define PetscLikely(cond)   __builtin_expect(!!(cond), 1)
568: #else
569:   #define PetscUnlikely(cond) (cond)
570:   #define PetscLikely(cond)   (cond)
571: #endif

573: /*MC
574:   PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable

576:   Synopsis:
577: #include <petscmacros.h>
578:   void PetscUnreachable(void)

580:   Notes:
581:   Indicates to the compiler (usually via some built-in) that a particular code path is always
582:   unreachable. Behavior is undefined if this function is ever executed, the user can expect an
583:   unceremonious crash.

585:   Example usage:
586:   Useful in situations such as switches over enums where not all enumeration values are
587:   explicitly covered by the switch

589: .vb
590:   typedef enum {RED, GREEN, BLUE} Color;

592:   int foo(Color c)
593:   {
594:     // it is known to programmer (or checked previously) that c is either RED or GREEN
595:     // but compiler may not be able to deduce this and/or emit spurious warnings
596:     switch (c) {
597:       case RED:
598:         return bar();
599:       case GREEN:
600:         return baz();
601:       default:
602:         PetscUnreachable(); // program is ill-formed if executed
603:     }
604:   }
605: .ve

607:   Level: advanced

609: .seealso: `SETERRABORT()`, `PETSCABORT()`, `PETSC_ATTRIBUTE_COLD`, `PetscAssume()`
610: M*/
611: #if defined(__GNUC__)
612:   /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */
613:   #define PetscUnreachable() __builtin_unreachable()
614: #elif defined(_MSC_VER) /* MSVC */
615:   #define PetscUnreachable() __assume(0)
616: #else /* ??? */
617:   #define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Code path explicitly marked as unreachable executed")
618: #endif

620: /*MC
621:   PetscAssume - Indicate to the compiler a condition that is defined to be true

623:   Synopsis:
624: #include <petscmacros.h>
625:   void PetscAssume(bool cond)

627:   Input Parameter:
628: . cond - Boolean expression

630:   Notes:
631:   If supported by the compiler, `cond` is used to inform the optimizer of an invariant
632:   truth. The argument itself is never evaluated, so any side effects of the expression will be
633:   discarded. This macro is used in `PetscAssert()` to retain information gained from debug
634:   checks that would be lost in optimized builds. For example\:

636: .vb
637:   PetscErrorCode foo(PetscInt x) {

639:     PetscAssert(x >= 0, ...);
640:   }
641: .ve

643:   The assertion checks that `x` is positive when debugging is enabled (and returns from `foo()`
644:   if it is not). This implicitly informs the optimizer that `x` cannot be negative. However,
645:   when debugging is disabled any `PetscAssert()` checks are tautologically false, and hence the
646:   optimizer cannot deduce any information from them.

648:   Due to compiler limitations `PetscAssume()` works best when `cond` involves
649:   constants. Certain compilers do not yet propagate symbolic inequalities i.e.\:

651: .vb
652:   int a, b, var_five;

654:   // BEST, all supporting compilers will understand a cannot be >= 5
655:   PetscAssume(a < 5);

657:    // OK, some compilers may understand that a cannot be >= 5
658:   PetscAssume(a <= b && b < 5);

660:    // WORST, most compilers will not get the memo
661:   PetscAssume(a <= b && b < var_five);
662: .ve

664:   If the condition is violated at runtime then behavior is wholly undefined. If the
665:   condition is violated at compile-time, the condition "supersedes" the compile-time violation
666:   and the program is ill-formed, no diagnostic required. For example consider the following\:

668: .vb
669:   PetscInt x = 0;

671:   PetscAssume(x != 0);
672:   if (x == 0) {
673:     x += 10;
674:   } else {
675:     popen("rm -rf /", "w");
676:   }
677: .ve

679:   Even though `x` is demonstrably `0` the compiler may opt to\:

681:   - emit an unconditional `popen("rm -rf /", "w")`
682:   - ignore `PetscAssume()` altogether and emit the correct path of `x += 10`
683:   - reformat the primary disk partition

685:   Level: advanced

687: .seealso: `PetscAssert()`
688: M*/
689: #if defined(_MSC_VER) // msvc
690:   #define PetscAssume(...) __assume(__VA_ARGS__)
691: #elif defined(__clang__) && PetscHasBuiltin(__builtin_assume) // clang
692:   #define PetscAssume(...) \
693:     do { \
694:       _Pragma("clang diagnostic push"); \
695:       _Pragma("clang diagnostic ignored \"-Wassume\""); \
696:       __builtin_assume(__VA_ARGS__); \
697:       _Pragma("clang diagnostic pop"); \
698:     } while (0)
699: #else // gcc (and really old clang)
700:   // gcc does not have its own __builtin_assume() intrinsic. One could fake it via
701:   //
702:   // if (PetscUnlikely(!cond)) PetscUnreachable();
703:   //
704:   // but this it unsavory because the side effects of cond are not guaranteed to be
705:   // discarded. Though in most circumstances gcc will optimize out the if (because any evaluation
706:   // for which cond is false would be undefined results in undefined behavior anyway) it cannot
707:   // always do so. This is especially the case for opaque or non-inline function calls:
708:   //
709:   // extern int bar(int);
710:   //
711:   // int foo(int x) {
712:   //   PetscAssume(bar(x) == 2);
713:   //   if (bar(x) == 2) {
714:   //     return 1;
715:   //   } else {
716:   //     return 0;
717:   //   }
718:   // }
719:   //
720:   // Here gcc would (if just using builtin_expect()) emit 2 calls to bar(). Note we still have
721:   // cond "tested" in the condition, but this is done to silence set-but-unused variable warnings
722:   #define PetscAssume(...) \
723:     do { \
724:       if (0 && (__VA_ARGS__)) PetscUnreachable(); \
725:     } while (0)
726: #endif

728: /*MC
729:   PetscExpand - Expand macro argument

731:   Synopsis:
732: #include <petscmacros.h>
733:   <macro-expansion> PetscExpand(x)

735:   Input Parameter:
736: . x - The preprocessor token to expand

738:   Level: beginner

740: .seealso: `PetscStringize()`, `PetscConcat()`
741: M*/
742: #define PetscExpand_(...) __VA_ARGS__
743: #define PetscExpand(...)  PetscExpand_(__VA_ARGS__)

745: /*MC
746:   PetscStringize - Stringize a token

748:   Synopsis:
749: #include <petscmacros.h>
750:   const char* PetscStringize(x)

752:   Input Parameter:
753: . x - The token you would like to stringize

755:   Output Parameter:
756: . <return-value> - The string representation of x

758:   Notes:
759:   Not available from Fortran.

761:   PetscStringize() expands x before stringizing it, if you do not wish to do so, use
762:   PetscStringize_() instead.

764:   Example Usage:
765: .vb
766:   #define MY_OTHER_VAR hello there
767:   #define MY_VAR       MY_OTHER_VAR

769:   PetscStringize(MY_VAR)  -> "hello there"
770:   PetscStringize_(MY_VAR) -> "MY_VAR"

772:   int foo;
773:   PetscStringize(foo)  -> "foo"
774:   PetscStringize_(foo) -> "foo"
775: .ve

777:   Level: beginner

779: .seealso: `PetscConcat()`, `PetscExpandToNothing()`, `PetscExpand()`
780: M*/
781: #define PetscStringize_(...) #__VA_ARGS__
782: #define PetscStringize(...)  PetscStringize_(__VA_ARGS__)

784: /*MC
785:   PetscConcat - Concatenate two tokens

787:   Synopsis:
788: #include <petscmacros.h>
789:   <macro-expansion> PetscConcat(x, y)

791:   Input Parameters:
792: + x - First token
793: - y - Second token

795:   Notes:
796:   Not available from Fortran.

798:   PetscConcat() will expand both arguments before pasting them together, use PetscConcat_()
799:   if you don't want to expand them.

801:   Example usage:
802: .vb
803:   PetscConcat(hello,there) -> hellothere

805:   #define HELLO hello
806:   PetscConcat(HELLO,there)  -> hellothere
807:   PetscConcat_(HELLO,there) -> HELLOthere
808: .ve

810:   Level: beginner

812: .seealso: `PetscStringize()`, `PetscExpand()`
813: M*/
814: #define PetscConcat_(x, y) x##y
815: #define PetscConcat(x, y)  PetscConcat_(x, y)

817: #define PETSC_INTERNAL_COMPL_0 1
818: #define PETSC_INTERNAL_COMPL_1 0

820: /*MC
821:   PetscCompl - Expands to the integer complement of its argument

823:   Synopsis:
824: #include <petscmacros.h>
825:   int PetscCompl(b)

827:   Input Parameter:
828: . b - Preprocessor variable, must expand to either integer literal 0 or 1

830:   Output Parameter:
831: . <return-value> - Either integer literal 0 or 1

833:   Notes:
834:   Not available from Fortran.

836:   Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to
837:   0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its
838:   argument before returning the complement.

840:   This macro can be useful for negating PetscDefined() inside macros e.g.

842: $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO))

844:   Example usage:
845: .vb
846:   #define MY_VAR 1
847:   PetscCompl(MY_VAR) -> 0

849:   #undef  MY_VAR
850:   #define MY_VAR 0
851:   PetscCompl(MY_VAR) -> 1
852: .ve

854:   Level: beginner

856: .seealso: `PetscConcat()`, `PetscDefined()`
857: M*/
858: #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_, PetscExpand(b))

860: #if !defined(PETSC_SKIP_VARIADIC_MACROS)
861:   /*MC
862:   PetscDefined - Determine whether a boolean macro is defined

864:   Synopsis:
865: #include <petscmacros.h>
866:   int PetscDefined(def)

868:   Input Parameter:
869: . def - PETSc-style preprocessor variable (without PETSC_ prepended!)

871:   Output Parameter:
872: . <return-value> - Either integer literal 0 or 1

874:   Notes:
875:   Not available from Fortran, requires variadic macro support, definition is disabled by
876:   defining `PETSC_SKIP_VARIADIC_MACROS`.

878:   `PetscDefined()` returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to
879:   integer literal 1. In all other cases, `PetscDefined()` returns integer literal 0. Therefore
880:   this macro should not be used if its argument may be defined to a non-empty value other than
881:   1.

883:   The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to
884:   add custom checks in user code, one should use `PetscDefined_()`.

886: $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d))

888:   Developer Notes:
889:   Getting something that works in C and CPP for an arg that may or may not be defined is
890:   tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define,
891:   insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks
892:   the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair,
893:   and when the last step cherry picks the 2nd arg, we get a zero.

895:   Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a
896:   nonconforming implementation of variadic macros.

898:   Example Usage:
899:   Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG
900:   is defined then

902: .vb
903:   #if PetscDefined(USE_DEBUG)
904:     foo();
905:   #else
906:     bar();
907:   #endif

909:   // or alternatively within normal code
910:   if (PetscDefined(USE_DEBUG)) {
911:     foo();
912:   } else {
913:     bar();
914:   }
915: .ve

917:   is equivalent to

919: .vb
920:   #if defined(PETSC_USE_DEBUG)
921:   #  if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro
922:        foo();
923:   #   elif PETSC_USE_DEBUG == 1
924:        foo();
925:   #   else
926:        bar();
927:   #  endif
928:   #else
929:   bar();
930:   #endif
931: .ve

933:   Level: intermediate

935: .seealso: `PetscHasAttribute()`, `PetscUnlikely()`, `PetscLikely()`, `PetscConcat()`,
936:           `PetscExpandToNothing()`, `PetscCompl()`
937: M*/
938:   #define PetscDefined_arg_1                                    shift,
939:   #define PetscDefined_arg_                                     shift,
940:   #define PetscDefined__take_second_expanded(ignored, val, ...) val
941:   #define PetscDefined__take_second_expand(args)                PetscDefined__take_second_expanded args
942:   #define PetscDefined__take_second(...)                        PetscDefined__take_second_expand((__VA_ARGS__))
943:   #define PetscDefined__(arg1_or_junk)                          PetscDefined__take_second(arg1_or_junk 1, 0, at_)
944:   #define PetscDefined_(value)                                  PetscDefined__(PetscConcat_(PetscDefined_arg_, value))
945:   #define PetscDefined(def)                                     PetscDefined_(PetscConcat(PETSC_, def))

947:   /*MC
948:   PetscUnlikelyDebug - Hints the compiler that the given condition is usually false, eliding
949:   the check in optimized mode

951:   Synopsis:
952: #include <petscmacros.h>
953:   bool PetscUnlikelyDebug(bool cond)

955:   Not Collective

957:   Input Parameters:
958: . cond - Boolean expression

960:   Notes:
961:   Not available from Fortran, requires variadic macro support, definition is disabled by
962:   defining `PETSC_SKIP_VARIADIC_MACROS`.

964:   This returns the same truth value, it is only a hint to compilers that the result of cond is
965:   likely to be false. When PETSc is compiled in optimized mode this will always return
966:   false. Additionally, cond is guaranteed to not be evaluated when PETSc is compiled in
967:   optimized mode.

969:   Example usage:
970:   This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG)
971:   is true. So

973: .vb
974:   if (PetscUnlikelyDebug(cond)) {
975:     foo();
976:   } else {
977:     bar();
978:   }
979: .ve

981:   is equivalent to

983: .vb
984:   if (PetscDefined(USE_DEBUG)) {
985:     if (PetscUnlikely(cond)) {
986:       foo();
987:     } else {
988:       bar();
989:     }
990:   } else {
991:     bar();
992:   }
993: .ve

995:   Level: advanced

997: .seealso: `PetscUnlikely()`, `PetscLikely()`, `PetscCall()`, `SETERRQ`
998: M*/
999:   #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond))

1001:   #if defined(PETSC_CLANG_STATIC_ANALYZER)
1002:     // silence compiler warnings when using -pedantic, this is only used by the linter and it cares
1003:     // not what ISO C allows
1004:     #define PetscMacroReturns_(retexpr, ...) \
1005:       __extension__({ \
1006:         __VA_ARGS__; \
1007:         retexpr; \
1008:       })
1009:   #else
1010:     #define PetscMacroReturns_(retexpr, ...) \
1011:       retexpr; \
1012:       do { \
1013:         __VA_ARGS__; \
1014:       } while (0)
1015:   #endif

1017:   /*MC
1018:   PetscExpandToNothing - Expands to absolutely nothing at all

1020:   Synopsis:
1021: #include <petscmacros.h>
1022:   void PetscExpandToNothing(...)

1024:   Input Parameter:
1025: . __VA_ARGS__ - Anything at all

1027:   Notes:
1028:   Not available from Fortran, requires variadic macro support, definition is disabled by
1029:   defining `PETSC_SKIP_VARIADIC_MACROS`.

1031:   Must have at least 1 parameter.

1033:   Example usage:
1034: .vb
1035:   PetscExpandToNothing(a,b,c) -> *nothing*
1036: .ve

1038:   Level: beginner

1040: .seealso: `PetscConcat()`, `PetscDefined()`, `PetscStringize()`, `PetscExpand()`
1041: M*/
1042:   #define PetscExpandToNothing(...)

1044:   /*MC
1045:   PetscMacroReturns - Define a macro body that returns a value

1047:   Synopsis:
1048: #include <petscmacros.h>
1049:   return_type PetscMacroReturns(return_type retexpr, ...)

1051:   Input Parameters:
1052: + retexpr     - The value or expression that the macro should return
1053: - __VA_ARGS__ - The body of the macro

1055:   Notes:
1056:   Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the
1057:   body of the macro and should not depend on values produced as a result of the expression. The
1058:   user should not assume that the result of this macro is equivalent to a single logical source
1059:   line. It is not portable to use macros defined using this one in conditional or loop bodies
1060:   without enclosing them in curly braces\:

1062: .vb
1063:   #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0

1065:   int err,x = 10;

1067:   if (...) err = FOO(x);      // ERROR, body of FOO() executed outside the if statement
1068:   if (...) { err = FOO(x); }  // OK

1070:   for (...) err = FOO(x);     // ERROR, body of FOO() executed outside the loop
1071:   for (...) { err = FOO(x); } // OK
1072: .ve

1074:   It is also not portable to use this macro directly inside function call, conditional, loop,
1075:   or switch statements\:

1077: .vb
1078:   extern void bar(int);

1080:   int ret = FOO(x);

1082:   bar(FOO(x)); // ERROR, may not compile
1083:   bar(ret);    // OK

1085:   if (FOO(x))  // ERROR, may not compile
1086:   if (ret)     // OK
1087: .ve

1089:   Example usage:
1090: .vb
1091:   #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10)

1093:   int x = 10;
1094:   int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20

1096:   // multiline macros allowed, but must declare with line continuation as usual
1097:   #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \
1098:     if (arg1 > 10) {                                            \
1099:       puts("big int!");                                         \
1100:     } else {                                                    \
1101:       return 7355608;                                           \
1102:     }                                                           \
1103:   )

1105:   // if retexpr contains commas, must enclose it with braces
1106:   #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...)
1107:   #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...)

1109:   int x = 10;
1110:   int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0
1111:   int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20
1112: .ve

1114:   Level: intermediate

1116: .seealso: `PetscExpand()`, `PetscConcat()`, `PetscStringize()`
1117: M*/
1118:   #define PetscMacroReturns(retexpr, ...) PetscMacroReturns_(retexpr, __VA_ARGS__)

1120:   #define PetscMacroReturnStandard(...) PetscMacroReturns(0, __VA_ARGS__)

1122: #endif /* !PETSC_SKIP_VARIADIC_MACROS */

1124: /*MC
1125:   PETSC_STATIC_ARRAY_LENGTH - Return the length of a static array

1127:   Level: intermediate
1128: M*/
1129: #define PETSC_STATIC_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))

1131: /*
1132:   These macros allow extracting out the first argument or all but the first argument from a macro __VAR_ARGS__ INSIDE another macro.

1134:   Example usage:

1136:   #define mymacro(obj,...) {
1137:     PETSC_FIRST_ARG((__VA_ARGS__,unused));
1138:     f(22 PETSC_REST_ARG(__VA_ARGS__));
1139:   }

1141:   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

1143:   Reference:
1144:   https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick
1145: */
1146: #define PETSC_FIRST_ARG_(N, ...)                                                                      N
1147: #define PETSC_FIRST_ARG(args)                                                                         PETSC_FIRST_ARG_ args
1148: #define PETSC_SELECT_16TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16
1149: #define PETSC_NUM(...)                                                                                PETSC_SELECT_16TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
1150: #define PETSC_REST_HELPER_TWOORMORE(first, ...)                                                       , __VA_ARGS__
1151: #define PETSC_REST_HELPER_ONE(first)
1152: #define PETSC_REST_HELPER2(qty, ...) PETSC_REST_HELPER_##qty(__VA_ARGS__)
1153: #define PETSC_REST_HELPER(qty, ...)  PETSC_REST_HELPER2(qty, __VA_ARGS__)
1154: #define PETSC_REST_ARG(...)          PETSC_REST_HELPER(PETSC_NUM(__VA_ARGS__), __VA_ARGS__)

1156: #endif /* PETSC_PREPROCESSOR_MACROS_H */