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: /* ========================================================================== */
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
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
24: #if defined(__cplusplus)
25: # define PETSC_RESTRICT PETSC_CXX_RESTRICT
26: #else
27: # define PETSC_RESTRICT restrict
28: #endif
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
33: #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */
34: # define __declspec(dllexport)
35: # define PETSC_DLLIMPORT __declspec(dllimport)
36: # define PETSC_VISIBILITY_INTERNAL
37: #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX)
38: # define __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 __attribute__((visibility ("default")))
43: # define PETSC_DLLIMPORT __attribute__((visibility ("default")))
44: # define PETSC_VISIBILITY_INTERNAL __attribute__((visibility ("hidden")))
45: #else
46: # define
47: # define PETSC_DLLIMPORT
48: # define PETSC_VISIBILITY_INTERNAL
49: #endif
51: #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */
52: # define PETSC_VISIBILITY_PUBLIC
53: #else /* Win32 users need this to import symbols from petsc.dll */
54: # define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT
55: #endif
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
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
76: /*MC
77: PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler
79: Synopsis:
80: #include <petscmacros.h>
81: boolean PetscHasAttribute(name)
83: Input Parameter:
84: . name - The name of the attribute to test
86: Notes:
87: name should be identical to what you might pass to the __attribute__ declaration itself --
88: plain, unbroken text.
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.
95: Example Usage:
96: Typical usage is using the preprocessor
98: .vb
99: #if PetscHasAttribute(always_inline)
100: # define MY_ALWAYS_INLINE __attribute__((always_inline))
101: #else
102: # define MY_ALWAYS_INLINE
103: #endif
105: void foo(void) MY_ALWAYS_INLINE;
106: .ve
108: but it can also be used in regular code
110: .vb
111: if (PetscHasAttribute(some_attribute)) {
112: foo();
113: } else {
114: bar();
115: }
116: .ve
118: Level: intermediate
120: .seealso: PetscDefined(), PetscLikely(), PetscUnlikely()
121: M*/
123: # define __has_attribute(x) 0
124: #endif
125: #define PetscHasAttribute(name) __has_attribute(name)
127: /*MC
128: PETSC_ATTRIBUTE_COLD - Indicate to the compiler that a function is very unlikely to be
129: executed
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.
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.
139: Example Usage:
140: .vb
141: void my_error_handler(...) PETSC_ATTRIBUTE_COLD;
143: if (temperature < 0) {
144: return my_error_handler(...); // chilly!
145: }
146: .ve
148: Level: intermediate
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
161: /*MC
162: PETSC_NULLPTR - Standard way of indicating a null value or pointer
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\:
170: .vb
171: ptr == PETSC_NULLPTR
172: ptr == NULL
173: ptr == 0
174: !ptr
176: ptr = PETSC_NULLPTR
177: ptr = NULL
178: ptr = 0
179: .ve
181: and for completeness' sake\:
183: .vb
184: PETSC_NULLPTR == NULL
185: .ve
187: Fortran Notes:
188: Not available in Fortran
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: };
199: // may be used to nullify objects
200: PetscObject obj = PETSC_NULLPTR;
202: // may be used in any function expecting NULL
203: PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor");
204: .ve
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.
211: Level: beginner
213: .seealso: PETSC_CONSTEXPR_14, PETSC_NODISCARD
214: M*/
216: /*MC
217: PETSC_CONSTEXPR_14 - C++14 constexpr
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.
225: Fortran Notes:
226: Not available in Fortran
228: Example Usage:
229: .vb
230: PETSC_CONSTEXPR_14 int factorial(int n)
231: {
232: int r = 1;
234: do {
235: r *= n;
236: } while (--n);
237: return r;
238: }
239: .ve
241: Level: beginner
243: .seealso: PETSC_NULLPTR, PETSC_NODISCARD
244: M*/
246: /*MC
247: PETSC_NODISCARD - Mark the return value of a function as non-discardable
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.
254: Fortran Notes:
255: Not available in Fortran
257: Example Usage:
258: .vb
259: class Foo
260: {
261: int x;
263: public:
264: PETSC_NODISCARD Foo(int y) : x(y) { }
265: };
267: PETSC_NODISCARD int factorial(int n)
268: {
269: return n <= 1 ? 1 : (n * factorial(n - 1));
270: }
272: auto x = factorial(10); // OK, capturing return value
273: factorial(10); // Warning: ignoring return value of function declared 'nodiscard'
275: auto f = Foo(x); // OK, capturing constructed object
276: Foo(x); // Warning: Ignoring temporary created by a constructor declared 'nodiscard'
277: .ve
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.
284: Level: beginner
286: .seealso: PETSC_NULLPTR, PETSC_CONSTEXPR_14
287: M*/
289: /* C++11 features */
290: #if defined(__cplusplus)
291: # define PETSC_NULLPTR nullptr
292: #else
293: # define PETSC_NULLPTR NULL
294: #endif
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
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
316: #include <petscversion.h>
317: #define PETSC_AUTHOR_INFO " The PETSc Team\n petsc-maint@mcs.anl.gov\n https://petsc.org/\n"
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
326: /*MC
327: PetscUnlikely - Hints the compiler that the given condition is usually FALSE
329: Synopsis:
330: #include <petscmacros.h>
331: bool PetscUnlikely(bool cond)
333: Not Collective
335: Input Parameter:
336: . cond - Boolean expression
338: Notes:
339: Not available from fortran.
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.
344: Example usage:
345: .vb
346: if (PetscUnlikely(cond)) {
347: foo(); // cold path
348: } else {
349: bar(); // hot path
350: }
351: .ve
353: Level: advanced
355: .seealso: PetscLikely(), PetscUnlikelyDebug(), PetscCall(), PetscDefined(), PetscHasAttribute(),
356: PETSC_ATTRIBUTE_COLD
357: M*/
359: /*MC
360: PetscLikely - Hints the compiler that the given condition is usually TRUE
362: Synopsis:
363: #include <petscmacros.h>
364: bool PetscLikely(bool cond)
366: Not Collective
368: Input Parameter:
369: . cond - Boolean expression
371: Notes:
372: Not available from fortran.
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.
377: Example usage:
378: .vb
379: if (PetscLikely(cond)) {
380: foo(); // hot path
381: } else {
382: bar(); // cold path
383: }
384: .ve
386: Level: advanced
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
399: /*MC
400: PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable
402: Synopsis:
403: #include <petscmacros.h>
404: void PetscUnreachable(void)
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.
411: Example usage:
412: Useful in situations such as switches over enums where not all enumeration values are
413: explicitly covered by the switch
415: .vb
416: typedef enum {RED, GREEN, BLUE} Color;
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
433: Level: advanced
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
446: /*MC
447: PetscExpand - Expand macro argument
449: Synopsis:
450: #include <petscmacros.h>
451: <macro-expansion> PetscExpand(x)
453: Input Parameter:
454: . x - The preprocessor token to expand
456: Level: beginner
458: .seealso: PetscStringize(), PetscConcat()
459: M*/
460: #define PetscExpand_(...) __VA_ARGS__
461: #define PetscExpand(...) PetscExpand_(__VA_ARGS__)
463: /*MC
464: PetscStringize - Stringize a token
466: Synopsis:
467: #include <petscmacros.h>
468: const char* PetscStringize(x)
470: Input Parameter:
471: . x - The token you would like to stringize
473: Output Parameter:
474: . <return-value> - The string representation of x
476: Notes:
477: Not available from Fortran.
479: PetscStringize() expands x before stringizing it, if you do not wish to do so, use
480: PetscStringize_() instead.
482: Example Usage:
483: .vb
484: #define MY_OTHER_VAR hello there
485: #define MY_VAR MY_OTHER_VAR
487: PetscStringize(MY_VAR) -> "hello there"
488: PetscStringize_(MY_VAR) -> "MY_VAR"
490: int foo;
491: PetscStringize(foo) -> "foo"
492: PetscStringize_(foo) -> "foo"
493: .ve
495: Level: beginner
497: .seealso: PetscConcat(), PetscExpandToNothing(), PetscExpand()
498: M*/
499: #define PetscStringize_(x) #x
500: #define PetscStringize(x) PetscStringize_(x)
502: /*MC
503: PetscConcat - Concatenate two tokens
505: Synopsis:
506: #include <petscmacros.h>
507: <macro-expansion> PetscConcat(x, y)
509: Input Parameters:
510: + x - First token
511: - y - Second token
513: Notes:
514: Not available from Fortran.
516: PetscConcat() will expand both arguments before pasting them together, use PetscConcat_()
517: if you don't want to expand them.
519: Example usage:
520: .vb
521: PetscConcat(hello,there) -> hellothere
523: #define HELLO hello
524: PetscConcat(HELLO,there) -> hellothere
525: PetscConcat_(HELLO,there) -> HELLOthere
526: .ve
528: Level: beginner
530: .seealso: PetscStringize(), PetscExpand()
531: M*/
532: #define PetscConcat_(x,y) x ## y
533: #define PetscConcat(x,y) PetscConcat_(x,y)
535: #define PETSC_INTERNAL_COMPL_0 1
536: #define PETSC_INTERNAL_COMPL_1 0
538: /*MC
539: PetscCompl - Expands to the integer complement of its argument
541: Synopsis:
542: #include <petscmacros.h>
543: int PetscCompl(b)
545: Input Parameter:
546: . b - Preprocessor variable, must expand to either integer literal 0 or 1
548: Output Parameter:
549: . <return-value> - Either integer literal 0 or 1
551: Notes:
552: Not available from Fortran.
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.
558: This macro can be useful for negating PetscDefined() inside macros e.g.
560: $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO))
562: Example usage:
563: .vb
564: #define MY_VAR 1
565: PetscCompl(MY_VAR) -> 0
567: #undef MY_VAR
568: #define MY_VAR 0
569: PetscCompl(MY_VAR) -> 1
570: .ve
572: Level: beginner
574: .seealso: PetscConcat(), PetscDefined()
575: M*/
576: #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_,PetscExpand(b))
578: #if !defined(PETSC_SKIP_VARIADIC_MACROS)
579: /*MC
580: PetscDefined - Determine whether a boolean macro is defined
582: Synopsis:
583: #include <petscmacros.h>
584: int PetscDefined(def)
586: Input Parameter:
587: . def - PETSc-style preprocessor variable (without PETSC_ prepended!)
589: Outut Parameter:
590: . <return-value> - Either integer literal 0 or 1
592: Notes:
593: Not available from Fortran, requires variadic macro support, definition is disabled by
594: defining PETSC_SKIP_VARIADIC_MACROS.
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.
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_().
604: $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d))
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.
613: Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a
614: nonconforming implementation of variadic macros.
616: Example Usage:
617: Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG
618: is defined then
620: .vb
621: #if PetscDefined(USE_DEBUG)
622: foo();
623: #else
624: bar();
625: #endif
627: // or alternatively within normal code
628: if (PetscDefined(USE_DEBUG)) {
629: foo();
630: } else {
631: bar();
632: }
633: .ve
635: is equivalent to
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
651: Level: intermediate
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))
665: /*MC
666: PetscUnlikelyDebug - Hints the compiler that the given condition is usually FALSE, eliding
667: the check in optimized mode
669: Synopsis:
670: #include <petscmacros.h>
671: bool PetscUnlikelyDebug(bool cond)
673: Not Collective
675: Input Parameters:
676: . cond - Boolean expression
678: Notes:
679: Not available from Fortran, requires variadic macro support, definition is disabled by
680: defining PETSC_SKIP_VARIADIC_MACROS.
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.
687: Example usage:
688: This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG)
689: is true. So
691: .vb
692: if (PetscUnlikelyDebug(cond)) {
693: foo();
694: } else {
695: bar();
696: }
697: .ve
699: is equivalent to
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
713: Level: advanced
715: .seealso: PetscUnlikely(), PetscLikely(), PetscCall(), SETERRQ
716: M*/
717: #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond))
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
727: /*MC
728: PetscExpandToNothing - Expands to absolutely nothing at all
730: Synopsis:
731: #include <petscmacros.h>
732: void PetscExpandToNothing(...)
734: Input Parameter:
735: . __VA_ARGS__ - Anything at all
737: Notes:
738: Not available from Fortran, requires variadic macro support, definition is disabled by
739: defining PETSC_SKIP_VARIADIC_MACROS.
741: Must have at least 1 parameter.
743: Example usage:
744: .vb
745: PetscExpandToNothing(a,b,c) -> *nothing*
746: .ve
748: Level: beginner
750: .seealso: PetscConcat(), PetscDefined(), PetscStringize(), PetscExpand()
751: M*/
752: #define PetscExpandToNothing(...)
754: /*MC
755: PetscMacroReturns - Define a macro body that returns a value
757: Synopsis:
758: #include <petscmacros.h>
759: return_type PetscMacroReturns(return_type retexpr, ...)
761: Input Parameters:
762: + retexpr - The value or expression that the macro should return
763: - __VA_ARGS__ - The body of the macro
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\:
772: .vb
773: #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0
775: int err,x = 10;
777: if (...) err = FOO(x); // ERROR, body of FOO() executed outside the if statement
778: if (...) { err = FOO(x); } // OK
780: for (...) err = FOO(x); // ERROR, body of FOO() executed outside the loop
781: for (...) { err = FOO(x); } // OK
782: .ve
784: It is also not portable to use this macro directly inside function call, conditional, loop,
785: or switch statements\:
787: .vb
788: extern void bar(int);
790: int ret = FOO(x);
792: bar(FOO(x)); // ERROR, may not compile
793: bar(ret); // OK
795: if (FOO(x)) // ERROR, may not compile
796: if (ret) // OK
797: .ve
799: Example usage:
800: .vb
801: #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10)
803: int x = 10;
804: int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20
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: )
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...)
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
824: Level: intermediate
826: .seealso: PetscExpand(), PetscConcat(), PetscStringize()
827: M*/
828: #define PetscMacroReturns(retexpr,...) PetscMacroReturns_(retexpr,__VA_ARGS__)
830: #define PetscMacroReturnStandard(...) PetscMacroReturns(0,__VA_ARGS__)
832: #endif /* !PETSC_SKIP_VARIADIC_MACROS */
834: #endif /* PETSC_PREPROCESSOR_MACROS_H */