summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Derek Mauro <dmauro@google.com>2023-08-28 13:30:41 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-08-28 13:32:04 -0700
commit1d83ac7128a5898d580a8a4164a78648a93ce2d4 (patch)
treefcbf255d2f5fd7823c66f4d5e874a79d0014bc05
parent197bac8574c511b1937b60ce6405462f9af678ce (diff)
Implement ABSL_ATTRIBUTE_PURE_FUNCTION and ABSL_ATTRIBUTE_CONST_FUNCTION
Pure functions have no effects except to return a value, and their return value depends only on the parameters and global variables. Functions of this kind can be subject to data flow analysis and might be eliminated. In practice, this means that repeated calls to the same function with the same arguments may be optimized away and only evaluated once. Const functions are similar to pure functions, but may not depend on global variables at all. It is an error not to use the result of a function with one of these attributes, since these functions have no other visible effects. Since some Abseil functions are tagged with these attributes, this is potentially a breaking change for code that doesn't use the result of these functions. For example, absl::Minutes() is tagged with ABSL_ATTRIBUTE_CONST_FUNCTION. If, for example, the result of absl::Minutes(n) is unused, some compilers with issue a warning or error. If this is the case, it is likely that there is a typo in the code, or the call can be removed. PiperOrigin-RevId: 560803581 Change-Id: Icd6f218be2cfb7226f8ab6b2d97cd960c0d3d72f
-rw-r--r--absl/base/attributes.h49
1 files changed, 46 insertions, 3 deletions
diff --git a/absl/base/attributes.h b/absl/base/attributes.h
index a7f279a0..61b79f45 100644
--- a/absl/base/attributes.h
+++ b/absl/base/attributes.h
@@ -747,9 +747,52 @@
#define ABSL_CONST_INIT
#endif
-// These annotations are not available yet due to fear of breaking code.
-#define ABSL_ATTRIBUTE_PURE_FUNCTION
-#define ABSL_ATTRIBUTE_CONST_FUNCTION
+// ABSL_ATTRIBUTE_PURE_FUNCTION
+//
+// ABSL_ATTRIBUTE_PURE_FUNCTION is used to annotate declarations of "pure"
+// functions. A function is pure if its return value is only a function of its
+// arguments. The pure attribute prohibits a function from modifying the state
+// of the program that is observable by means other than inspecting the
+// function's return value. Declaring such functions with the pure attribute
+// allows the compiler to avoid emitting some calls in repeated invocations of
+// the function with the same argument values.
+//
+// Example:
+//
+// ABSL_ATTRIBUTE_PURE_FUNCTION std::string FormatTime(Time t);
+#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::pure)
+#define ABSL_ATTRIBUTE_PURE_FUNCTION [[gnu::pure]]
+#elif ABSL_HAVE_ATTRIBUTE(pure)
+#define ABSL_ATTRIBUTE_PURE_FUNCTION __attribute__((pure))
+#else
+// If the attribute isn't defined, we'll fallback to ABSL_MUST_USE_RESULT since
+// pure functions are useless if its return is ignored.
+#define ABSL_ATTRIBUTE_PURE_FUNCTION ABSL_MUST_USE_RESULT
+#endif
+
+// ABSL_ATTRIBUTE_CONST_FUNCTION
+//
+// ABSL_ATTRIBUTE_CONST_FUNCTION is used to annotate declarations of "const"
+// functions. A const function is similar to a pure function, with one
+// exception: Pure functions may return value that depend on a non-volatile
+// object that isn't provided as a function argument, while the const function
+// is guaranteed to return the same result given the same arguments.
+//
+// Example:
+//
+// ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Milliseconds(Duration d);
+#if defined(_MSC_VER) && !defined(__clang__)
+// Put the MSVC case first since MSVC seems to parse const as a C++ keyword.
+#define ABSL_ATTRIBUTE_CONST_FUNCTION ABSL_ATTRIBUTE_PURE_FUNCTION
+#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::const)
+#define ABSL_ATTRIBUTE_CONST_FUNCTION [[gnu::const]]
+#elif ABSL_HAVE_ATTRIBUTE(const)
+#define ABSL_ATTRIBUTE_CONST_FUNCTION __attribute__((const))
+#else
+// Since const functions are more restrictive pure function, we'll fallback to a
+// pure function if the const attribute is not handled.
+#define ABSL_ATTRIBUTE_CONST_FUNCTION ABSL_ATTRIBUTE_PURE_FUNCTION
+#endif
// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function
// parameter or implicit object parameter is retained by the return value of the