xref: /petsc/include/petscmacros.h (revision 98921bda46e76d7aaed9e0138c5ff9d0ce93f355)
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