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 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 /*MC 286 PetscUnlikely - Hints the compiler that the given condition is usually FALSE 287 288 Synopsis: 289 #include <petscmacros.h> 290 bool PetscUnlikely(bool cond) 291 292 Not Collective 293 294 Input Parameter: 295 . cond - Boolean expression 296 297 Notes: 298 Not available from fortran. 299 300 This returns the same truth value, it is only a hint to compilers that the result of cond is 301 unlikely to be true. 302 303 Example usage: 304 .vb 305 if (PetscUnlikely(cond)) { 306 foo(); // cold path 307 } else { 308 bar(); // hot path 309 } 310 .ve 311 312 Level: advanced 313 314 .seealso: PetscLikely(), PetscUnlikelyDebug(), CHKERRQ, PetscDefined(), PetscHasAttribute() 315 M*/ 316 317 /*MC 318 PetscLikely - Hints the compiler that the given condition is usually TRUE 319 320 Synopsis: 321 #include <petscmacros.h> 322 bool PetscLikely(bool cond) 323 324 Not Collective 325 326 Input Parameter: 327 . cond - Boolean expression 328 329 Notes: 330 Not available from fortran. 331 332 This returns the same truth value, it is only a hint to compilers that the result of cond is 333 likely to be true. 334 335 Example usage: 336 .vb 337 if (PetscLikely(cond)) { 338 foo(); // hot path 339 } else { 340 bar(); // cold path 341 } 342 .ve 343 344 Level: advanced 345 346 .seealso: PetscUnlikely(), PetscDefined(), PetscHasAttribute() 347 M*/ 348 #if defined(PETSC_HAVE_BUILTIN_EXPECT) 349 # define PetscUnlikely(cond) __builtin_expect(!!(cond),0) 350 # define PetscLikely(cond) __builtin_expect(!!(cond),1) 351 #else 352 # define PetscUnlikely(cond) (cond) 353 # define PetscLikely(cond) (cond) 354 #endif 355 356 /*MC 357 PetscUnreachable() - Indicate to the compiler that a code-path is logically unreachable 358 359 Synopsis: 360 #include <petscmacros.h> 361 void PetscUnreachable(void) 362 363 Notes: 364 Indicates to the compiler (usually via some built-in) that a particular code path is always 365 unreachable. Behavior is undefined if this function is ever executed, the user can expect an 366 unceremonious crash. 367 368 Example usage: 369 Useful in situations such as switches over enums where not all enumeration values are 370 explicitly covered by the switch 371 372 .vb 373 typedef enum {RED, GREEN, BLUE} Color; 374 375 int foo(Color c) 376 { 377 // it is known to programmer (or checked previously) that c is either RED or GREEN 378 // but compiler may not be able to deduce this and/or emit spurious warnings 379 switch (c) { 380 case RED: 381 return bar(); 382 case GREEN: 383 return baz(); 384 default: 385 PetscUnreachable(); // program is ill-formed if executed 386 } 387 } 388 .ve 389 390 Level: advanced 391 392 .seealso: SETERRABORT(), PETSCABORT() 393 MC*/ 394 #if defined(__GNUC__) 395 /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */ 396 # define PetscUnreachable() __builtin_unreachable() 397 #elif defined(_MSC_VER) /* MSVC */ 398 # define PetscUnreachable() __assume(0) 399 #else /* ??? */ 400 # define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Code path explicitly marked as unreachable executed") 401 #endif 402 403 /*MC 404 PetscExpand - Expand macro argument 405 406 Synopsis: 407 #include <petscmacros.h> 408 <macro-expansion> PetscExpand(x) 409 410 Input Paramter: 411 . x - The preprocessor token to expand 412 413 .seealso: PetscStringize(), PetscConcat() 414 MC*/ 415 #define PetscExpand_(...) __VA_ARGS__ 416 #define PetscExpand(...) PetscExpand_(__VA_ARGS__) 417 418 /*MC 419 PetscStringize - Stringize a token 420 421 Synopsis: 422 #include <petscmacros.h> 423 const char* PetscStringize(x) 424 425 Input Parameter: 426 . x - The token you would like to stringize 427 428 Output Parameter: 429 . <return-value> - The string representation of x 430 431 Notes: 432 Not available from Fortran. 433 434 PetscStringize() expands x before stringizing it, if you do not wish to do so, use 435 PetscStringize_() instead. 436 437 Example Usage: 438 .vb 439 #define MY_OTHER_VAR hello there 440 #define MY_VAR MY_OTHER_VAR 441 442 PetscStringize(MY_VAR) -> "hello there" 443 PetscStringize_(MY_VAR) -> "MY_VAR" 444 445 int foo; 446 PetscStringize(foo) -> "foo" 447 PetscStringize_(foo) -> "foo" 448 .ve 449 450 Level: beginner 451 452 .seealso: PetscConcat(), PetscExpandToNothing(), PetscExpand() 453 MC*/ 454 #define PetscStringize_(x) #x 455 #define PetscStringize(x) PetscStringize_(x) 456 457 /*MC 458 PetscConcat - Concatenate two tokens 459 460 Synopsis: 461 #include <petscmacros.h> 462 <macro-expansion> PetscConcat(x, y) 463 464 Input Parameters: 465 + x - First token 466 - y - Second token 467 468 Notes: 469 Not available from Fortran. 470 471 PetscConcat() will expand both arguments before pasting them together, use PetscConcat_() 472 if you don't want to expand them. 473 474 Example usage: 475 .vb 476 PetscConcat(hello,there) -> hellothere 477 478 #define HELLO hello 479 PetscConcat(HELLO,there) -> hellothere 480 PetscConcat_(HELLO,there) -> HELLOthere 481 .ve 482 483 Level: beginner 484 485 .seealso: PetscStringize(), PetscExpand() 486 MC*/ 487 #define PetscConcat_(x,y) x ## y 488 #define PetscConcat(x,y) PetscConcat_(x,y) 489 490 #define PETSC_INTERNAL_COMPL_0 1 491 #define PETSC_INTERNAL_COMPL_1 0 492 493 /*MC 494 PetscCompl - Expands to the integer complement of its argument 495 496 Synopsis: 497 #include <petscmacros.h> 498 int PetscCompl(b) 499 500 Input Parameter: 501 . b - Preprocessor variable, must expand to either integer literal 0 or 1 502 503 Output Paramter: 504 . <return-value> - Either integer literal 0 or 1 505 506 Notes: 507 Not available from Fortran. 508 509 Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to 510 0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its 511 argument before returning the complement. 512 513 This macro can be useful for negating PetscDefined() inside macros e.g. 514 515 $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO)) 516 517 Example usage: 518 .vb 519 #define MY_VAR 1 520 PetscCompl(MY_VAR) -> 0 521 522 #undef MY_VAR 523 #define MY_VAR 0 524 PetscCompl(MY_VAR) -> 1 525 .ve 526 527 Level: beginner 528 529 .seealso: PetscConcat(), PetscDefined() 530 MC*/ 531 #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_,PetscExpand(b)) 532 533 #if !defined(PETSC_SKIP_VARIADIC_MACROS) 534 /*MC 535 PetscDefined - Determine whether a boolean macro is defined 536 537 Synopsis: 538 #include <petscmacros.h> 539 int PetscDefined(def) 540 541 Input Parameter: 542 . def - PETSc-style preprocessor variable (without PETSC_ prepended!) 543 544 Outut Parameter: 545 . <return-value> - Either integer literal 0 or 1 546 547 Notes: 548 Not available from Fortran, requires variadic macro support, definition is disabled by 549 defining PETSC_SKIP_VARIADIC_MACROS. 550 551 PetscDefined() returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to 552 integer literal 1. In all other cases, PetscDefined() returns integer literal 0. Therefore 553 this macro should not be used if its argument may be defined to a non-empty value other than 554 1. 555 556 The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to 557 add custom checks in user code, one should use PetscDefined_(). 558 559 $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_,d)) 560 561 Developer Notes: 562 Getting something that works in C and CPP for an arg that may or may not be defined is 563 tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define, 564 insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks 565 the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair, 566 and when the last step cherry picks the 2nd arg, we get a zero. 567 568 Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a 569 nonconforming implementation of variadic macros. 570 571 Example Usage: 572 Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG 573 is defined then 574 575 .vb 576 #if PetscDefined(USE_DEBUG) 577 foo(); 578 #else 579 bar(); 580 #endif 581 582 // or alternatively within normal code 583 if (PetscDefined(USE_DEBUG)) { 584 foo(); 585 } else { 586 bar(); 587 } 588 .ve 589 590 is equivalent to 591 592 .vb 593 #if defined(PETSC_USE_DEBUG) 594 # if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro 595 foo(); 596 # elif PETSC_USE_DEBUG == 1 597 foo(); 598 # else 599 bar(); 600 # endif 601 #else 602 bar(); 603 #endif 604 .ve 605 606 Level: intermediate 607 608 .seealso: PetscHasAttribute(), PetscUnlikely(), PetscLikely(), PetscConcat(), 609 PetscExpandToNothing(), PetscCompl() 610 MC*/ 611 #define PetscDefined_arg_1 shift, 612 #define PetscDefined_arg_ shift, 613 #define PetscDefined__take_second_expanded(ignored, val, ...) val 614 #define PetscDefined__take_second_expand(args) PetscDefined__take_second_expanded args 615 #define PetscDefined__take_second(...) PetscDefined__take_second_expand((__VA_ARGS__)) 616 #define PetscDefined__(arg1_or_junk) PetscDefined__take_second(arg1_or_junk 1, 0, at_) 617 #define PetscDefined_(value) PetscDefined__(PetscConcat_(PetscDefined_arg_,value)) 618 #define PetscDefined(def) PetscDefined_(PetscConcat(PETSC_,def)) 619 620 /*MC 621 PetscUnlikelyDebug - Hints the compiler that the given condition is usually FALSE, eliding 622 the check in optimized mode 623 624 Synopsis: 625 #include <petscmacros.h> 626 bool PetscUnlikelyDebug(bool cond) 627 628 Not Collective 629 630 Input Parameters: 631 . cond - Boolean expression 632 633 Notes: 634 Not available from Fortran, requires variadic macro support, definition is disabled by 635 defining PETSC_SKIP_VARIADIC_MACROS. 636 637 This returns the same truth value, it is only a hint to compilers that the result of cond is 638 likely to be false. When PETSc is compiled in optimized mode this will always return 639 false. Additionally, cond is guaranteed to not be evaluated when PETSc is compiled in 640 optimized mode. 641 642 Example usage: 643 This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG) 644 is true. So 645 646 .vb 647 if (PetscUnlikelyDebug(cond)) { 648 foo(); 649 } else { 650 bar(); 651 } 652 .ve 653 654 is equivalent to 655 656 .vb 657 if (PetscDefined(USE_DEBUG)) { 658 if (PetscUnlikely(cond)) { 659 foo(); 660 } else { 661 bar(); 662 } 663 } else { 664 bar(); 665 } 666 .ve 667 668 Level: advanced 669 670 .seealso: PetscUnlikely(), PetscLikely(), CHKERRQ, SETERRQ 671 M*/ 672 #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond)) 673 674 /*MC 675 PetscExpandToNothing - Expands to absolutely nothing at all 676 677 Synopsis: 678 #include <petscmacros.h> 679 void PetscExpandToNothing(...) 680 681 Input Parameter: 682 . __VA_ARGS__ - Anything at all 683 684 Notes: 685 Not available from Fortran, requires variadic macro support, definition is disabled by 686 defining PETSC_SKIP_VARIADIC_MACROS. 687 688 Must have at least 1 parameter. 689 690 Example usage: 691 .vb 692 PetscExpandToNothing(a,b,c) -> *nothing* 693 .ve 694 695 Level: beginner 696 697 .seealso: PetscConcat(), PetscDefined(), PetscStringize(), PetscExpand() 698 MC*/ 699 #define PetscExpandToNothing(...) 700 #endif /* !PETSC_SKIP_VARIADIC_MACROS */ 701 702 #endif /* PETSC_PREPROCESSOR_MACROS_H */ 703