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 Paramter: 454 . x - The preprocessor token to expand 455 456 .seealso: PetscStringize(), PetscConcat() 457 M*/ 458 #define PetscExpand_(...) __VA_ARGS__ 459 #define PetscExpand(...) PetscExpand_(__VA_ARGS__) 460 461 /*MC 462 PetscStringize - Stringize a token 463 464 Synopsis: 465 #include <petscmacros.h> 466 const char* PetscStringize(x) 467 468 Input Parameter: 469 . x - The token you would like to stringize 470 471 Output Parameter: 472 . <return-value> - The string representation of x 473 474 Notes: 475 Not available from Fortran. 476 477 PetscStringize() expands x before stringizing it, if you do not wish to do so, use 478 PetscStringize_() instead. 479 480 Example Usage: 481 .vb 482 #define MY_OTHER_VAR hello there 483 #define MY_VAR MY_OTHER_VAR 484 485 PetscStringize(MY_VAR) -> "hello there" 486 PetscStringize_(MY_VAR) -> "MY_VAR" 487 488 int foo; 489 PetscStringize(foo) -> "foo" 490 PetscStringize_(foo) -> "foo" 491 .ve 492 493 Level: beginner 494 495 .seealso: PetscConcat(), PetscExpandToNothing(), PetscExpand() 496 M*/ 497 #define PetscStringize_(x) #x 498 #define PetscStringize(x) PetscStringize_(x) 499 500 /*MC 501 PetscConcat - Concatenate two tokens 502 503 Synopsis: 504 #include <petscmacros.h> 505 <macro-expansion> PetscConcat(x, y) 506 507 Input Parameters: 508 + x - First token 509 - y - Second token 510 511 Notes: 512 Not available from Fortran. 513 514 PetscConcat() will expand both arguments before pasting them together, use PetscConcat_() 515 if you don't want to expand them. 516 517 Example usage: 518 .vb 519 PetscConcat(hello,there) -> hellothere 520 521 #define HELLO hello 522 PetscConcat(HELLO,there) -> hellothere 523 PetscConcat_(HELLO,there) -> HELLOthere 524 .ve 525 526 Level: beginner 527 528 .seealso: PetscStringize(), PetscExpand() 529 M*/ 530 #define PetscConcat_(x,y) x ## y 531 #define PetscConcat(x,y) PetscConcat_(x,y) 532 533 #define PETSC_INTERNAL_COMPL_0 1 534 #define PETSC_INTERNAL_COMPL_1 0 535 536 /*MC 537 PetscCompl - Expands to the integer complement of its argument 538 539 Synopsis: 540 #include <petscmacros.h> 541 int PetscCompl(b) 542 543 Input Parameter: 544 . b - Preprocessor variable, must expand to either integer literal 0 or 1 545 546 Output Paramter: 547 . <return-value> - Either integer literal 0 or 1 548 549 Notes: 550 Not available from Fortran. 551 552 Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to 553 0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its 554 argument before returning the complement. 555 556 This macro can be useful for negating PetscDefined() inside macros e.g. 557 558 $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO)) 559 560 Example usage: 561 .vb 562 #define MY_VAR 1 563 PetscCompl(MY_VAR) -> 0 564 565 #undef MY_VAR 566 #define MY_VAR 0 567 PetscCompl(MY_VAR) -> 1 568 .ve 569 570 Level: beginner 571 572 .seealso: PetscConcat(), PetscDefined() 573 M*/ 574 #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_,PetscExpand(b)) 575 576 #if !defined(PETSC_SKIP_VARIADIC_MACROS) 577 /*MC 578 PetscDefined - Determine whether a boolean macro is defined 579 580 Synopsis: 581 #include <petscmacros.h> 582 int PetscDefined(def) 583 584 Input Parameter: 585 . def - PETSc-style preprocessor variable (without PETSC_ prepended!) 586 587 Outut Parameter: 588 . <return-value> - Either integer literal 0 or 1 589 590 Notes: 591 Not available from Fortran, requires variadic macro support, definition is disabled by 592 defining PETSC_SKIP_VARIADIC_MACROS. 593 594 PetscDefined() returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to 595 integer literal 1. In all other cases, PetscDefined() returns integer literal 0. Therefore 596 this macro should not be used if its argument may be defined to a non-empty value other than 597 1. 598 599 The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to 600 add custom checks in user code, one should use PetscDefined_(). 601 602 $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d)) 603 604 Developer Notes: 605 Getting something that works in C and CPP for an arg that may or may not be defined is 606 tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define, 607 insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks 608 the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair, 609 and when the last step cherry picks the 2nd arg, we get a zero. 610 611 Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a 612 nonconforming implementation of variadic macros. 613 614 Example Usage: 615 Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG 616 is defined then 617 618 .vb 619 #if PetscDefined(USE_DEBUG) 620 foo(); 621 #else 622 bar(); 623 #endif 624 625 // or alternatively within normal code 626 if (PetscDefined(USE_DEBUG)) { 627 foo(); 628 } else { 629 bar(); 630 } 631 .ve 632 633 is equivalent to 634 635 .vb 636 #if defined(PETSC_USE_DEBUG) 637 # if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro 638 foo(); 639 # elif PETSC_USE_DEBUG == 1 640 foo(); 641 # else 642 bar(); 643 # endif 644 #else 645 bar(); 646 #endif 647 .ve 648 649 Level: intermediate 650 651 .seealso: PetscHasAttribute(), PetscUnlikely(), PetscLikely(), PetscConcat(), 652 PetscExpandToNothing(), PetscCompl() 653 M*/ 654 #define PetscDefined_arg_1 shift, 655 #define PetscDefined_arg_ shift, 656 #define PetscDefined__take_second_expanded(ignored, val, ...) val 657 #define PetscDefined__take_second_expand(args) PetscDefined__take_second_expanded args 658 #define PetscDefined__take_second(...) PetscDefined__take_second_expand((__VA_ARGS__)) 659 #define PetscDefined__(arg1_or_junk) PetscDefined__take_second(arg1_or_junk 1, 0, at_) 660 #define PetscDefined_(value) PetscDefined__(PetscConcat_(PetscDefined_arg_,value)) 661 #define PetscDefined(def) PetscDefined_(PetscConcat(PETSC_,def)) 662 663 /*MC 664 PetscUnlikelyDebug - Hints the compiler that the given condition is usually FALSE, eliding 665 the check in optimized mode 666 667 Synopsis: 668 #include <petscmacros.h> 669 bool PetscUnlikelyDebug(bool cond) 670 671 Not Collective 672 673 Input Parameters: 674 . cond - Boolean expression 675 676 Notes: 677 Not available from Fortran, requires variadic macro support, definition is disabled by 678 defining PETSC_SKIP_VARIADIC_MACROS. 679 680 This returns the same truth value, it is only a hint to compilers that the result of cond is 681 likely to be false. When PETSc is compiled in optimized mode this will always return 682 false. Additionally, cond is guaranteed to not be evaluated when PETSc is compiled in 683 optimized mode. 684 685 Example usage: 686 This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG) 687 is true. So 688 689 .vb 690 if (PetscUnlikelyDebug(cond)) { 691 foo(); 692 } else { 693 bar(); 694 } 695 .ve 696 697 is equivalent to 698 699 .vb 700 if (PetscDefined(USE_DEBUG)) { 701 if (PetscUnlikely(cond)) { 702 foo(); 703 } else { 704 bar(); 705 } 706 } else { 707 bar(); 708 } 709 .ve 710 711 Level: advanced 712 713 .seealso: PetscUnlikely(), PetscLikely(), PetscCall(), SETERRQ 714 M*/ 715 #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond)) 716 717 #if defined(PETSC_CLANG_STATIC_ANALYZER) 718 // silence compiler warnings when using -pedantic, this is only used by the linter and it cares 719 // not what ISO C allows 720 # define PetscMacroReturns_(retexpr,...) __extension__ ({ __VA_ARGS__; retexpr; }) 721 #else 722 # define PetscMacroReturns_(retexpr,...) retexpr; do { __VA_ARGS__; } while (0) 723 #endif 724 725 /*MC 726 PetscExpandToNothing - Expands to absolutely nothing at all 727 728 Synopsis: 729 #include <petscmacros.h> 730 void PetscExpandToNothing(...) 731 732 Input Parameter: 733 . __VA_ARGS__ - Anything at all 734 735 Notes: 736 Not available from Fortran, requires variadic macro support, definition is disabled by 737 defining PETSC_SKIP_VARIADIC_MACROS. 738 739 Must have at least 1 parameter. 740 741 Example usage: 742 .vb 743 PetscExpandToNothing(a,b,c) -> *nothing* 744 .ve 745 746 Level: beginner 747 748 .seealso: PetscConcat(), PetscDefined(), PetscStringize(), PetscExpand() 749 M*/ 750 #define PetscExpandToNothing(...) 751 752 /*MC 753 PetscMacroReturns - Define a macro body that returns a value 754 755 Synopsis: 756 #include <petscmacros.h> 757 return_type PetscMacroReturns(return_type retexpr, ...) 758 759 Input Parameters: 760 + retexpr - The value or expression that the macro should return 761 - __VA_ARGS__ - The body of the macro 762 763 Notes: 764 Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the 765 body of the macro and should not depend on values produced as a result of the expression. The 766 user should not assume that the result of this macro is equivalent to a single logical source 767 line. It is not portable to use macros defined using this one in conditional or loop bodies 768 without enclosing them in curly braces\: 769 770 .vb 771 #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0 772 773 int err,x = 10; 774 775 if (...) err = FOO(x); // ERROR, body of FOO() executed outside the if statement 776 if (...) { err = FOO(x); } // OK 777 778 for (...) err = FOO(x); // ERROR, body of FOO() executed outside the loop 779 for (...) { err = FOO(x); } // OK 780 .ve 781 782 It is also not portable to use this macro directly inside function call, conditional, loop, 783 or switch statements\: 784 785 .vb 786 extern void bar(int); 787 788 int ret = FOO(x); 789 790 bar(FOO(x)); // ERROR, may not compile 791 bar(ret); // OK 792 793 if (FOO(x)) // ERROR, may not compile 794 if (ret) // OK 795 .ve 796 797 Example usage: 798 .vb 799 #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10) 800 801 int x = 10; 802 int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20 803 804 // multiline macros allowed, but must declare with line continuation as usual 805 #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \ 806 if (arg1 > 10) { \ 807 puts("big int!"); \ 808 } else { \ 809 return 7355608; \ 810 } \ 811 ) 812 813 // if retexpr contains commas, must enclose it with braces 814 #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...) 815 #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...) 816 817 int x = 10; 818 int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0 819 int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20 820 .ve 821 822 Level: intermediate 823 824 .seealso: PetscExpand(), PetscConcat(), PetscStringize() 825 M*/ 826 #define PetscMacroReturns(retexpr,...) PetscMacroReturns_(retexpr,__VA_ARGS__) 827 828 #define PetscMacroReturnStandard(...) PetscMacroReturns(0,__VA_ARGS__) 829 830 #endif /* !PETSC_SKIP_VARIADIC_MACROS */ 831 832 #endif /* PETSC_PREPROCESSOR_MACROS_H */ 833