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