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