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