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 */