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_NULLPTR - Standard way of indicating a null value or pointer 129 130 Notes: 131 Equivalent to NULL in C source, and nullptr in C++ source. Note that for the purposes of 132 interoperability between C and C++, setting a pointer to PETSC_NULLPTR in C++ is functonially 133 equivalent to setting the same pointer to NULL in C. That is to say that the following 134 expressions are equivalent\: 135 136 .vb 137 ptr == PETSC_NULLPTR 138 ptr == NULL 139 ptr == 0 140 !ptr 141 142 ptr = PETSC_NULLPTR 143 ptr = NULL 144 ptr = 0 145 .ve 146 147 and for completeness' sake\: 148 149 .vb 150 PETSC_NULLPTR == NULL 151 .ve 152 153 Fortran Notes: 154 Not available in Fortran 155 156 Example Usage: 157 .vb 158 // may be used in place of '\0' or other such teminators in the definition of char arrays 159 const char *const MyEnumTypes[] = { 160 "foo", 161 "bar", 162 PETSC_NULLPTR 163 }; 164 165 // may be used to nullify objects 166 PetscObject obj = PETSC_NULLPTR; 167 168 // may be used in any function expecting NULL 169 PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor"); 170 .ve 171 172 Developer Notes: 173 PETSC_NULLPTR must be used in place of NULL in all C++ source files. Using NULL in source 174 files compiled with a C++ compiler may lead to unexpected side-effects in function overload 175 resolution and/or compiler warnings. 176 177 Level: beginner 178 179 .seealso: PETSC_CONSTEXPR_14, PETSC_NODISCARD 180 MC*/ 181 182 /*MC 183 PETSC_CONSTEXPR_14 - C++14 constexpr 184 185 Notes: 186 Equivalent to constexpr when using a C++ compiler that supports C++14. Expands to nothing 187 if the C++ compiler does not suppport C++14 or when not compiling with a C++ compiler. Note 188 that this cannot be used in cases where an empty expansion would result in invalid code. It 189 is safe to use this in C source files. 190 191 Fortran Notes: 192 Not available in Fortran 193 194 Example Usage: 195 .vb 196 PETSC_CONSTEXPR_14 int factorial(int n) 197 { 198 int r = 1; 199 200 do { 201 r *= n; 202 } while (--n); 203 return r; 204 } 205 .ve 206 207 Level: beginner 208 209 .seealso: PETSC_NULLPTR, PETSC_NODISCARD 210 MC*/ 211 212 /*MC 213 PETSC_NODISCARD - Mark the return value of a function as non-discardable 214 215 Notes: 216 Hints to the compiler that the return value of a function must be captured. A diagnostic may 217 (but is not required) be emitted if the value is discarded. It is safe to use this in C 218 and C++ source files. 219 220 Fortran Notes: 221 Not available in Fortran 222 223 Example Usage: 224 .vb 225 class Foo 226 { 227 int x; 228 229 public: 230 PETSC_NODISCARD Foo(int y) : x(y) { } 231 }; 232 233 PETSC_NODISCARD int factorial(int n) 234 { 235 return n <= 1 ? 1 : (n * factorial(n - 1)); 236 } 237 238 auto x = factorial(10); // OK, capturing return value 239 factorial(10); // Warning: ignoring return value of function declared 'nodiscard' 240 241 auto f = Foo(x); // OK, capturing constructed object 242 Foo(x); // Warning: Ignoring temporary created by a constructor declared 'nodiscard' 243 .ve 244 245 Developer Notes: 246 It is highly recommended if not downright required that any PETSc routines written in C++ 247 returning a PetscErrorCode be marked PETSC_NODISCARD. Ignoring the return value of PETSc 248 routines is not supported; unhandled errors may leave PETSc in an unrecoverable state. 249 250 Level: beginner 251 252 .seealso: PETSC_NULLPTR, PETSC_CONSTEXPR_14 253 MC*/ 254 255 /* C++11 features */ 256 #if defined(__cplusplus) 257 # define PETSC_NULLPTR nullptr 258 #else 259 # define PETSC_NULLPTR NULL 260 #endif 261 262 /* C++14 features */ 263 #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_DIALECT_CXX14) 264 # define PETSC_CONSTEXPR_14 constexpr 265 #else 266 # define PETSC_CONSTEXPR_14 267 #endif 268 269 /* C++17 features */ 270 /* We met cases that the host CXX compiler (say mpicxx) supports C++17, but nvcc does not 271 * agree, even with -ccbin mpicxx! */ 272 #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_DIALECT_CXX17) && (!defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_CUDA_DIALECT_CXX17)) 273 # define PETSC_NODISCARD [[nodiscard]] 274 #else 275 # if PetscHasAttribute(warn_unused_result) 276 # define PETSC_NODISCARD __attribute__((warn_unused_result)) 277 # else 278 # define PETSC_NODISCARD 279 # endif 280 #endif 281 282 #include <petscversion.h> 283 #define PETSC_AUTHOR_INFO " The PETSc Team\n petsc-maint@mcs.anl.gov\n https://petsc.org/\n" 284 285 /* designated initializers since C99 and C++20, MSVC never supports them though */ 286 #if defined(_MSC_VER) || (defined(__cplusplus) && (__cplusplus < 202002L)) 287 # define PetscDesignatedInitializer(name,...) __VA_ARGS__ 288 #else 289 # define PetscDesignatedInitializer(name,...) .name = __VA_ARGS__ 290 #endif 291 292 /*MC 293 PetscUnlikely - Hints the compiler that the given condition is usually FALSE 294 295 Synopsis: 296 #include <petscmacros.h> 297 bool PetscUnlikely(bool cond) 298 299 Not Collective 300 301 Input Parameter: 302 . cond - Boolean expression 303 304 Notes: 305 Not available from fortran. 306 307 This returns the same truth value, it is only a hint to compilers that the result of cond is 308 unlikely to be true. 309 310 Example usage: 311 .vb 312 if (PetscUnlikely(cond)) { 313 foo(); // cold path 314 } else { 315 bar(); // hot path 316 } 317 .ve 318 319 Level: advanced 320 321 .seealso: PetscLikely(), PetscUnlikelyDebug(), CHKERRQ, PetscDefined(), PetscHasAttribute() 322 M*/ 323 324 /*MC 325 PetscLikely - Hints the compiler that the given condition is usually TRUE 326 327 Synopsis: 328 #include <petscmacros.h> 329 bool PetscLikely(bool cond) 330 331 Not Collective 332 333 Input Parameter: 334 . cond - Boolean expression 335 336 Notes: 337 Not available from fortran. 338 339 This returns the same truth value, it is only a hint to compilers that the result of cond is 340 likely to be true. 341 342 Example usage: 343 .vb 344 if (PetscLikely(cond)) { 345 foo(); // hot path 346 } else { 347 bar(); // cold path 348 } 349 .ve 350 351 Level: advanced 352 353 .seealso: PetscUnlikely(), PetscDefined(), PetscHasAttribute() 354 M*/ 355 #if defined(PETSC_HAVE_BUILTIN_EXPECT) 356 # define PetscUnlikely(cond) __builtin_expect(!!(cond),0) 357 # define PetscLikely(cond) __builtin_expect(!!(cond),1) 358 #else 359 # define PetscUnlikely(cond) (cond) 360 # define PetscLikely(cond) (cond) 361 #endif 362 363 /*MC 364 PetscUnreachable() - Indicate to the compiler that a code-path is logically unreachable 365 366 Synopsis: 367 #include <petscmacros.h> 368 void PetscUnreachable(void) 369 370 Notes: 371 Indicates to the compiler (usually via some built-in) that a particular code path is always 372 unreachable. Behavior is undefined if this function is ever executed, the user can expect an 373 unceremonious crash. 374 375 Example usage: 376 Useful in situations such as switches over enums where not all enumeration values are 377 explicitly covered by the switch 378 379 .vb 380 typedef enum {RED, GREEN, BLUE} Color; 381 382 int foo(Color c) 383 { 384 // it is known to programmer (or checked previously) that c is either RED or GREEN 385 // but compiler may not be able to deduce this and/or emit spurious warnings 386 switch (c) { 387 case RED: 388 return bar(); 389 case GREEN: 390 return baz(); 391 default: 392 PetscUnreachable(); // program is ill-formed if executed 393 } 394 } 395 .ve 396 397 Level: advanced 398 399 .seealso: SETERRABORT(), PETSCABORT() 400 MC*/ 401 #if defined(__GNUC__) 402 /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */ 403 # define PetscUnreachable() __builtin_unreachable() 404 #elif defined(_MSC_VER) /* MSVC */ 405 # define PetscUnreachable() __assume(0) 406 #else /* ??? */ 407 # define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Code path explicitly marked as unreachable executed") 408 #endif 409 410 /*MC 411 PetscExpand - Expand macro argument 412 413 Synopsis: 414 #include <petscmacros.h> 415 <macro-expansion> PetscExpand(x) 416 417 Input Paramter: 418 . x - The preprocessor token to expand 419 420 .seealso: PetscStringize(), PetscConcat() 421 MC*/ 422 #define PetscExpand_(...) __VA_ARGS__ 423 #define PetscExpand(...) PetscExpand_(__VA_ARGS__) 424 425 /*MC 426 PetscStringize - Stringize a token 427 428 Synopsis: 429 #include <petscmacros.h> 430 const char* PetscStringize(x) 431 432 Input Parameter: 433 . x - The token you would like to stringize 434 435 Output Parameter: 436 . <return-value> - The string representation of x 437 438 Notes: 439 Not available from Fortran. 440 441 PetscStringize() expands x before stringizing it, if you do not wish to do so, use 442 PetscStringize_() instead. 443 444 Example Usage: 445 .vb 446 #define MY_OTHER_VAR hello there 447 #define MY_VAR MY_OTHER_VAR 448 449 PetscStringize(MY_VAR) -> "hello there" 450 PetscStringize_(MY_VAR) -> "MY_VAR" 451 452 int foo; 453 PetscStringize(foo) -> "foo" 454 PetscStringize_(foo) -> "foo" 455 .ve 456 457 Level: beginner 458 459 .seealso: PetscConcat(), PetscExpandToNothing(), PetscExpand() 460 MC*/ 461 #define PetscStringize_(x) #x 462 #define PetscStringize(x) PetscStringize_(x) 463 464 /*MC 465 PetscConcat - Concatenate two tokens 466 467 Synopsis: 468 #include <petscmacros.h> 469 <macro-expansion> PetscConcat(x, y) 470 471 Input Parameters: 472 + x - First token 473 - y - Second token 474 475 Notes: 476 Not available from Fortran. 477 478 PetscConcat() will expand both arguments before pasting them together, use PetscConcat_() 479 if you don't want to expand them. 480 481 Example usage: 482 .vb 483 PetscConcat(hello,there) -> hellothere 484 485 #define HELLO hello 486 PetscConcat(HELLO,there) -> hellothere 487 PetscConcat_(HELLO,there) -> HELLOthere 488 .ve 489 490 Level: beginner 491 492 .seealso: PetscStringize(), PetscExpand() 493 MC*/ 494 #define PetscConcat_(x,y) x ## y 495 #define PetscConcat(x,y) PetscConcat_(x,y) 496 497 #define PETSC_INTERNAL_COMPL_0 1 498 #define PETSC_INTERNAL_COMPL_1 0 499 500 /*MC 501 PetscCompl - Expands to the integer complement of its argument 502 503 Synopsis: 504 #include <petscmacros.h> 505 int PetscCompl(b) 506 507 Input Parameter: 508 . b - Preprocessor variable, must expand to either integer literal 0 or 1 509 510 Output Paramter: 511 . <return-value> - Either integer literal 0 or 1 512 513 Notes: 514 Not available from Fortran. 515 516 Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to 517 0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its 518 argument before returning the complement. 519 520 This macro can be useful for negating PetscDefined() inside macros e.g. 521 522 $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO)) 523 524 Example usage: 525 .vb 526 #define MY_VAR 1 527 PetscCompl(MY_VAR) -> 0 528 529 #undef MY_VAR 530 #define MY_VAR 0 531 PetscCompl(MY_VAR) -> 1 532 .ve 533 534 Level: beginner 535 536 .seealso: PetscConcat(), PetscDefined() 537 MC*/ 538 #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_,PetscExpand(b)) 539 540 #if !defined(PETSC_SKIP_VARIADIC_MACROS) 541 /*MC 542 PetscDefined - Determine whether a boolean macro is defined 543 544 Synopsis: 545 #include <petscmacros.h> 546 int PetscDefined(def) 547 548 Input Parameter: 549 . def - PETSc-style preprocessor variable (without PETSC_ prepended!) 550 551 Outut Parameter: 552 . <return-value> - Either integer literal 0 or 1 553 554 Notes: 555 Not available from Fortran, requires variadic macro support, definition is disabled by 556 defining PETSC_SKIP_VARIADIC_MACROS. 557 558 PetscDefined() returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to 559 integer literal 1. In all other cases, PetscDefined() returns integer literal 0. Therefore 560 this macro should not be used if its argument may be defined to a non-empty value other than 561 1. 562 563 The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to 564 add custom checks in user code, one should use PetscDefined_(). 565 566 $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d)) 567 568 Developer Notes: 569 Getting something that works in C and CPP for an arg that may or may not be defined is 570 tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define, 571 insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks 572 the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair, 573 and when the last step cherry picks the 2nd arg, we get a zero. 574 575 Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a 576 nonconforming implementation of variadic macros. 577 578 Example Usage: 579 Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG 580 is defined then 581 582 .vb 583 #if PetscDefined(USE_DEBUG) 584 foo(); 585 #else 586 bar(); 587 #endif 588 589 // or alternatively within normal code 590 if (PetscDefined(USE_DEBUG)) { 591 foo(); 592 } else { 593 bar(); 594 } 595 .ve 596 597 is equivalent to 598 599 .vb 600 #if defined(PETSC_USE_DEBUG) 601 # if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro 602 foo(); 603 # elif PETSC_USE_DEBUG == 1 604 foo(); 605 # else 606 bar(); 607 # endif 608 #else 609 bar(); 610 #endif 611 .ve 612 613 Level: intermediate 614 615 .seealso: PetscHasAttribute(), PetscUnlikely(), PetscLikely(), PetscConcat(), 616 PetscExpandToNothing(), PetscCompl() 617 MC*/ 618 #define PetscDefined_arg_1 shift, 619 #define PetscDefined_arg_ shift, 620 #define PetscDefined__take_second_expanded(ignored, val, ...) val 621 #define PetscDefined__take_second_expand(args) PetscDefined__take_second_expanded args 622 #define PetscDefined__take_second(...) PetscDefined__take_second_expand((__VA_ARGS__)) 623 #define PetscDefined__(arg1_or_junk) PetscDefined__take_second(arg1_or_junk 1, 0, at_) 624 #define PetscDefined_(value) PetscDefined__(PetscConcat_(PetscDefined_arg_,value)) 625 #define PetscDefined(def) PetscDefined_(PetscConcat(PETSC_,def)) 626 627 /*MC 628 PetscUnlikelyDebug - Hints the compiler that the given condition is usually FALSE, eliding 629 the check in optimized mode 630 631 Synopsis: 632 #include <petscmacros.h> 633 bool PetscUnlikelyDebug(bool cond) 634 635 Not Collective 636 637 Input Parameters: 638 . cond - Boolean expression 639 640 Notes: 641 Not available from Fortran, requires variadic macro support, definition is disabled by 642 defining PETSC_SKIP_VARIADIC_MACROS. 643 644 This returns the same truth value, it is only a hint to compilers that the result of cond is 645 likely to be false. When PETSc is compiled in optimized mode this will always return 646 false. Additionally, cond is guaranteed to not be evaluated when PETSc is compiled in 647 optimized mode. 648 649 Example usage: 650 This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG) 651 is true. So 652 653 .vb 654 if (PetscUnlikelyDebug(cond)) { 655 foo(); 656 } else { 657 bar(); 658 } 659 .ve 660 661 is equivalent to 662 663 .vb 664 if (PetscDefined(USE_DEBUG)) { 665 if (PetscUnlikely(cond)) { 666 foo(); 667 } else { 668 bar(); 669 } 670 } else { 671 bar(); 672 } 673 .ve 674 675 Level: advanced 676 677 .seealso: PetscUnlikely(), PetscLikely(), CHKERRQ, SETERRQ 678 M*/ 679 #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond)) 680 681 /*MC 682 PetscExpandToNothing - Expands to absolutely nothing at all 683 684 Synopsis: 685 #include <petscmacros.h> 686 void PetscExpandToNothing(...) 687 688 Input Parameter: 689 . __VA_ARGS__ - Anything at all 690 691 Notes: 692 Not available from Fortran, requires variadic macro support, definition is disabled by 693 defining PETSC_SKIP_VARIADIC_MACROS. 694 695 Must have at least 1 parameter. 696 697 Example usage: 698 .vb 699 PetscExpandToNothing(a,b,c) -> *nothing* 700 .ve 701 702 Level: beginner 703 704 .seealso: PetscConcat(), PetscDefined(), PetscStringize(), PetscExpand() 705 MC*/ 706 #define PetscExpandToNothing(...) 707 #endif /* !PETSC_SKIP_VARIADIC_MACROS */ 708 709 #endif /* PETSC_PREPROCESSOR_MACROS_H */ 710