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