<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Abseil Blog &amp; Tips</title>
    <description>An open-source collection of C++ library code designed to
    augment the C++ standard library</description>
    <link>https://abseil.io</link>
    
      
        <item>
          <title>Performance Tip of the Week #97: Virtuous ecosystem cycles</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #97 on August 21, 2025&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-11-27&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/97&quot;&gt;abseil.io/fast/97&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Software ecosystems aim to maximize qualities like efficiency, correctness, and
reliability while minimizing the costs of achieving these properties. Improving
a single service through customization can help build an optimization more
expediently, but it has an inherent limited scope to its upside and increases
&lt;a href=&quot;/fast/52&quot;&gt;technical debt&lt;/a&gt;. A point solution fails to provide the full benefits
from applying features horizontally. In this episode, we discuss how lessons
learned from partnerships to improve individual applications can improve
efficiency for everyone.&lt;/p&gt;

&lt;h2 id=&quot;case-studies&quot;&gt;Case studies&lt;/h2&gt;

&lt;p&gt;We look at several case studies where we could take a feature that showed
benefits for a single team and rolled it out to provide benefits for all of
Google.&lt;/p&gt;

&lt;h3 id=&quot;swissmap&quot;&gt;SwissMap&lt;/h3&gt;

&lt;p&gt;Abseil’s
&lt;a href=&quot;https://abseil.io/blog/20180927-swisstables&quot;&gt;hash table implementation&lt;/a&gt;,
SwissMap, originated out of a partnership between our C++ core libraries team
and two Zurich-based engineers, Alkis Evlogimenos and Roman Perepelitsa, on our
search indexing team. They had set out to make an improved hash table that used
open addressing for &lt;a href=&quot;/fast/83&quot;&gt;fewer data indirections&lt;/a&gt;, improved the design to
reduce memory usage, and added API features to avoid unnecessary copies. Jeff
Dean and Sanjay Ghemawat had suggested a SIMD-accelerated control block to speed
up comparison, allowing the table to efficiently run at a higher load factor.&lt;/p&gt;

&lt;p&gt;While hash tables are a key tool in a programmer’s toolbox, they tend to not
span API boundaries to nearly the same degree as other
&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2125r0.pdf&quot;&gt;vocabulary types&lt;/a&gt;
like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt;. For the indexing team’s purposes, most of
the benefits for their application could be obtained by replacing their hottest
hashtables and declaring victory.&lt;/p&gt;

&lt;p&gt;But rather than stopping, the team opted to drive widespread adoption of the
superior hashtable. Over tens of thousands of changes later, nearly every hash
table in Google’s codebase is a SwissMap. The early years of the rollout saved a
substantial amount of CPU and RAM. These savings were only unlocked because we
pursued a scaled migration.&lt;/p&gt;

&lt;p&gt;The broad rollout produced ongoing ecosystem dividends:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“Just use SwissMap” was good advice, but for an engineer trying to
&lt;a href=&quot;https://queue.acm.org/detail.cfm?id=3733703&quot;&gt;develop a new feature&lt;/a&gt;, it is
easier to use the existing types, even if SwissMap would be a better fit for
performance. The widespread usage of SwissMap made it easier for new code to
reach for it.&lt;/li&gt;
  &lt;li&gt;Drawing on lessons from prior hash table changes, &lt;a href=&quot;/fast/93&quot;&gt;randomization&lt;/a&gt;
was introduced to prevent code from relying on the order of iteration. This
made it easier to land subsequent optimizations under the hood, allowing us
to iteratively improve the hash function by changing its algorithm.&lt;/li&gt;
  &lt;li&gt;Because of our implementation freedom, we were able to add telemetry
features like &lt;a href=&quot;/fast/26&quot;&gt;built-in profiling&lt;/a&gt; that work across the fleet.
This has allowed us to find and fix bad hash functions, identify
optimizations for small tables, and proactively &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reserve&lt;/code&gt; containers to
their final sizes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;size-class-driven-allocation&quot;&gt;Size class-driven allocation&lt;/h3&gt;

&lt;p&gt;Modern memory allocators like TCMalloc use
“&lt;a href=&quot;https://github.com/google/tcmalloc/blob/master/docs/design.md#objects&quot;&gt;size classes&lt;/a&gt;”
to efficiently cache small objects. Rather than fit each allocation precisely,
the allocator determines which size class a request falls into and checks the
freelist for that size class. When an object is freed, the allocator determines
which size class the memory belongs to and puts the object on the appropriate
freelist for future reuse. This design simplifies bookkeeping and reduces the
cost of allocating and deallocating memory.&lt;/p&gt;

&lt;h4 id=&quot;sized-deallocation&quot;&gt;Sized deallocation&lt;/h4&gt;

&lt;p&gt;Using size classes requires a memory allocator to determine which freelist to
put freed objects onto. TCMalloc’s original mapping approach required
&lt;a href=&quot;/fast/83&quot;&gt;several pointer dereferences&lt;/a&gt;. In 2012, Google’s compiler
optimization team identified that the object’s size is frequently already known
outside of the allocator. Passing this size as an
&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3778.html&quot;&gt;argument to the allocator&lt;/a&gt;
avoids the expensive lookup.&lt;/p&gt;

&lt;p&gt;Once sized deallocation was implemented, several teams were able to adopt the
feature to reduce allocation costs. This optimization can exacerbate
&lt;a href=&quot;https://github.com/google/tcmalloc/blob/master/docs/mismatched-sized-delete.md#tcmalloc-is-buggy&quot;&gt;existing undefined behavior&lt;/a&gt;
or introduce bugs in the rare case of tail-padded structures, requiring would-be
adopters to clean up their code and transitive dependencies. Because of these
lurking issues, the default remained “unsized” delete.&lt;/p&gt;

&lt;p&gt;Motivated by
&lt;a href=&quot;https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/44271.pdf&quot;&gt;fleetwide profiles showing the horizontal cost of TCMalloc&lt;/a&gt;,
work began to enable sized deallocation for the entire codebase.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/fast/93&quot;&gt;Runtime assertions&lt;/a&gt; were added to TCMalloc to catch bugs in debug
builds.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#:~:text=The%20Beyonc%C3%A9%20Rule&amp;amp;text=The%20straightforward%20answer%20is%3A%20test,an%20automated%20test%20for%20it.&quot;&gt;Test failures&lt;/a&gt;
were investigated and numerous fixes submitted.&lt;/li&gt;
  &lt;li&gt;The feature was progressively rolled out to Address Sanitizer, debug, and
optimized builds, preventing backsliding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Infrastructure improvements, like the runtime assertions themselves, cost the
same to develop for one team as they do would for widespread deployment. For
other steps, like enabling sized deallocation in tests, operating centrally on
all tests was cheaper and easier to do than asking each team to set up a
parallel set of tests for themselves and their dependencies.&lt;/p&gt;

&lt;p&gt;While the project delivered on its original goal of reducing TCMalloc costs in
the fleet, the central effort strengthened the ecosystem’s reliability as a
whole by creating a sturdier foundation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;By enabling sized deallocation for all tests, teams already relying on the
optimization benefited from the prevention of new bugs in their transitive
dependencies. In the past, bugs would manifest as production crashes
requiring teams to play whack-a-mole to set up extra testing. Moving the
entire platform to sized delete foreclosed this entire class of bugs while
avoiding the cost of duplicative and ad hoc testing setups.&lt;/li&gt;
  &lt;li&gt;The added information allows TCMalloc to
&lt;a href=&quot;https://dl.acm.org/doi/10.1145/3639477.3640328&quot;&gt;occasionally double-check&lt;/a&gt;
the purported size, allowing further memory corruption bugs to be uncovered.
This was only possible because size arguments are routinely passed to
deallocations.&lt;/li&gt;
  &lt;li&gt;The centralized burndown uncovered a relatively rare, but important, pattern
of tail padded structures not working well with sized deallocation. This
spurred C++20’s
&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0722r3.html&quot;&gt;destroying delete&lt;/a&gt;
feature, which may not have been standardized and adopted universally
without a central vantage point of its value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Had we eschewed centralized adoption, individual teams would have faced similar
challenges, more bugs in production, and not benefitted from the flywheel of
follow-on improvements.&lt;/p&gt;

&lt;h4 id=&quot;size-class-improvements&quot;&gt;Size class improvements&lt;/h4&gt;

&lt;p&gt;Size classes simplify the logic required to allocate and deallocate memory, but
they introduce a new optimization problem: which sizes should we select as our
buckets? For many years, these partitions were chosen to minimize the amount of
memory lost by rounding up the request to its bucket (“internal fragmentation”)
based on fleetwide profiles.&lt;/p&gt;

&lt;p&gt;Internal fragmentation is just &lt;a href=&quot;/fast/70&quot;&gt;one metric&lt;/a&gt; we can look at when making
these choices. Merging two size classes would mean some smaller sizes grow,
increasing roundup overhead, while being offset by reducing the amount of memory
left in TCMalloc’s caches at peak demand
(“&lt;a href=&quot;https://storage.googleapis.com/gweb-research2023-media/pubtools/6213.pdf#page=4&quot;&gt;external fragmentation&lt;/a&gt;”).
Having too few size classes would put more stress on TCMalloc’s backend and
global locks.&lt;/p&gt;

&lt;p&gt;One partnership with the Search retrieval team produced a series of
optimizations. The experiments showed improved performance with two sets of size
classes, “power-of-2 below 64” and “power-of-2 only.” Rather than stop with just
that service, we opted to evaluate the impact for all workloads.&lt;/p&gt;

&lt;p&gt;The former struck a tradeoff between maximizing CPU performance while modestly
increasing RAM usage. Fleetwide A/B experimentation allowed this set to be
evaluated and rolled out to improve aggregate CPU performance, a result
comparable to the initial load tests motivating the work.&lt;/p&gt;

&lt;p&gt;Continued investigation of the “power-of-2 only” result pointed towards reducing
the amount of time an object might sit on one of TCMalloc’s caches before the
next allocation that uses it. By choosing size classes that were likely to see
high allocation rates rather than solely minimizing internal fragmentation, we
were able to further improve fleetwide CPU performance.&lt;/p&gt;

&lt;p&gt;We can contrast this with the hypothetical counterfactual where we made size
class &lt;a href=&quot;/fast/52&quot;&gt;customizability&lt;/a&gt; a full-fledged feature of TCMalloc and
individual teams tuned for their workloads.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;For the teams with the time and inclination to customize their
configuration, they might have seen even larger wins for themselves than
what they obtained because of the global rollout, but over time, these
settings might have become stale. The second round of global optimizations
underscores the risk that individual teams might have stopped at a
suboptimal point.&lt;/li&gt;
  &lt;li&gt;More configurations make it harder to maintain TCMalloc, and hamper
&lt;a href=&quot;/fast/52&quot;&gt;implementation freedom&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;The tightly controlled configuration space made it possible to land
improvements centrally, without having to navigate the existing
customizations or risks from &lt;a href=&quot;https://hyrumslaw.com&quot;&gt;breaking&lt;/a&gt;
&lt;a href=&quot;https://xkcd.com/1172/&quot;&gt;someone’s use case&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;turbo-troubles&quot;&gt;Turbo troubles&lt;/h3&gt;

&lt;p&gt;Early work to use AVX instructions in general purpose workloads faced the
headwind of downclocking on the first AVX-capable platforms. In a math-intensive
workload, a modest frequency reduction would be a tolerable tradeoff for a
doubling in floating point throughput. In other workloads, the compiler’s
occasional use of them in mostly scalar code produced performance regressions,
not wins, which deterred adoption.&lt;/p&gt;

&lt;p&gt;Changing the compiler to constrain autovectorization broke the logjam. It was
possible to make this change because:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Most math-intensive code already used intrinsics to ensure high-quality
vectorization, rather than relying on autovectorization. This was unaffected
by the compiler change.&lt;/li&gt;
  &lt;li&gt;Scalar code could unlock and leverage new instruction sets like
&lt;a href=&quot;/fast/39&quot;&gt;BMI2&lt;/a&gt; from subsequent microarchitectures.&lt;/li&gt;
  &lt;li&gt;In places where mostly scalar code could be vectorized somewhat, the
compiler was constrained from introducing heavyweight vector instructions
that introduced downclocking.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Being able to leverage the performance benefits of these new instructions
without downsides spurred broader adoption, creating a flywheel for further
horizontally and vertically-driven optimizations to be built on top of it.&lt;/p&gt;

&lt;h2 id=&quot;lessons&quot;&gt;Lessons&lt;/h2&gt;

&lt;h3 id=&quot;dont-assume-the-status-quo-is-fixed&quot;&gt;Don’t assume the status quo is fixed&lt;/h3&gt;

&lt;p&gt;Teams working on a single application sometimes treat the underlying ecosystem
and platform as immutable, and solve problems within that constraint. The
platform itself is rarely immutable if there’s sufficient value to be gained
from an ecosystem-wide change.&lt;/p&gt;

&lt;p&gt;Even if it makes sense to work around a problem for reasons of expediency,
surfacing these pain points can raise awareness of frequently encountered pain
points. A frequent problem might look rare if everyone works around it rather
than seeing it get fixed in the platform once and for all.&lt;/p&gt;

&lt;h3 id=&quot;focus-on-problems-and-outcomes-not-exact-solutions&quot;&gt;Focus on problems and outcomes, not exact solutions&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;/fast/72&quot;&gt;Prototypes&lt;/a&gt; are an invaluable resource for assessing how to solve a
problem and determining what strategies actually work. It can help to step back
to think about requirements and &lt;a href=&quot;/fast/70&quot;&gt;desired outcomes&lt;/a&gt;. We can say “yes,
this is an important problem worth solving,” while simultaneously saying “but in
a different way.”&lt;/p&gt;

&lt;p&gt;When charting a path for scaled adoption of a prototype, we might want to use a
different implementation strategy to target a broader addressable market, take
advantage of existing use cases, or avoid long-term technical debt. Rarely is
“deploy exactly this prototype” the outcome we care about, so flexibility
towards solving the problem in different ways can let us grow our impact.&lt;/p&gt;

&lt;h3 id=&quot;create-and-use-leverage&quot;&gt;Create and use leverage&lt;/h3&gt;

&lt;p&gt;As we take vertically-inspired solutions and deploy them horizontally, we are
often looking for leverage. If there is already a broadly used library or
feature that we can improve, we get a larger benefit than if we created an
entirely new thing that needed adoption. Rather than workaround a problem, we
should see if we can push changes further down the stack to fix issues more
generally and for everyone.&lt;/p&gt;

&lt;p&gt;At other times, we might need to create a lever for ourselves. As seen with
SwissMap and AVX, driving adoption helped us to bootstrap. It created usage
where there was none previously, and then used that lever to motivate further
centralized optimizations.&lt;/p&gt;

&lt;h3 id=&quot;understand-what-is-seen-and-unseen&quot;&gt;Understand what is seen and unseen&lt;/h3&gt;

&lt;p&gt;Opinionated libraries that might offer relatively few configuration options may
appear to be an impediment to optimization, but it is easy to miss the
opportunity costs of catering too much to specific use cases or flexibility. The
costs of the former tend to be &lt;a href=&quot;/fast/74&quot;&gt;visible&lt;/a&gt;, while the latter is not.&lt;/p&gt;

&lt;p&gt;A healthier, more sustainable core library can deliver other optimizations that
help our service of interest. For example, we can see the costs of SwissMap’s
per-instance &lt;a href=&quot;/fast/93&quot;&gt;randomization&lt;/a&gt; when copying.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The direct savings are clear: Removing this randomization would help improve
performance for copying-intensive users.&lt;/li&gt;
  &lt;li&gt;The indirect costs are less so: Loss of randomization would make it harder
to add optimizations to common operations like lookup and insertion. This
would hurt the broad ecosystem, likely including copy-intensive users as
well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing words&lt;/h2&gt;

&lt;p&gt;Deep work with individual workloads can produce novel optimization insights.
Finding ways to scale these to the broader ecosystem can increase our impact,
both by removing bottlenecks for that workload and by addressing the problem
systematically.&lt;/p&gt;
</description>
          <pubDate>2025-11-27T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/97</link>
          <guid isPermaLink="true">https://abseil.io/fast/97</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #99: Illuminating the processor core with llvm-mca</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #99 on September 29, 2025&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-10-07&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/99&quot;&gt;abseil.io/fast/99&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/Reduced_instruction_set_computer&quot;&gt;RISC&lt;/a&gt;
versus &lt;a href=&quot;https://en.wikipedia.org/wiki/Complex_instruction_set_computer&quot;&gt;CISC&lt;/a&gt;
debate ended in a draw: Modern processors decompose instructions into
&lt;a href=&quot;https://en.wikipedia.org/wiki/Micro-operation&quot;&gt;micro-ops&lt;/a&gt; handled by backend
execution units. Understanding how instructions are executed by these units can
give us insights on optimizing key functions that are backend bound. In this
episode, we walk through using
&lt;a href=&quot;https://llvm.org/docs/CommandGuide/llvm-mca.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt;&lt;/a&gt; to analyze
functions and identify performance insights from its simulation.&lt;/p&gt;

&lt;h2 id=&quot;preliminaries-varint-optimization&quot;&gt;Preliminaries: Varint optimization&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt;, short for Machine Code Analyzer, is a tool within LLVM. It uses the
same datasets that the compiler uses for making instruction scheduling
decisions. This ensures that improvements made to compiler optimizations
automatically flow towards keeping &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; representative. The flip side is
that the tool is only as good as LLVM’s internal modeling of processor designs,
so certain quirks of individual microarchitecture generations might be omitted.
It also models the processor &lt;a href=&quot;#limitations&quot;&gt;behavior statically&lt;/a&gt;, so cache
misses, branch mispredictions, and other dynamic properties aren’t considered.&lt;/p&gt;

&lt;p&gt;Consider Protobuf’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VarintSize64&lt;/code&gt; method:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
size_t CodedOutputStream::VarintSize64(uint64_t value) {
#if PROTOBUF_CODED_STREAM_H_PREFER_BSR
  // Explicit OR 0x1 to avoid calling absl::countl_zero(0), which
  // requires a branch to check for on platforms without a clz instruction.
  uint32_t log2value = (std::numeric_limits&amp;lt;uint64_t&amp;gt;::digits - 1) -
                       absl::countl_zero(value | 0x1);
  return static_cast&amp;lt;size_t&amp;gt;((log2value * 9 + (64 + 9)) / 64);
#else
  uint32_t clz = absl::countl_zero(value);
  return static_cast&amp;lt;size_t&amp;gt;(
      ((std::numeric_limits&amp;lt;uint64_t&amp;gt;::digits * 9 + 64) - (clz * 9)) / 64);
#endif
}
&lt;/pre&gt;

&lt;p&gt;This function calculates how many bytes an encoded integer will consume in
&lt;a href=&quot;https://protobuf.dev/programming-guides/encoding/#varints&quot;&gt;Protobuf’s wire
format&lt;/a&gt;. It first
computes the number of bits needed to represent the value by finding the log2
size of the input, then approximates division by 7. The size of the input can be
calculated using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::countl_zero&lt;/code&gt; function. However this has two possible
implementations depending on whether the processor has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; (Leading Zero
Count) instruction available or if this operation needs to instead leverage the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bsr&lt;/code&gt; (Bit Scan Reverse) instruction.&lt;/p&gt;

&lt;p&gt;Under the hood of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::countl_zero&lt;/code&gt;, we need to check whether the argument is
zero, since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__builtin_clz&lt;/code&gt; (Count Leading Zeros) models the behavior of x86’s
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bsr&lt;/code&gt; (Bit Scan Reverse) instruction and has unspecified behavior if the input
is 0. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;| 0x1&lt;/code&gt; avoids needing a branch by ensuring the argument is non-zero
in a way the compiler can follow.&lt;/p&gt;

&lt;p&gt;When we have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; available, the compiler optimizes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x == 0 ? 32 :
__builtin_clz(x)&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::countl_zero&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; without branches. This makes
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;| 0x1&lt;/code&gt; unnecessary.&lt;/p&gt;

&lt;p&gt;Compiling this gives us two different assembly sequences depending on whether
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; instruction is available or not:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bsr&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-march=ivybridge&lt;/code&gt;):&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
orq     $1, %rdi
bsrq    %rdi, %rax
leal    (%rax,%rax,8), %eax
addl    $73, %eax
shrl    $6, %eax
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-march=haswell&lt;/code&gt;):&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
lzcntq  %rdi, %rax
leal    (%rax,%rax,8), %ecx
movl    $640, %eax
subl    %ecx, %eax
shrl    $6, %eax
&lt;/pre&gt;

&lt;h3 id=&quot;analyzing-the-code&quot;&gt;Analyzing the code&lt;/h3&gt;

&lt;p&gt;We can now use &lt;a href=&quot;https://godbolt.org/z/39EMsWq7z&quot;&gt;Compiler Explorer&lt;/a&gt; to run these
sequences through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; and get an analysis of how they would execute on a
simulated Skylake processor (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-mcpu=skylake&lt;/code&gt;) for a single invocation
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-iterations=1&lt;/code&gt;) and include &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-timeline&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bsr&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-march=ivybridge&lt;/code&gt;):&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
Iterations:        1
Instructions:      5
Total Cycles:      10
Total uOps:        5

Dispatch Width:    6
uOps Per Cycle:    0.50
IPC:               0.50
Block RThroughput: 1.0

Timeline view:
Index     0123456789

[0,0]     DeER .   .   orq      $1, %rdi
[0,1]     D=eeeER  .   bsrq     %rdi, %rax
[0,2]     D====eER .   leal     (%rax,%rax,8), %eax
[0,3]     D=====eER.   addl     $73, %eax
[0,4]     D======eER   shrl     $6, %eax
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-march=haswell&lt;/code&gt;):&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
Iterations:        1
Instructions:      5
Total Cycles:      9
Total uOps:        5

Dispatch Width:    6
uOps Per Cycle:    0.56
IPC:               0.56
Block RThroughput: 1.0

Timeline view:
Index     012345678

[0,0]     DeeeER  .   lzcntq    %rdi, %rax
[0,1]     D===eER .   leal      (%rax,%rax,8), %ecx
[0,2]     DeE---R .   movl      $640, %eax
[0,3]     D====eER.   subl      %ecx, %eax
[0,4]     D=====eER   shrl      $6, %eax
&lt;/pre&gt;

&lt;p&gt;This can also be obtained via the command line&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ clang file.cpp -O3 --target=x86_64 -S -o - | llvm-mca -mcpu=skylake -iterations=1 -timeline
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s two sections to this output, the first section provides some summary
statistics for the code, the second section covers the execution “timeline.” The
timeline provides interesting detail about how instructions flow through the
execution pipelines in the processor. There are three columns, and each
instruction is shown on a separate row. The three columns are as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The first column is a pair of numbers, the first number is the iteration,
the second number is the index of the instruction. In the above example
there’s a single iteration, number 0, so just the index of the instruction
changes on each row.&lt;/li&gt;
  &lt;li&gt;The third column is the instruction.&lt;/li&gt;
  &lt;li&gt;The second column is the timeline. Each character in that column represents
a cycle, and the character indicates what’s happening to the instruction in
that cycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The timeline is counted in cycles. Each instruction goes through several steps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; the instruction is dispatched by the processor; modern desktop or server
processors can dispatch many instructions per cycle. Little Arm cores like
the Cortex-A55 used in smartphones are more limited.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&lt;/code&gt; the instruction is waiting to execute. In this case, the instructions
are waiting for the results of prior instructions to be available. In other
cases, there might be a bottleneck in the processor’s backend.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt; the instruction is executing.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;E&lt;/code&gt; the instruction’s output is available.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-&lt;/code&gt; the instruction has completed execution and is waiting to be retired.
Instructions generally retire in program order, the order instructions
appear in the program. An instruction will wait to retire until prior ones
have also retired. On some architectures like the Cortex-A55, there is no
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R&lt;/code&gt; phase in the timeline as some instructions &lt;a href=&quot;https://chipsandcheese.com/i/149874023/out-of-order-retire&quot;&gt;retire
out-of-order&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R&lt;/code&gt; the instruction has been retired, and is no longer occupying execution
resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output is lengthy, but we can extract a few high-level insights from it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; implementation is quicker to execute (9 cycles) than the “bsr”
implementation (10 cycles). This is seen under the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Total Cycles&lt;/code&gt; summary as
well as the timeline.&lt;/li&gt;
  &lt;li&gt;The routine is simple: with the exception of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;movl&lt;/code&gt;, the instructions depend
on each other sequentially (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;E&lt;/code&gt;-finishing to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt;-starting vertically
aligning, pairwise, in the timeline view).&lt;/li&gt;
  &lt;li&gt;Bitwise-&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;or&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x1&lt;/code&gt; delays &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bsrq&lt;/code&gt;’s input being available by 1 cycle,
contributing to the longer execution cost.&lt;/li&gt;
  &lt;li&gt;Note that although &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;movl&lt;/code&gt; starts immediately in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; implementation,
it can’t retire until prior instructions are retired, since we retire in
program order.&lt;/li&gt;
  &lt;li&gt;Both sequences are 5 instructions long, but the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; implementation has
higher &lt;a href=&quot;https://en.wikipedia.org/wiki/Instruction-level_parallelism&quot;&gt;instruction-level parallelism
(ILP)&lt;/a&gt; because
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mov&lt;/code&gt; has no dependencies. This demonstrates that counting instructions
need not tell us the &lt;a href=&quot;/fast/7&quot;&gt;cycle cost&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; is flexible and can model other processors:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AMD Zen3 (&lt;a href=&quot;https://godbolt.org/z/xbq9PqG8z&quot;&gt;Compiler Explorer&lt;/a&gt;), where the
cost difference is more stark (8 cycles versus 12 cycles).&lt;/li&gt;
  &lt;li&gt;Arm Neoverse-V2 (&lt;a href=&quot;https://godbolt.org/z/sE3T65n8M&quot;&gt;Compiler Explorer&lt;/a&gt;), a
server CPU where the difference is 7 vs 9 cycles.&lt;/li&gt;
  &lt;li&gt;Arm Cortex-A55 (&lt;a href=&quot;https://godbolt.org/z/vPP5EPrcW&quot;&gt;Compiler Explorer&lt;/a&gt;), a
popular little core used in smartphones, where the difference is 8 vs 10
cycles. Note how the much smaller dispatch width results in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; phase of
instructions starting later.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;throughput-versus-latency&quot;&gt;Throughput versus latency&lt;/h3&gt;

&lt;p&gt;When designing &lt;a href=&quot;/fast/75&quot;&gt;microbenchmarks&lt;/a&gt;, we sometimes want to distinguish
between throughput and latency microbenchmarks. If the input of one benchmark
iteration does not depend on the prior iteration, the processor can execute
multiple iterations in parallel. Generally for code that is expected to execute
in a loop we care more about throughput, and for code that is inlined in many
places interspersed with other logic we care more about latency.&lt;/p&gt;

&lt;p&gt;We can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; to model execution of the block of code in a tight loop.
By specifying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-iterations=100&lt;/code&gt; on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lzcnt&lt;/code&gt; version, we get a very different
set of results because one iteration’s execution can overlap with the next:&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
Iterations:        100
Instructions:      500
Total Cycles:      134
Total uOps:        500

Dispatch Width:    6
uOps Per Cycle:    3.73
IPC:               3.73
Block RThroughput: 1.0
&lt;/pre&gt;

&lt;p&gt;We were able to execute 100 iterations in only 134 cycles (1.34 cycles/element)
by achieving high ILP.&lt;/p&gt;

&lt;p&gt;Achieving the best performance may sometimes entail trading off the latency of a
basic block in favor of higher throughput. Inside of the protobuf implementation
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VarintSize&lt;/code&gt;
(&lt;a href=&quot;https://github.com/protocolbuffers/protobuf/tree/main/src/google/protobuf/wire_format_lite.cc&quot;&gt;protobuf/wire_format_lite.cc&lt;/a&gt;),
we use a vectorized version for realizing higher throughput albeit with worse
latency. A single iteration of the loop takes 29 cycles to process 32 elements
(&lt;a href=&quot;https://godbolt.org/z/TczKTaGd8&quot;&gt;Compiler Explorer&lt;/a&gt;) for 0.91 cycles/element,
but 100 iterations (3200 elements) only requires 1217 cycles (0.38
cycles/element - about 3x faster) showcasing the high throughput once setup
costs are amortized.&lt;/p&gt;

&lt;h2 id=&quot;understanding-dependency-chains&quot;&gt;Understanding dependency chains&lt;/h2&gt;

&lt;p&gt;When we are looking at CPU profiles, we are often tracking when instructions
&lt;em&gt;retire&lt;/em&gt;. Costs are attributed to instructions that took longer to retire.
Suppose we profile a small function that accesses memory pseudo-randomly:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
unsigned Chains(unsigned* x) {
   unsigned a0 = x[0];
   unsigned b0 = x[1];

   unsigned a1 = x[a0];
   unsigned b1 = x[b0];

   unsigned b2 = x[b1];

   return a1 | b2;
}
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; models memory loads being an L1 hit (&lt;a href=&quot;https://godbolt.org/z/6PzTPYv8T&quot;&gt;Compiler
Explorer&lt;/a&gt;): It takes 5 cycles for the value of
a load to be available after the load starts execution. The output has been
annotated with the source code to make it easier to read.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
Iterations:        1
Instructions:      6
Total Cycles:      19
Total uOps:        9

Dispatch Width:    6
uOps Per Cycle:    0.47
IPC:               0.32
Block RThroughput: 3.0

Timeline view:
                    012345678
Index     0123456789


[0,0]     DeeeeeER  .    .  .   movl    (%rdi), %ecx         // ecx = a0 = x[0]
[0,1]     DeeeeeER  .    .  .   movl    4(%rdi), %eax        // eax = b0 = x[1]
[0,2]     D=====eeeeeER  .  .   movl    (%rdi,%rax,4), %eax  // eax = b1 = x[b0]
[0,3]     D==========eeeeeER.   movl    (%rdi,%rax,4), %eax  // eax = b2 = x[b1]
[0,4]     D==========eeeeeeER   orl     (%rdi,%rcx,4), %eax  // eax |= a1 = x[a0]
[0,5]     .DeeeeeeeE--------R   retq
&lt;/pre&gt;

&lt;p&gt;In this timeline the first two instructions load &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a0&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b0&lt;/code&gt;. Both of these
operations can happen immediately. However, the load of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x[b0]&lt;/code&gt; can only happen
once the value for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b0&lt;/code&gt; is available in a register - after a 5 cycle delay. The
load of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x[b1]&lt;/code&gt; can only happen once the value for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b1&lt;/code&gt; is available after
another 5 cycle delay.&lt;/p&gt;

&lt;p&gt;This program has two places where we can execute loads in parallel: the pair
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a0&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b0&lt;/code&gt; and the pair &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a1 and b1&lt;/code&gt; (note: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; does not correctly
model the memory load uop from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orl&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a1&lt;/code&gt; starting). Since the processor
retires instructions in program order we expect the profile weight to appear on
the loads for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a0&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b1&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b2&lt;/code&gt;, even though we had parallel loads in-flight
simultaneously.&lt;/p&gt;

&lt;p&gt;If we examine this profile, we might try to optimize one of the memory
indirections because it appears in our profile. We might do this by miraculously
replacing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a0&lt;/code&gt; with a constant (&lt;a href=&quot;https://godbolt.org/z/b68KzsKMP&quot;&gt;Compiler
Explorer&lt;/a&gt;).&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
unsigned Chains(unsigned* x) {
   unsigned a0 = 0;
   unsigned b0 = x[1];

   unsigned a1 = x[a0];
   unsigned b1 = x[b0];

   unsigned b2 = x[b1];

   return a1 | b2;
}
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
Iterations:        1
Instructions:      5
Total Cycles:      19
Total uOps:        8

Dispatch Width:    6
uOps Per Cycle:    0.42
IPC:               0.26
Block RThroughput: 2.5

Timeline view:
                    012345678
Index     0123456789

[0,0]     DeeeeeER  .    .  .   movl    4(%rdi), %eax
[0,1]     D=====eeeeeER  .  .   movl    (%rdi,%rax,4), %eax
[0,2]     D==========eeeeeER.   movl    (%rdi,%rax,4), %eax
[0,3]     D==========eeeeeeER   orl     (%rdi), %eax
[0,4]     .DeeeeeeeE--------R   retq
&lt;/pre&gt;

&lt;p&gt;Even though we got rid of the “expensive” load we saw in the CPU profile, we
didn’t actually change the overall length of the critical path that was
dominated by the 3 load long “b” chain. The timeline view shows the critical
path for the function, and performance can only be improved if the duration of
the critical path is reduced.&lt;/p&gt;

&lt;h2 id=&quot;optimizing-crc32c&quot;&gt;Optimizing CRC32C&lt;/h2&gt;

&lt;p&gt;CRC32C is a common hashing function and modern architectures include dedicated
instructions for calculating it. On short sizes, we’re largely dealing with
handling odd numbers of bytes. For large sizes, we are constrained by repeatedly
invoking &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32q&lt;/code&gt; (x86) or similar every few bytes of the input. By examining
the repeated invocation, we can look at how the processor will execute it
(&lt;a href=&quot;https://godbolt.org/z/nEYsWWzWs&quot;&gt;Compiler Explorer&lt;/a&gt;):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
uint32_t BlockHash() {
 asm volatile(&quot;# LLVM-MCA-BEGIN&quot;);
 uint32_t crc = 0;
 for (int i = 0; i &amp;lt; 16; ++i) {
   crc = _mm_crc32_u64(crc, i);
 }
 asm volatile(&quot;# LLVM-MCA-END&quot; : &quot;+r&quot;(crc));
 return crc;
}
&lt;/pre&gt;

&lt;p&gt;This function doesn’t hash anything useful, but it allows us to see the
back-to-back usage of one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32q&lt;/code&gt;’s output with the next &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32q&lt;/code&gt;’s inputs.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
Iterations:        1
Instructions:      32
Total Cycles:      51
Total uOps:        32

Dispatch Width:    6
uOps Per Cycle:    0.63
IPC:               0.63
Block RThroughput: 16.0

Instruction Info:

[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      0     0.17                        xorl   %eax, %eax
1      3     1.00                        crc32q %rax, %rax
1      1     0.25                        movl   $1, %ecx
1      3     1.00                        crc32q %rcx, %rax
...

Resources:
[0]   - SKLDivider
[1]   - SKLFPDivider
[2]   - SKLPort0
[3]   - SKLPort1
[4]   - SKLPort2
[5]   - SKLPort3
[6]   - SKLPort4
[7]   - SKLPort5
[8]   - SKLPort6
[9]   - SKLPort7


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6]    [7]    [8]    [9]
-      -     4.00   18.00   -     1.00    -     5.00   6.00    -

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6]    [7]    [8]    [9]    Instructions:
-      -      -      -      -      -      -      -      -      -     xorl       %eax, %eax
-      -      -     1.00    -      -      -      -      -      -     crc32q     %rax, %rax
-      -      -      -      -      -      -      -     1.00    -     movl       $1, %ecx
-      -      -     1.00    -      -      -      -      -      -     crc32q     %rcx, %rax
-      -      -      -      -      -      -     1.00    -      -     movl       $2, %ecx
-      -      -     1.00    -      -      -      -      -      -     crc32q     %rcx, %rax
...
-      -      -      -      -      -      -      -     1.00    -     movl       $15, %ecx
-      -      -     1.00    -      -      -      -      -      -     crc32q     %rcx, %rax
-      -      -      -      -     1.00    -     1.00   1.00    -     retq


Timeline view:
                    0123456789          0123456789          0
Index     0123456789          0123456789          0123456789

[0,0]     DR   .    .    .    .    .    .    .    .    .    .   xorl    %eax, %eax
[0,1]     DeeeER    .    .    .    .    .    .    .    .    .   crc32q  %rax, %rax
[0,2]     DeE--R    .    .    .    .    .    .    .    .    .   movl    $1, %ecx
[0,3]     D===eeeER .    .    .    .    .    .    .    .    .   crc32q  %rcx, %rax
[0,4]     DeE-----R .    .    .    .    .    .    .    .    .   movl    $2, %ecx
[0,5]     D======eeeER   .    .    .    .    .    .    .    .   crc32q  %rcx, %rax
...
[0,30]    .    DeE---------------------------------------R  .   movl    $15, %ecx
[0,31]    .    D========================================eeeER   crc32q  %rcx, %rax
&lt;/pre&gt;

&lt;p&gt;Based on the “&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Instruction Info&lt;/code&gt;” table, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32q&lt;/code&gt; has latency 3 and throughput
1: Every clock cycle, we can start processing a new invocation on port 1 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[3]&lt;/code&gt;
in the table), but it takes 3 cycles for the result to be available.&lt;/p&gt;

&lt;p&gt;Instructions decompose into individual micro operations (or “uops”). The
resources section lists the processor execution pipelines (often referred to as
ports). Every cycle uops can be issued to these ports. There are constraints -
no port can take every kind of uop and there is a maximum number of uops that
can be dispatched to the processor pipelines every cycle.&lt;/p&gt;

&lt;p&gt;For the instructions in our function, there is a one-to-one correspondence so
the number of instructions and the number of uops executed are equivalent (32).
The processor has several backends for processing uops. From the resource
pressure tables, we see that while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32&lt;/code&gt; must execute on port 1, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;movl&lt;/code&gt;
executes on any of ports 0, 1, 5, and 6.&lt;/p&gt;

&lt;p&gt;In the timeline view, we see that for our back-to-back sequence, we can’t
actually begin processing the 2nd &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32q&lt;/code&gt; for several clock cycles until the
1st &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32q&lt;/code&gt; hasn’t completed. This tells us that we’re underutilizing port 1’s
capabilities, since its throughput indicates that an instruction can be
dispatched to it once per cycle.&lt;/p&gt;

&lt;p&gt;If we restructure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockHash&lt;/code&gt; to compute 3 parallel streams with a simulated
combine function (the code uses a bitwise or as a placeholder for the correct
logic that this approach requires), we can accomplish the same amount of work in
fewer clock cycles (&lt;a href=&quot;https://godbolt.org/z/ha9KdYovh&quot;&gt;Compiler Explorer&lt;/a&gt;):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
uint32_t ParallelBlockHash(const char* p) {
 uint32_t crc0 = 0, crc1 = 0, crc2 = 0;
 for (int i = 0; i &amp;lt; 5; ++i) {
   crc0 = _mm_crc32_u64(crc0, 3 * i + 0);
   crc1 = _mm_crc32_u64(crc1, 3 * i + 1);
   crc2 = _mm_crc32_u64(crc2, 3 * i + 2);
 }
 crc0 = _mm_crc32_u64(crc0, 15);
 return crc0 | crc1 | crc2;
}
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
Iterations:        1
Instructions:      36
Total Cycles:      22
Total uOps:        36

Dispatch Width:    6
uOps Per Cycle:    1.64
IPC:               1.64
Block RThroughput: 16.0

Timeline view:
                    0123456789
Index     0123456789          01

[0,0]     DR   .    .    .    ..   xorl %eax, %eax
[0,1]     DR   .    .    .    ..   xorl %ecx, %ecx
[0,2]     DeeeER    .    .    ..   crc32q       %rcx, %rcx
[0,3]     DeE--R    .    .    ..   movl $1, %esi
[0,4]     D----R    .    .    ..   xorl %edx, %edx
[0,5]     D=eeeER   .    .    ..   crc32q       %rsi, %rdx
[0,6]     .DeE--R   .    .    ..   movl $2, %esi
[0,7]     .D=eeeER  .    .    ..   crc32q       %rsi, %rax
[0,8]     .DeE---R  .    .    ..   movl $3, %esi
[0,9]     .D==eeeER .    .    ..   crc32q       %rsi, %rcx
[0,10]    .DeE----R .    .    ..   movl $4, %esi
[0,11]    .D===eeeER.    .    ..   crc32q       %rsi, %rdx
...
[0,32]    .    DeE-----------R..   movl $15, %esi
[0,33]    .    D==========eeeER.   crc32q       %rsi, %rcx
[0,34]    .    D============eER.   orl  %edx, %eax
[0,35]    .    D=============eER   orl  %ecx, %eax
&lt;/pre&gt;

&lt;p&gt;The implementation invokes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32q&lt;/code&gt; the same number of times, but the end-to-end
latency of the block is 22 cycles instead of 51 cycles The timeline view shows
that the processor can issue a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32&lt;/code&gt; instruction every cycle.&lt;/p&gt;

&lt;p&gt;This modeling can be evidenced by &lt;a href=&quot;/fast/75&quot;&gt;microbenchmark&lt;/a&gt; results for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::ComputeCrc32c&lt;/code&gt;
(&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/crc/crc32c_benchmark.cc&quot;&gt;absl/crc/crc32c_benchmark.cc&lt;/a&gt;).
The real implementation uses multiple streams (and correctly combines them).
Ablating these shows a regression, validating the value of the technique.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
name                          CYCLES/op    CYCLES/op    vs base
BM_Calculate/0                   5.007 ± 0%     5.008 ± 0%         ~ (p=0.149 n=6)
BM_Calculate/1                   6.669 ± 1%     8.012 ± 0%   +20.14% (p=0.002 n=6)
BM_Calculate/100                 30.82 ± 0%     30.05 ± 0%    -2.49% (p=0.002 n=6)
BM_Calculate/2048                285.6 ± 0%     644.8 ± 0%  +125.78% (p=0.002 n=6)
BM_Calculate/10000               906.7 ± 0%    3633.8 ± 0%  +300.78% (p=0.002 n=6)
BM_Calculate/500000             37.77k ± 0%   187.69k ± 0%  +396.97% (p=0.002 n=6)
&lt;/pre&gt;

&lt;p&gt;If we create a 4th stream for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ParallelBlockHash&lt;/code&gt; (&lt;a href=&quot;https://godbolt.org/z/eo36ejca7&quot;&gt;Compiler
Explorer&lt;/a&gt;), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; shows that the overall
latency is unchanged since we are bottlenecked on port 1’s throughput. Unrolling
further adds additional overhead to combine the streams and makes prefetching
harder without actually improving performance.&lt;/p&gt;

&lt;p&gt;To improve performance, many fast CRC32C implementations use other processor
features. Instructions like the carryless multiply instruction (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pclmulqdq&lt;/code&gt; on
x86) can be used to implement another parallel stream. This allows additional
ILP to be extracted by using the other ports of the processor without worsening
the bottleneck on the port used by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;limitations&quot;&gt;Limitations&lt;/h2&gt;

&lt;p&gt;While &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; can be a useful tool in many situations, its modeling has
limits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Memory accesses are modeled as L1 hits. In the real world, we can have much
longer stalls when we need to access the L2, L3, or even &lt;a href=&quot;/fast/62&quot;&gt;main
memory&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It cannot model branch predictor behavior.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It does not model instruction fetch and decode steps.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Its analysis is only as good as LLVM’s processor models. If these do not
accurately model the processor, the simulation might differ from the real
processor.&lt;/p&gt;

    &lt;p&gt;For example, many ARM processor models are incomplete, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; picks
a processor model that it estimates to be a good substitute; this is
generally fine for compiler heuristics, where differences only matter if it
would result in different generated code, but it can derail manual
optimization efforts.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing words&lt;/h2&gt;

&lt;p&gt;Understanding how the processor executes and retires instructions can give us
powerful insights for optimizing functions. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt; lets us peer into the
processor to let us understand bottlenecks and underutilized resources.&lt;/p&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://uops.info&quot;&gt;uops.info&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Chandler Carruth’s “&lt;a href=&quot;https://www.youtube.com/watch?v=2EWejmkKlxs&quot;&gt;Going Nowhere
Faster&lt;/a&gt;” talk&lt;/li&gt;
  &lt;li&gt;Agner Fog’s “&lt;a href=&quot;https://www.agner.org/optimize/&quot;&gt;Software Optimization
Resources&lt;/a&gt;”&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2025-10-07T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/99</link>
          <guid isPermaLink="true">https://abseil.io/fast/99</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #98: Measurement has an ROI</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #98 on August 23, 2025&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-10-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/98&quot;&gt;abseil.io/fast/98&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Effectively measuring optimization projects is an important part of the
&lt;a href=&quot;/fast/72&quot;&gt;lifecycle of an optimization&lt;/a&gt;. Overlooking a large positive (or
negative) &lt;a href=&quot;/fast/95&quot;&gt;externality&lt;/a&gt; can cause us to make the wrong decisions for
choosing our next steps and future projects. Nevertheless, this quest for
accuracy needs to be balanced against the ROI from a better measurement. In this
episode, we discuss strategies for deciding when to invest more time in
measuring a project and when to move on.&lt;/p&gt;

&lt;h2 id=&quot;getting-the-big-picture-right&quot;&gt;Getting the big picture right&lt;/h2&gt;

&lt;p&gt;In choosing a measurement strategy, we want to get the big picture right. We
want to look for where a difference &lt;a href=&quot;/fast/94&quot;&gt;changes our decisions&lt;/a&gt; for a
project: Do we roll back because something wasn’t really helpful, the complexity
unwarranted, or do we double down and keep working in the same space
&lt;a href=&quot;/fast/72&quot;&gt;following success&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;Spending a small amount of effort to realize a 2x difference in our measured
results can have a tremendously positive ROI: The extra measurement time is
easier than finding, developing, and landing another equally-sized optimization
from scratch. Conversely, spending twice the effort to refine the measurement of
a much smaller optimization has a poor ROI, as the added precision is lost in
the noise of larger effects.&lt;/p&gt;

&lt;p&gt;It is easy to fixate on the numbers that we have &lt;a href=&quot;/fast/74&quot;&gt;on the page&lt;/a&gt; while
overlooking the numbers that are off the page. It is more important that we
don’t overlook large positive (or negative) externalities that change our
conclusions than to eke out a 7th digit of precision.&lt;/p&gt;

&lt;h2 id=&quot;significant-figures&quot;&gt;Significant figures&lt;/h2&gt;

&lt;p&gt;Optimization outcomes are quantitative, which can make them an attractive
nuisance for believing they are overly precise and accurate. For many
techniques, we can only measure 1 or 2
&lt;a href=&quot;https://en.wikipedia.org/wiki/Significant_figures&quot;&gt;significant digits&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With a tool like
&lt;a href=&quot;https://research.google/pubs/google-wide-profiling-a-continuous-profiling-infrastructure-for-data-centers/&quot;&gt;Google-Wide Profiling&lt;/a&gt;,
we can represent the fraction of Google fleet cycles in TCMalloc as a 17 decimal
digit, double-precision floating point number. Writing out this many digits
doesn’t actually mean the number has that
&lt;a href=&quot;https://en.wikipedia.org/wiki/False_precision&quot;&gt;precision&lt;/a&gt;. Spending a few
additional milliseconds in TCMalloc on a single server will change some of the
digits in that number. While the overall trend is stable, there is a day-to-day
standard deviation in the total. A second-order effect with small magnitude
relative to that variation might be entirely lost in the noise.&lt;/p&gt;

&lt;p&gt;Aggregating more days can give us more samples, but longer longitudinal studies
can experience confounding factors from unrelated changes in the environment if
the true effect size is small. We may have achieved a more precise measurement,
but changes to the environment will negatively impact our accuracy beyond the
added precision.&lt;/p&gt;

&lt;h2 id=&quot;precision-and-accuracy&quot;&gt;Precision and accuracy&lt;/h2&gt;

&lt;p&gt;We want to avoid confusing
&lt;a href=&quot;https://en.wikipedia.org/wiki/Accuracy_and_precision&quot;&gt;precision for accuracy&lt;/a&gt;,
and vice-versa. Similar to how a long duration analysis might be stymied by
confounding factors, a carefully controlled experiment might claim a high
precision result without being accurate.&lt;/p&gt;

&lt;p&gt;Many load tests repeatedly replay traffic and compare the performance between a
modified and baseline configuration. These repeated runs can deliver large
sample sizes to produce low standard deviation estimates, instilling a
(potentially false) belief that the result is accurate. By construction, load
tests are &lt;a href=&quot;/fast/39&quot;&gt;simplifications&lt;/a&gt; of production and so they may omit certain
&lt;a href=&quot;/fast/94&quot;&gt;workload types, platforms, or environment features&lt;/a&gt; that would be
seen in widespread deployment.&lt;/p&gt;

&lt;p&gt;Even with tools like production A/B experiments, which can help give us accurate
results by testing against the full variety of workloads, we still must account
for nuances in the technique:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Our sample has to be representative. For example, an A/B test in a single
data center will encounter a different subset of workloads than the fleet as
a whole.&lt;/li&gt;
  &lt;li&gt;Our control and experiment groups have to be
&lt;a href=&quot;/fast/95&quot;&gt;sufficiently isolated&lt;/a&gt; from each other.&lt;/li&gt;
  &lt;li&gt;Our experimental setup needs to avoid statistical pitfalls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Spending time to account for these factors makes sense if we’re making real
gains in accuracy: Large scale data locality and contention effects can be
challenging to measure by other means. For small changes without these
externalities, we may expend a lot of effort to measure without obtaining a
better measurement.&lt;/p&gt;

&lt;h2 id=&quot;increasing-statistical-power-through-aggregation&quot;&gt;Increasing statistical power through aggregation&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#write_small_changes&quot;&gt;Small changes&lt;/a&gt;
create agility by breaking them into manageable, focused chunks, which aids
testing, debugging, and review. This can complicate a measurement story, since
it adds more pieces that we need to track.&lt;/p&gt;

&lt;p&gt;Rather than allow the measurement tail to wag the dog by forcing us to combine
unrelated optimizations or forgo them entirely, we may opt to track the
aggregate benefit from a series of optimizations made over a brief period of
time.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;As we iteratively optimized TCMalloc’s fast path, we could track the overall
trend and the performance impact against the baseline. Each individual
change could be evaluated through inspection of assembly or microbenchmarks.&lt;/li&gt;
  &lt;li&gt;During the SwissMap migration, we could track the overall trend in
associative container costs. Based on the overwhelming performance results
for early deployments, each individual change could be primarily evaluated
for correctness with careful benchmarking reserved for only a fraction of
the changes in the migration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if we’re pursuing a general strategy of aggregating similar changes, we may
want to separate out the effects of more tradeoff-heavy optimizations. A change
that creates subtle edge cases or long-lived technical debt might be worth it if
it’s a sufficiently large optimization. If we don’t end up realizing the
benefits, we might prefer to roll it back in favor of looking for simpler
approaches.&lt;/p&gt;

&lt;h2 id=&quot;balancing-complexity-and-simplicity&quot;&gt;Balancing complexity and simplicity&lt;/h2&gt;

&lt;p&gt;Aiming for greater accuracy can tempt us to pursue more complex methodologies.
An approach that is easier to implement, but captures most of the impact and
regression signals from our project, can afford us more time to work on the
actual optimizations, look for externalities, and be just as accurate in the
end.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Importantly, a simple measurement should not be confused with an incomplete
one. The goal is to avoid needless precision, not to overlook significant
impacts like transitive costs on other systems or shifts between different
resource dimensions.&lt;/p&gt;

    &lt;p&gt;The more complex approach that captures small effects can draw
&lt;a href=&quot;https://en.wikipedia.org/wiki/Law_of_triviality&quot;&gt;attention&lt;/a&gt; to its details,
causing us to overlook the larger effects that we missed. Even though we
explicitly made a good faith attempt to quantify everything, it is easier to
focus on the words on the page than the words absent from it.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;While we might capture additional phenomena relevant to performance, the
additional factors we consider introduce new sources of error for us.
Joining multiple data sources can be tempting; but if we are not familiar
with their idiosyncrasies, we might end up with surprising (or wrong)
results.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Simple is explainable. “&lt;a href=&quot;/fast/88&quot;&gt;This performance optimization only has an effect
during Australian business hours&lt;/a&gt;” might be completely correct due
to diurnal effects, but it is harder to see the immediate connection between
what our approach left implicit and a causal explanation.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we consider additional factors for measuring a project, we should try to
gauge the contribution of each relative to the significant figures provided by
the others. If one signal contributes 1% +/- 0.1pp, it will overwhelm another
term that contributes 0.01% +/- 0.001pp.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In choosing a measurement strategy, we want to strike a balance between
precision, accuracy, and effort. Accurate measurements can help us to continue
pursuing fruitful areas for adjacent optimizations, but we should be mindful
where increasing effort produces diminishing returns.&lt;/p&gt;
</description>
          <pubDate>2025-10-03T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/98</link>
          <guid isPermaLink="true">https://abseil.io/fast/98</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #26: Fixing things with hashtable profiling</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #26 on May 20, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt; and &lt;a href=&quot;mailto:zearen@google.com&quot;&gt;Zie Weaver&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-07-16&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/26&quot;&gt;abseil.io/fast/26&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As discussed by Matt Kulukundis in his
&lt;a href=&quot;https://www.youtube.com/watch?v=JZE3_0qvrMg&quot;&gt;2019 CppCon talk&lt;/a&gt;, identifying a
“slow” hashtable from a pure CPU profile can be challenging. Abseil’s
&lt;a href=&quot;/tips/136&quot;&gt;C++ hashtables&lt;/a&gt; have a built-in profiler. In this episode we
describe what insights about the hash function quality and hash collisions it
can provide, making them discernible at scale. We also look at a couple of case
studies where this information was used to improve Google’s production fleet
efficiency.&lt;/p&gt;

&lt;h2 id=&quot;starting-the-analysis&quot;&gt;Starting the analysis&lt;/h2&gt;

&lt;p&gt;We can gather hashtable profiles by collecting them from a server in production
and loading them into pprof.&lt;/p&gt;

&lt;p&gt;The data can be used to identify problematic hashtables. Bad hashtables usually
come from a low-entropy hash function or using the same hash function for both
the table and sharding across instances. These can be addressed by:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Using &lt;a href=&quot;https://abseil.io/docs/cpp/guides/hash&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt;&lt;/a&gt; to provide a
well-mixed hash function.&lt;/li&gt;
  &lt;li&gt;Using a distinct hash function by salting the hash.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;finding-stuck-bits&quot;&gt;Finding stuck bits&lt;/h2&gt;

&lt;p&gt;Stuck bits are bits that never change across every hash. Naturally, this
increases the probability of a collision exponentially in the number of stuck
bits.&lt;/p&gt;

&lt;p&gt;We can look at a few examples to demonstrate causes of stuck hash functions.&lt;/p&gt;

&lt;h3 id=&quot;case-study-internalsubscribermessagereceived&quot;&gt;Case study: &lt;code&gt;InternalSubscriber::MessageReceived&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;This function showed up multiple times when searching for stuck bits. It’s in a
client library used in many servers.&lt;/p&gt;

&lt;p&gt;We see an insertion into an indexed array called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pending_ack_callbacks&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
pending_ack_callbacks_[i].shard.insert(ack_cb, ack_callback);
&lt;/pre&gt;

&lt;p&gt;Its definition is an array of hashtables:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct {
  ABSL_CACHELINE_ALIGNED absl::flat_hash_map&amp;lt;Closure*, Closure*&amp;gt; shard;
} pending_ack_callbacks_[kNumPendingAckShards];
&lt;/pre&gt;

&lt;p&gt;where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kNumPendingAckShards = 256&lt;/code&gt;. Suspiciously, our stuck bits were 0xff =&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;We choose our shard based on the hash:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
/* static */
int InternalSubscriber::ClosureAddressToShard(Closure *address) {
  absl::flat_hash_set&amp;lt;Closure*&amp;gt;::hasher h;
  return h(address) % kNumPendingAckShards;
}
&lt;/pre&gt;

&lt;p&gt;For the hashtable of any shard, all the bottom bits will be the same by
definition. The hashtable uses these same bits to determine where to insert new
values, so we see worse performance due to collisions.&lt;/p&gt;

&lt;p&gt;This was fixed by salting the hash that determines sharding:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
absl::Hash&amp;lt;std::pair&amp;lt;Closure*, int&amp;gt;&amp;gt; h;
return h(std::pair(address, 42)) % kNumPendingAckShards;
&lt;/pre&gt;

&lt;p&gt;This salting technique provides distinct hash functions for shard lookup and
table lookup. This halved the cost of insertions in this library.&lt;/p&gt;

&lt;h3 id=&quot;case-study-processwatchdone&quot;&gt;Case study: &lt;code&gt;ProcessWatchDone&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;In a different library, we found an unusual pattern of stuck bits:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4030802800000000&lt;/code&gt;. Before it was fixed, we found the declarations:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
typedef absl::node_hash_map&amp;lt;NamespaceKey, int64, NamespaceKeyHash&amp;gt;
    NsKeyRequestIdMap;
&lt;/pre&gt;

&lt;p&gt;Since it the code previously used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NamespaceKey&lt;/code&gt; wasn’t
hashable with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::hash&lt;/code&gt;, it specified a custom hasher, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NamespaceKeyHash&lt;/code&gt;. It
used using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GoodFastHash&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
size_t NamespaceKeyHash::operator()(const NamespaceKey&amp;amp; ns_key) const {
  return GoodFastHash&amp;lt;NamespaceKey&amp;gt;()(ns_key);
}
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NamespaceKey&lt;/code&gt; is a pair of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cord&lt;/code&gt;s. But &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GoodFastHash&lt;/code&gt; does not properly mix
bits for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
typedef std::pair&amp;lt;absl::Cord, absl::Cord&amp;gt; NamespaceKey;
&lt;/pre&gt;

&lt;p&gt;Migrating this to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt; fixed this by improving mixing on the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;finding-tables-with-many-collisions&quot;&gt;Finding tables with many collisions&lt;/h2&gt;

&lt;p&gt;When a hashtable has more collisions, it has to do more probes to find a
particular element for a lookup. With more collisions, lookup performance scales
with O(n) rather than O(1). The required memory loads might be uncached,
&lt;a href=&quot;https://static.googleusercontent.com/media/sre.google/en//static/pdf/rule-of-thumb-latency-numbers-letter.pdf&quot;&gt;hurting performance&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A perfect probe length is 0, which means we found the object right where we
first looked. If the average probe length is greater than 0.1, then the table is
probing more often than should be necessary as ~10% of keys are encountering
collisions. We can calculate average probe length by dividing the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;total_probe_length&lt;/code&gt; by the sum of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;num_erases&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size&lt;/code&gt; (these two
numbers capture the total number of elements that have been inserted into the
table).&lt;/p&gt;

&lt;h3 id=&quot;case-study-portmapperimplupdateactivemap&quot;&gt;Case study: &lt;code&gt;PortMapperImpl::UpdateActiveMap&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;This one showed a max probe length of 133 and an average probe length of 8.4.
This is effectively performing a linear search on many lookups.&lt;/p&gt;

&lt;p&gt;We can look at where we are mutating the table:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Allocate new ConnLabel element and update counters
iter = active_map_-&amp;gt;find_or_insert(*flow);
iter-&amp;gt;second = new ConnLabel;
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;active_map_&lt;/code&gt;’s definition points us to:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
typedef priority_hash_map&amp;lt;IpFlow,
                          ConnLabel*,
                          IpFlowPrioritizer&amp;gt; ClientPortMap;
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;priority_hash_map&lt;/code&gt; is a custom type wrapping a SwissMap, but with
less-than-ideal defaults:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
template&amp;lt;class _Key,
         class _Val, // NOLINT - &quot;Failed to find complete declaration of
                     //           class _Val  [build/class] [5]&quot;
         class _PriorityFunc,
         class _PriorityKey = int,
         class _PriorityHash = hash&amp;lt;_PriorityKey&amp;gt;,
         class _PriorityEqual = std::equal_to&amp;lt;_PriorityKey&amp;gt;,
         class _PriorityCompare = std::less&amp;lt;_PriorityKey&amp;gt;,
         class _KeyHash = hash&amp;lt;_Key&amp;gt;,
         class _KeyEqual = std::equal_to&amp;lt;_Key&amp;gt; &amp;gt;
class priority_hash_map {
 public:
  typedef absl::flat_hash_map&amp;lt;_Key, _Val, _KeyHash, _KeyEqual&amp;gt; hash_map_type;
  ...
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_PriorityHash&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_KeyHash&lt;/code&gt; are using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hash&amp;lt;&amp;gt;&lt;/code&gt;, which provides a custom hash
specialization:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
template&amp;lt;&amp;gt; struct hash&amp;lt;IpFlow&amp;gt; {
  size_t operator()(const IpFlow&amp;amp; flow) const {
    return flow.remote_ip()
           (flow.proto() &amp;lt;&amp;lt; 24) ^ flow.local_port() ^
           (flow.remote_port() &amp;lt;&amp;lt; 16);
 }
};
&lt;/pre&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xor&lt;/code&gt;‘d bits can lead to poor mixing. For example, all you’d need for a
collision is an IP &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.0.0.33&lt;/code&gt; on port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2038&lt;/code&gt; and another IP &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.0.0.32&lt;/code&gt; on port
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2039&lt;/code&gt;. To fix this, we implemented &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslHashValue&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IpFlow&lt;/code&gt; so
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;priority_hash_map&lt;/code&gt; could switch to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Allow this to be used as a hash map key.
template&amp;lt;typename H&amp;gt;
friend H AbslHashValue(H h, const IpFlow&amp;amp; flow) {
 return H::combine(
     std::move(h),
     flow.remote_ip(),
     flow.proto(),
     flow.local_port(),
     flow.remote_port());
}
&lt;/pre&gt;

&lt;h2 id=&quot;hashtable-statistics&quot;&gt;Hashtable statistics&lt;/h2&gt;

&lt;p&gt;For each profiled hashtable, we record statistics in several tags:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;capacity&lt;/code&gt; tells the exact capacity of the hashtable.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size&lt;/code&gt; is the current number of elements in the hashtable.&lt;/li&gt;
  &lt;li&gt;The probe length statistics (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_probe_length&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;total_probe_length&lt;/code&gt;) tell
us how many extra lookups were needed to find an element. In an ideal
hashtable, we find the element we are looking for on the first lookup
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;probe length = 0&lt;/code&gt;). If there are collisions, we’ll have a higher probe
length. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_probe_length&lt;/code&gt; tells us the worst case probe length for any
element in the hashtable. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;total_probe_length&lt;/code&gt; is the sum of probe lengths
for all elements of the hashtable.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stuck_bits&lt;/code&gt; is a bitmask that will indicate any bits for which the hash
codes in the table have only seen one value (either zero or one). For a good
hash function this should be 0 for any table &amp;gt;10 elements. This is
implemented as a (running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt; of all hashes) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~&lt;/code&gt;(running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt; of all
hashes). A stuck bit indicates that our hash function may not be providing
sufficient entropy.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;num_rehashes&lt;/code&gt; records the number of times the table has been rehashed.
Calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reserve&lt;/code&gt; with an appropriate size (close to the true size of the
table) can avoid reduce hashes.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_reserve&lt;/code&gt; records the maximum size passed to a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reserve&lt;/code&gt; for the
instance, or 0 if no such call has occurred. This can be useful for
identifying tables that are too large (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size &amp;lt;&amp;lt; capacity&lt;/code&gt;) because they were
called with too large a size. Similarly, tables with many rehashes can save
on rehashing costs by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reserve&lt;/code&gt; with a sufficient size.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;num_erases&lt;/code&gt; is the number of elements that have been erased from the
hashtable (since the last rehash). The sum of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;num_erases&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size&lt;/code&gt;
indicates the number of elements added to the table since the last rehash.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline_element_size&lt;/code&gt; is the size of the elements of the flat part of the
array. For flat hashtables, this is the size of the key-value pair. For node
hashtables, this is the size of the pointer to the key-value pair.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key_size&lt;/code&gt; is equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(key_type)&lt;/code&gt; for the table.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_size&lt;/code&gt; is equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(value_type)&lt;/code&gt; for the table. On sets,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(key_type) == sizeof(value_type)&lt;/code&gt;. On maps, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_type&lt;/code&gt; holds both
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key_type&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mapped_type&lt;/code&gt; with appropriate padding for alignment.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;soo_capacity&lt;/code&gt; is the number of elements in the table’s small-object
optimization (SOO).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;table_age&lt;/code&gt; reports the age in microseconds of the table.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;detecting-bad-hashtables-in-unit-tests&quot;&gt;Detecting bad hashtables in unit tests&lt;/h2&gt;

&lt;p&gt;One additional safeguard is that we can run the profiler while running our
tests. This requires running with the environment variable
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ABSL_CONTAINER_FORCE_HASHTABLEZ_SAMPLE=1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since this triggers a test failure, its threshold for alerting is fairly high.
Unit tests may not insert sufficiently large numbers of elements into the
hashtables to produce collisions.&lt;/p&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing words&lt;/h2&gt;

&lt;p&gt;Finding issues in hashtables from a CPU profile alone is challenging since
opportunities may not appear prominently in the profile. SwissMap’s built-in
hashtable profiling lets us peer into a number of hashtable properties to find
low-quality hash functions, collisions, or excessive rehashing.&lt;/p&gt;
</description>
          <pubDate>2025-07-16T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/26</link>
          <guid isPermaLink="true">https://abseil.io/fast/26</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #95: Spooky action at a distance</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #95 on July 1, 2025&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-07-14&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/95&quot;&gt;abseil.io/fast/95&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shared resources can cause surprising performance impacts on seemingly unchanged
software. In this episode, we discuss how to anticipate these effects and
externalities.&lt;/p&gt;

&lt;h2 id=&quot;normalization-techniques&quot;&gt;Normalization techniques&lt;/h2&gt;

&lt;p&gt;Workload changes can confound longitudinal analysis: If you optimize a library
like protocol buffers, does spending more time in that code mean your
optimization didn’t work or that the application now serves more load?&lt;/p&gt;

&lt;p&gt;A/B tests can control for independent variables. Nevertheless, load balancing
can throw a wrench into this. A client-side load balancing algorithm (like
&lt;a href=&quot;https://sre.google/sre-book/load-balancing-datacenter/&quot;&gt;Weighted Round Robin&lt;/a&gt;)
might observe the better performance of some tasks and send more requests to
them.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In absolute terms, the total CPU usage of both experiment arms might be
unchanged.&lt;/li&gt;
  &lt;li&gt;In relative terms, there may be small, second order changes in relative time
(for example, %-of-time in Protobuf). This might hide the true significance
of the optimization or worse, lead us to believe the change is a regression
when it is not.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For individual jobs, normalizing by &lt;a href=&quot;/fast/7&quot;&gt;useful work done&lt;/a&gt; can let us
compare throughput-per-CPU or throughput-per-RAM to allow us to control for
workload shifts.&lt;/p&gt;

&lt;h2 id=&quot;choosing-the-right-partitioning-scheme&quot;&gt;Choosing the right partitioning scheme&lt;/h2&gt;

&lt;p&gt;Where we have shared resources at the process, machine, or even data center
level, we want to design an experimentation scheme that allows us to treat the
shared resources as part of our experiment and control groups too.&lt;/p&gt;

&lt;h3 id=&quot;cache-locality-and-memory-bandwidth&quot;&gt;Cache locality and memory bandwidth&lt;/h3&gt;

&lt;p&gt;Cache misses carry two costs for performance: they cause our code to wait for
the miss to resolve and every miss puts pressure on the memory subsystem for
other code that we are not closely studying.&lt;/p&gt;

&lt;p&gt;In a &lt;a href=&quot;/fast/83&quot;&gt;previous episode&lt;/a&gt;, we discussed an optimization to move a hot
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_set&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_set&lt;/code&gt;. This change only affected one
particular type of queries going through the server. While we saw 5-7%
improvements for those types of queries, completely unmodified code paths for
other query types also showed an improvement, albeit smaller.&lt;/p&gt;

&lt;p&gt;Measuring the latter effect required process-level partitioning, which selected
some processes to always use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_set&lt;/code&gt; and other processes to always
use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_set&lt;/code&gt;. Without this technique, all requests handled by the
server coexist with a 50:50 mix of modified/unmodified code paths. The modified
code path would have shown a performance improvement from fewer cache misses on
its lookups. For query types unaffected by the change, their data structures
would have seen the same mix of cache pressure from neighboring modified and
unmodified requests, rather than ever seeing a 100% modified or 100% unmodified
neighbor. Per-request randomization would prevent us from measuring the “blast
radius” impact of our change. This happens all the time for any change that uses
a shared resource (aka most changes).&lt;/p&gt;

&lt;p&gt;This challenge of experiment design can be especially pronounced with load
tests. Without studying the right query distribution of different request types
concurrently, we won’t see the full impact, both positive and negative, of our
change.&lt;/p&gt;

&lt;h3 id=&quot;better-hugepage-coverage-lifted-all-boats&quot;&gt;Better hugepage coverage lifted all boats&lt;/h3&gt;

&lt;p&gt;Before
&lt;a href=&quot;https://storage.googleapis.com/gweb-research2023-media/pubtools/6170.pdf&quot;&gt;Temeraire&lt;/a&gt;,
TCMalloc’s hugepage-aware allocator, many teams had opted to not periodically
release memory from TCMalloc’s page heap to maximize hugepage availability and
CPU performance. Other, less CPU-intensive workloads released memory
periodically to strike a different balance between CPU usage and RAM usage due
to free pages resting on TCMalloc’s heap.&lt;/p&gt;

&lt;p&gt;Several
&lt;a href=&quot;https://storage.googleapis.com/gweb-research2023-media/pubtools/6213.pdf&quot;&gt;additional&lt;/a&gt;
optimizations have since modified the behavior, but the initial rollout sought
to maintain the same “release on request” characteristic of the old page heap to
&lt;a href=&quot;/fast/79&quot;&gt;minimize tradeoffs&lt;/a&gt;. Ensuring that almost all applications used no
more memory than they previously did allowed us to focus on CPU performance and
a handful of edge cases in allocation patterns.&lt;/p&gt;

&lt;p&gt;When we ran A/B experiments prior to the fleetwide rollout of Temeraire, we saw
improvements in hugepage coverage, even for applications that did not
periodically release memory.&lt;/p&gt;

&lt;p&gt;Managing memory in a hugepage-aware fashion everywhere improved performance even
where we did not anticipate substantial benefits. The new allocator allowed
whole hugepages to be returned, avoiding physical memory fragmentation
altogether, and allowed us to iteratively target already fragmented pages to
satisfy requests.&lt;/p&gt;

&lt;p&gt;These added benefits were only recognized by A/B testing at the machine level.
While we had enabled Temeraire with the help of many eager, early adopters, we
could only see the first order effect–direct impact on the modified
application–and not the second order effect–better behaved neighbors–during
those experiments.&lt;/p&gt;

&lt;h3 id=&quot;distributed-systems&quot;&gt;Distributed systems&lt;/h3&gt;

&lt;p&gt;In larger, distributed serving stacks, we might go further to partition
resources to prevent confounding our results.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;For example, if we send more requests to server backends during an A/B
experiment, the effect of higher load will be smeared across all of the
backends, affecting both the experiment and control group’s latency. Several
teams use a “stripes” setup for this purpose, partitioning the serving stack
so that once a request is routed to one particular partition, it does not
cross back into other partitions.&lt;/li&gt;
  &lt;li&gt;A change to
&lt;a href=&quot;https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43438.pdf&quot;&gt;job scheduling&lt;/a&gt;
might impact how work is distributed to individual machines in a data
center. If we were to improve performance on some machines, effectively
lowering their utilization, the control plane might shift machine
assignments to rebalance. While jobs may still have effectively the same
amount of CPU time, a busier machine can translate into lower per-core
performance due to memory bandwidth, cache contention, and frequency scaling
effects that create a headwind for the experiment group.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing words&lt;/h2&gt;

&lt;p&gt;Managing and reducing contention for shared resources is a large source of
performance opportunities. Nevertheless, recognizing these opportunities fully
requires consideration of experiment design to ensure confounding factors do not
obscure the real benefits from us.&lt;/p&gt;
</description>
          <pubDate>2025-07-14T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/95</link>
          <guid isPermaLink="true">https://abseil.io/fast/95</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #94: Decision making in a data-imperfect world</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #94 on June 26, 2025&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-06-27&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/94&quot;&gt;abseil.io/fast/94&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Profiling tools are vital to narrowing the search space of all possible changes
we could make to highlight the best uses of our time. In this episode, we
discuss strategies for identifying when we might want to seek out more data and
when we are in the midst of diminishing returns.&lt;/p&gt;

&lt;h2 id=&quot;focusing-on-outcomes&quot;&gt;Focusing on outcomes&lt;/h2&gt;

&lt;p&gt;The ultimate outcomes that we want from our tools are insights that let us
improve performance.&lt;/p&gt;

&lt;p&gt;We can almost always do more analysis – increase the time horizon, auxiliary
metrics considered, alternative bucketing strategies – to try to make a
decision. This can be initially helpful at finding unforeseen situations, but we
might mire ourselves in &lt;a href=&quot;/fast/88&quot;&gt;spurious findings&lt;/a&gt; or develop analysis
paralysis.&lt;/p&gt;

&lt;h3 id=&quot;changing-decisions&quot;&gt;Changing decisions&lt;/h3&gt;

&lt;p&gt;At some point, &lt;a href=&quot;/fast/60&quot;&gt;redundant tools&lt;/a&gt;, &lt;a href=&quot;/fast/98&quot;&gt;extra precision&lt;/a&gt;, or
further experiments add less value than their cost to obtain. While we can seek
these things anyway, if they aren’t changing the decisions we make, we could do
without and achieve the same outcome.&lt;/p&gt;

&lt;p&gt;It’s easy to fall into a trap of looking for one last thing, but this carries an
opportunity cost. We will occasionally make mistakes in the form of unsuccessful
projects. While some of these could be avoided in hindsight with extra analysis
or a small “fail fast” prototype, these are tolerable when the
&lt;a href=&quot;/fast/87&quot;&gt;stakes are low&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When considering an experiment to get additional information, ask yourself
questions like “can the possible range of outcomes convince me to change my
mind?” Otherwise, constructing additional experiments may merely serve to
provide confirmation bias. The following are examples where the extra analysis
seems appealing, but is ultimately unnecessary:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;We might try out a new optimization technique with minimal rollout scope and
complexity. If it works, we’ve &lt;a href=&quot;/fast/72&quot;&gt;gained confidence&lt;/a&gt;. If it fails,
we should change our plans. If either of those &lt;em&gt;possible&lt;/em&gt; outcomes might be
&lt;a href=&quot;https://en.wikipedia.org/wiki/Ad_hoc_hypothesis&quot;&gt;insufficient to persuade us&lt;/a&gt;,
we should instead develop a plan that will provide a definitive next step.&lt;/p&gt;

    &lt;p&gt;If we plan to iteratively move
&lt;a href=&quot;/fast/39&quot;&gt;from microbenchmark to loadtest to production&lt;/a&gt;, we should stop or
at least reconsider if the early benchmarks produce neutral results rather
than moving to production. The fact that a benchmark can give us a result
different from production might motivate us to move forward anyway, but
tediously collecting the data from them is pointless if our plan is to
unconditionally ignore them.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;/fast/90&quot;&gt;Estimates&lt;/a&gt; only need to be good enough to break ties. If our plan
is to look at the top 10 largest users of a library for performance
opportunities, improved accuracy might adjust the order somewhat, but not
dramatically. Historical data might give us slightly different orders for
rankings chosen using yesterday’s data versus last week’s, but the bulk of
the distribution is often roughly consistent.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;failing-fast&quot;&gt;Failing fast&lt;/h3&gt;

&lt;p&gt;Consider a project where we’re optimistic it will work, but we have a long slog
ahead of ourselves to get it over the finish line. There are a couple of
strategies we can use to quickly gain confidence in the optimization or abandon
it if it fails to provide the expected benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A &lt;a href=&quot;/fast/64&quot;&gt;new API&lt;/a&gt; might be more expressive and easier to optimize, but
we need to migrate our existing users to it. Testing and canarying a single
user is easier to attempt (and rollback, if unsuccessful) than to deploy it
everywhere before switching implementations.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We might be interested in deploying a new data layout, either in-memory or
on-disk. A simple prototype that simulates an approximation of that layout
can tell us a lot about the probable performance characteristics. Even
before we can handle every edge case, the “best case” scenario not panning
out gives us a reason to stop and go no further.&lt;/p&gt;

    &lt;p&gt;For example, as we attempt to remove &lt;a href=&quot;/fast/83&quot;&gt;data indirections&lt;/a&gt;, we might
&lt;a href=&quot;/fast/75&quot;&gt;microbenchmark&lt;/a&gt; a few candidate layouts for a data structure,
starting from the status quo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;T*&amp;gt;&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::deque&amp;lt;T&amp;gt;&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InlinedVector&amp;lt;T*, 4&amp;gt;&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;T&amp;gt;&lt;/code&gt;. Each of these solutions
has its merits based on the constraints of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; and the access pattern of the
program. Having a sense of where the largest opportunity is for the current
access pattern can help us focus our attention and avoid a situation where
we sink time into a migration before we can derisk anything.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Getting things over the finish line may still be 80% of the work, but our
initial work will have derisked the outcome. Investing time in polish for a
project that ultimately fails carries a high opportunity cost.&lt;/p&gt;

&lt;h3 id=&quot;updating-our-priors&quot;&gt;Updating our priors&lt;/h3&gt;

&lt;p&gt;The analysis we do is just to determine the course of action we should take.
Ultimately, we care about the impact of the action, not how elegant our plans
were. A promising change backed by good estimates and preliminary benchmarks has
to be successful when deployed to production to actually be a success. Good
benchmarks alone are not the &lt;a href=&quot;/fast/70&quot;&gt;outcome&lt;/a&gt; we are after. Sometimes we’ll
find that promising analysis or benchmarks do not turn into benefits in
production, and the outcome is instead &lt;a href=&quot;/fast/72&quot;&gt;an opportunity for learning&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If we chose among several candidate solutions to a problem, we should confirm
that their qualities held up. For example, we might have picked a strategy that
was more complex but perceived to be more reliable than an alternative. Even if
the project was a success otherwise, but reliability instead suffered, we should
reconsider if the alternatives are worth revisiting.&lt;/p&gt;

&lt;h2 id=&quot;data-censorship&quot;&gt;Data censorship&lt;/h2&gt;

&lt;p&gt;Our tools sometimes have blind spots that we need to consider when using them.
Simplifications to get a “good enough” result can help our priors, but we should
be cautious about extrapolating too broadly from them.&lt;/p&gt;

&lt;p&gt;More data points with the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Censoring_\(statistics\)&quot;&gt;same caveats&lt;/a&gt; merely
make us overconfident, not more accurate. When the stakes are higher,
cross-validation against other information can help uncover gaps. More data
points from distinct vantage points are more valuable than more data points from
the same ones. We should prime ourselves to consider what new evidence would
cause us to reconsider our plans.&lt;/p&gt;

&lt;h3 id=&quot;profiler&quot;&gt;Profiler limitations&lt;/h3&gt;

&lt;p&gt;Many profilers are cost-conscious to minimize their impact. To do this, they
employ sampling strategies that
&lt;a href=&quot;https://en.wikipedia.org/wiki/Censoring_\(statistics\)&quot;&gt;omit some data points&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our &lt;a href=&quot;/fast/26&quot;&gt;hashtable profiler&lt;/a&gt; makes its sampling decisions when tables are
first mutated. Avoiding a sampling decision in the default constructor keeps
things efficient, but means that empty tables are not represented in the
statistics. Using other profilers, we can determine that many destroyed tables
are in fact empty.&lt;/p&gt;

&lt;p&gt;Historically, TCMalloc’s lifetime profiler had a similar caveat. To simplify the
initial implementation, it only reported objects that had been both allocated
&lt;em&gt;and&lt;/em&gt; deallocated during a profiling session. It omitted existing objects (left
censorship) and objects that outlived the session (right censorship). This
profiler has since been improved to include these, but understanding a
profiler’s limitations is crucial to avoiding drawing the wrong conclusions from
biased data.&lt;/p&gt;

&lt;p&gt;Profilers tracking CPU cycles are often measuring how long it took for an
instruction to retire. The profile &lt;a href=&quot;/fast/39&quot;&gt;hides&lt;/a&gt; the cost of instructions
that come after a high latency one. In other situations, diffusely attributed
costs may obscure the actual critical path of the function found only by
&lt;a href=&quot;https://github.com/protocolbuffers/upb/pull/310&quot;&gt;careful analysis&lt;/a&gt; or tools
like &lt;a href=&quot;https://llvm.org/docs/CommandGuide/llvm-mca.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm-mca&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These examples illustrate how not everything can be measured with a
sampling-based profiler, but there are often different approaches.&lt;/p&gt;

&lt;h3 id=&quot;partial&quot;&gt;Partial populations&lt;/h3&gt;

&lt;p&gt;Running a load test or even &lt;a href=&quot;/fast/39&quot;&gt;canarying a change in production&lt;/a&gt; for a
single application can increase our confidence that something will work.
Nevertheless, the limited scope doesn’t assure us that the effect will be the
same on a wider population.&lt;/p&gt;

&lt;p&gt;This pitfall cuts in both positive and negative directions. If we have an
optimization for a library that isn’t used by an application, no amount of
testing it with that application is likely to produce a &lt;a href=&quot;/fast/88&quot;&gt;real effect&lt;/a&gt;.
A negative result where there is no opportunity for the optimization to show
benefit should not deter us, but we might abandon a good idea because of the
spurious result. Conversely, an optimization might falter as it is brought to a
broader scale, as our initial data points were biased by
&lt;a href=&quot;/fast/74&quot;&gt;streetlamp effects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can avoid this by measuring the effect on the wider population or by choosing
a broadly representative set of data points, instead of just one. Minimally we
should be confident that the method we have chosen to evaluate the optimization
has the potential to show a positive or negative impact.&lt;/p&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing words&lt;/h2&gt;

&lt;p&gt;As we work to gather data to guide our decisions, we should work to ensure we’re
looking for features that could lead us to change our plans. It is easy to fall
into the trap of seeking additional data points to increase confidence, but we
may merely be falling into a trap of confirmation bias.&lt;/p&gt;
</description>
          <pubDate>2025-06-27T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/94</link>
          <guid isPermaLink="true">https://abseil.io/fast/94</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #93: Robots never sleep</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #93 on May 27, 2025&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-06-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/93&quot;&gt;abseil.io/fast/93&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Techniques like presubmits are essential tools for effective software
engineering. For performance optimization, changing observable but unspecified
behaviors can be a large source of opportunities. In this episode, we discuss
strategies for leaning on automation and additional tools to make it easier to
evolve software.&lt;/p&gt;

&lt;h2 id=&quot;prevent-problems-via-technical-means&quot;&gt;Prevent problems via technical means&lt;/h2&gt;

&lt;p&gt;Use technical means, rather than (eventually fallible) humans, to prevent
problems. Humans can be a valuable line of defense for unknown unknowns, but
they cannot be the only line of defense for everything. While human-executed
&lt;a href=&quot;https://en.wikipedia.org/wiki/The_Checklist_Manifesto&quot;&gt;checklists are great&lt;/a&gt;,
they also have to be short and that makes them unsuitable for encoding a bunch
of knowledge about a problem domain. It can be tempting to add to the checklist
after every incident and never subtract from it, but this leads to inevitable
toil or skipped steps. Robots never get tired.&lt;/p&gt;

&lt;p&gt;When we introduced &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GoodFastHash&lt;/code&gt; as a faster alternative to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::hash&lt;/code&gt;, it was
intended that we could change the algorithm from time to time. This property was
documented in a comment. Over time, we accreted code depending on its existing
behavior. This ranged from brittle tests relying on the stable order of
iteration of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt; paired with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GoodFastHash&lt;/code&gt; to production
designs that relied on it for stable cache keys. This stymied performance and
hash quality improvements to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GoodFastHash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Automated testing is a well-known software technique, but it can be worth
bringing the automation to bear in new ways on new problems to
&lt;a href=&quot;https://en.wikipedia.org/wiki/Shift-left_testing&quot;&gt;shift-left&lt;/a&gt;. Consider an
example outside of performance: Many outages have been caused by large,
unanticipated changes in configurations. For example, a 100.0% reduction in
configuration size is probably a bug (and an outage waiting to happen). An empty
configuration file can be detected mechanically, leaving humans to worry about
all of the much more subtle gotchas. Presubmit checks that detect and block
large diffs without an explicit exception can stop many issues in their tracks.&lt;/p&gt;

&lt;p&gt;We can apply automation towards keeping code flexible over the long run,
enabling us to make it more efficient while simultaneously ensuring reliability.&lt;/p&gt;

&lt;h2 id=&quot;strategies-for-taming-subtlety&quot;&gt;Strategies for taming subtlety&lt;/h2&gt;

&lt;p&gt;As the complexity of our software stack grows, tending to every corner reliably
and manually is challenging. An API might promise one thing, but the software
built on top of it relies on its implementation details much farther down the
stack.&lt;/p&gt;

&lt;h3 id=&quot;compile-time-hardening&quot;&gt;Compile-time hardening&lt;/h3&gt;

&lt;p&gt;The very &lt;a href=&quot;/tips/1&quot;&gt;first C++ TotW&lt;/a&gt; was for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;, which can improve
performance by avoiding string copies. This makes it attractive for regular
usage, but it is bug-prone due to &lt;a href=&quot;/tips/180&quot;&gt;dangling references&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Reference-like types like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Span&lt;/code&gt; allow us to write
code agnostic to the underlying data storage. A string could be backed by
constant data in a global or a heap allocated copy. A container of N elements
might be stored as an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InlinedVector&lt;/code&gt;, removing a
&lt;a href=&quot;/fast/83&quot;&gt;heap indirection&lt;/a&gt; in the common case.&lt;/p&gt;

&lt;p&gt;As with other references, these types come with downsides: The usage of the
reference might not coincide with the lifetime of the underlying storage,
leading to use-after-free/use-after-return bugs. While sanitizers can detect
these bugs, they can have false negatives depending on test coverage.
Fortunately, source code annotations like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ABSL_ATTRIBUTE_LIFETIME_BOUND&lt;/code&gt; can
find many of them at compile time. These annotations allow us to shift-left on
finding bugs, allowing the engineer actively writing code to fix the issue right
away, rather than waiting for a production outage with its commensurately higher
costs.&lt;/p&gt;

&lt;p&gt;Similarly, lock annotations allow us to programmatically
&lt;a href=&quot;https://clang.llvm.org/docs/ThreadSafetyAnalysis.html&quot;&gt;convey thread safety requirements&lt;/a&gt;
so they can be checked at compile time. Rather than having to remember to hold a
lock on every access of a member variable by hand, we can transform these into
build failures when we access it without holding the lock. While these
annotations can’t express subtle, but correct, locking strategies, they can
allows us budget more time for those subtle cases, saved by not having to
carefully audit even mundate concurrency patterns.&lt;/p&gt;

&lt;h3 id=&quot;runtime-hardening&quot;&gt;Runtime hardening&lt;/h3&gt;

&lt;p&gt;Over time, we’ve developed several techniques for warding off
&lt;a href=&quot;https://hyrumslaw.com&quot;&gt;Hyrum’s Law&lt;/a&gt;. While there are any number of
implementation details we can obfuscate, the following techniques have proven
useful:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Memory addresses for low-cost entropy: Taking the address of a global is
extremely efficient (a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rip&lt;/code&gt;-relative &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lea&lt;/code&gt; on x86) and powers
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt;’s randomization. Having learned from the lessons of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GoodFastHash&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt; deliberately used a random number to seed its
hash computation. This ensured tests were more robust because they could not
rely on fragile implementation details. Consequently, it has been possible
to land several optimizations to replace its implementation wholesale
without being blocked by brittleness.&lt;/p&gt;

    &lt;p&gt;This introduces just enough entropy from ASLR and linker orderings to make
it hard to rely on its values across tests and production tasks. Similarly,
heap allocations can provide instance-specific entropy. We use this in
SwissMap to ensure different table instances have different iteration
orders.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Extra checks in debug builds / sampling: We want to maintain implementation
freedom to ensure we can improve performance in future. However, expensive
checks would reduce performance if done in optimized builds, defeating part
of the purpose. For these, we can put most of our checks in debug builds.&lt;/p&gt;

    &lt;p&gt;Sized delete from C++14 allows our deallocation path to avoid a costly radix
tree walk, but incorrect sizes would lead to data corruption. In debug
builds, TCMalloc checks the provided size against its internal metadata
groundtruth. TCMalloc already samples periodically to drive heap profiling,
allowing it to provide extra checks on these sampled objects to
&lt;a href=&quot;https://dl.acm.org/doi/10.1145/3639477.3640328&quot;&gt;proactively find further issues in production&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Counterfactual checks: In sanitizer builds, we check that SwissMap’s
iterators remain valid after any potential invalidations. Even if a
particular insert doesn’t cause a rehash &lt;em&gt;but could have caused one&lt;/em&gt;, the
iterator is considered invalid. This allows us to prevent dependencies on
SwissMap’s growth rate, iterator invalidation behaviors, and so forth, even
if the present implementation used in day-to-day builds overdelivers against
its guarantees.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enabling these defenses widely means we get benefits from everyone’s tests.
These approaches ensure that code does not depend on characteristics that are
sensitive to implementation details, so we can change implementations quickly
without breaking code.&lt;/p&gt;

&lt;h3 id=&quot;static-analysis&quot;&gt;Static analysis&lt;/h3&gt;

&lt;p&gt;Tools like Clang-Tidy can spot problematic patterns and flag them at code review
time. This can shift left on preventing problems, rather than waiting for a
failed runtime check in production.&lt;/p&gt;

&lt;p&gt;For example, some protobuf optimizations are sensitive to misuse of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const_cast&lt;/code&gt;. This misuse is partly stopped by placing default instances in
global, read-only storage, causing the program to crash if the instance is
mutated. Since it isn’t ideal to crash on potentially under-tested code paths
and because this technique doesn’t cover all types of misuse, a Clang-Tidy check
can flag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const_cast&lt;/code&gt; where the type is a protobuf instance.&lt;/p&gt;

&lt;h3 id=&quot;ratchet-and-pawl&quot;&gt;Ratchet-and-pawl&lt;/h3&gt;

&lt;p&gt;Matt Kulukundis popularized the phrase “ratchet-and-pawl” to describe
incremental migrations that prevented backsliding. This allows us to make
progress where we can, secure in the knowledge that the problem will not get
worse.&lt;/p&gt;

&lt;p&gt;During the SwissMap migration, it was infeasible to randomize &lt;em&gt;all&lt;/em&gt; existing
unordered containers due to failing tests and actual production dependencies on
the current behavior. Individual instances could be migrated where tests passed
(or were made to pass). As the migration progressed, visibility allowlists on
lesser used containers (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dense_hash_map&lt;/code&gt;) and Clang Tidy on more common ones
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt;) reduced new usages of the legacy containers. An allowlist
with a thousand entries might seem inelegant, but it’s a powerful tool for
preventing backsliding. The list can be ratcheted down over time by hand or by
automated cleanups as uses are removed.&lt;/p&gt;

&lt;h2 id=&quot;costs-of-avoided-guarantees&quot;&gt;Costs of avoided guarantees&lt;/h2&gt;

&lt;p&gt;Preserving implementation freedom carries costs, whether due to performance
overheads when we need to work around it, opportunity costs, or simply worse
ergonomics.&lt;/p&gt;

&lt;p&gt;With hashtables, changing hash algorithms, initial sizes, and growth rates had
come up time and time again, stymied by brittle tests, prior to the introduction
of SwissMap and Abseil Hash. SwissMap using its heap allocation’s address as an
entropy source makes copies more expensive on primitive types: Rather than
simply &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt;‘ing the raw data, we need to rehash our keys. Making the order
more deterministic could let us improve performance, but the benefits outweigh
these small costs.&lt;/p&gt;

&lt;p&gt;As useful as it is to maintain as much implementation flexibility, it is
important to focus on the implementation details most likely to change. Just
because we can obscure an implementation detail doesn’t necessarily mean it’s
worth the runtime and engineering cost if it’s unlikely to ever change or
valuable to do so.&lt;/p&gt;

&lt;h2 id=&quot;validating-policy-choices&quot;&gt;Validating policy choices&lt;/h2&gt;

&lt;p&gt;For large, performance-critical optimizations, we may want to carefully test
that the desired &lt;em&gt;performance&lt;/em&gt; characteristics remain, even where the code would
be functionally correct with or without the optimization.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;TCMalloc’s tests often relied on making lots of actual allocations to
exercise edge cases, but with the development of
&lt;a href=&quot;https://storage.googleapis.com/gweb-research2023-media/pubtools/6170.pdf&quot;&gt;Temeraire&lt;/a&gt;,
tests could exercise the policies to simulate gigabytes of memory usage
without actually using that much physical memory. Leveraging this design
choice allowed a wider variety of edge cases to be tested and regressions
avoided as new improvements are brought online.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Protobuf elides copies in several situations. Tests ensure that this
implementation detail is preserved to avoid substantial regressions.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we like our optimizations, we should
&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html&quot;&gt;put a test on it&lt;/a&gt;.
Automation prevents regressions upfront, rather than waiting for after-the-fact
debugging.&lt;/p&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing words&lt;/h2&gt;

&lt;p&gt;Shifting problem-finding away from humans and onto automated mechanisms lets us
focus on the bigger picture and improve our velocity. When things do break, we
save human time in the long-run because we can spend less effort figuring out
what caused a regression.&lt;/p&gt;
</description>
          <pubDate>2025-06-03T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/93</link>
          <guid isPermaLink="true">https://abseil.io/fast/93</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #90: How to estimate</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #90 on February 6, 2025&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-08-11&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/90&quot;&gt;abseil.io/fast/90&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Estimating savings can be useful for improving our decision making. In this
episode, we discuss how to make and use estimates in the
&lt;a href=&quot;/fast/72&quot;&gt;optimization lifecycle&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;why-estimate&quot;&gt;Why estimate?&lt;/h2&gt;

&lt;p&gt;While looking for and developing optimizations, we use performance estimates
frequently to decide how to approach problems and spend time:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A sense of how &lt;a href=&quot;/fast/72&quot;&gt;large a problem domain&lt;/a&gt; is might tell us where to
look for opportunities in the first place.&lt;/li&gt;
  &lt;li&gt;Given finite time and multiple projects to work on, we will prioritize those
with the highest return on investment. Estimation lets us fill in a guess
for “return,” before we have it in hand. Our goal is to make better
decisions, not perfect-in-hindsight ones.&lt;/li&gt;
  &lt;li&gt;Within a specific optimization project, an estimate of the benefit might
inform us how much complexity (fiddly edge cases, technical debt, etc.) we
might be willing to tolerate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The outcome of better estimates is better decisions, which informs us how much
precision we might need. If we’re considering project A that will make things 5%
faster and project B that will make things 0.1% faster, we don’t need to worry
about additional significant figures for project A’s estimate. A more precise
estimate for project A of 5.134% won’t change our prioritization all things
being equal (effort, complexity, etc.). In that situation, we should instead
prefer to focus on information that could &lt;a href=&quot;/fast/94&quot;&gt;change our decision&lt;/a&gt; rather
than gathering unneeded precision that won’t.&lt;/p&gt;

&lt;h2 id=&quot;how-big-is-it&quot;&gt;How big is it?&lt;/h2&gt;

&lt;p&gt;Profiles are our jumping-off point for sizing how large an opportunity might be.
When we’re deciding between competing choices, this information can give us a
high-order bit to winnow the set for further investigation.&lt;/p&gt;

&lt;p&gt;The best-case scenario is that we completely eliminate a bottleneck: If we drove
something’s cost all the way to zero, would it be a worthwhile opportunity, or
are there larger ones to pursue? This can be a handy heuristic as we’re filling
in blanks for where an optimization might not be applicable. We can assume the
best case scenario–an optimization applies everywhere, to the fullest
degree–and see if the result is still meaningful. If it’s not, a more accurate
estimate won’t change the outcome.&lt;/p&gt;

&lt;h3 id=&quot;exploring-profiles&quot;&gt;Exploring profiles&lt;/h3&gt;

&lt;p&gt;The most common starting point is a CPU or heap profile. We can refine this
information to identify a rough upper bound for the opportunity. To illustrate
this, consider a few examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;As of February 2025, the protobuf implementation checks
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;the_repeated_field.size() != 0&lt;/code&gt; for deciding whether a repeated field is
present and in need of further recursion. While there’s nothing inherently
wrong with this, a message with many absent fields might be able to check
their presence more efficiently with “has bit”-like auxiliary data rather
than &lt;a href=&quot;/fast/62&quot;&gt;touching many cachelines&lt;/a&gt;.&lt;/p&gt;

    &lt;p&gt;In the very best case, we can make two assumptions. First, the added cost of
toggling a bit every time we create a mutable reference to the field is
free. Second, every call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size()&lt;/code&gt; internal to the protocol buffer
implementation can be elided with this because the fields are all absent.
This is a gross simplifying assumption (and not true), but it provides an
upper bound.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The C++ protocol buffer parsing implementation uses a series of tail-called
functions for parsing each type of field. Prior to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;preserve_none&lt;/code&gt;
calling convention added in LLVM and adopted by protobuf, these function
bodies would preserve registers–adding extra &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pop&lt;/code&gt;s and code size
pressure–that would be unneeded.&lt;/p&gt;

    &lt;p&gt;We could use profiles to identify parsing functions with push/pop
instructions setting up frames, sum their total cost, and scale based on
past experience from optimizations that had eliminated stack frames in other
libraries to produce an estimate.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Copies and destructors consume a large fraction of compute. While we cannot
necessarily eliminate all of those copies and their corresponding
destructors, some can be elided by using a const reference or a move. Tools
allow us to join profiles against a specific C++ pattern to estimate the
potential savings.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;leveraging-other-data-sources&quot;&gt;Leveraging other data sources&lt;/h3&gt;

&lt;p&gt;Other PMU events and server facts can give us more information about the size
and scope of a problem.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Events like page table walks or what fraction of effective pages were small
can tell us about the total size of the opportunity from huge pages.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.intel.com/content/www/us/en/docs/vtune-profiler/cookbook/2023-0/top-down-microarchitecture-analysis-method.html&quot;&gt;Topdown analysis&lt;/a&gt;
to break down whether a piece of code is frontend or backend-bound can tell
us how much we can expect to save. If a particular function is largely
backend-bound, reducing instruction count, branches, or applying SIMD might
not be helpful. Conversely, if a function is frontend-bound, optimizing the
memory accesses it makes might not be helpful.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Allocation size information from TCMalloc profiles can help tell us about
the size of a particular container. If all of the memory requests coming
from a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;MyType&amp;gt;&lt;/code&gt; instance are for exactly &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(MyType)&lt;/code&gt;
bytes, the vector’s size is likely 1.&lt;/p&gt;

    &lt;p&gt;While proving a strict bound may be difficult, distributions from the heap
or &lt;a href=&quot;/fast/26&quot;&gt;container-specific profiles&lt;/a&gt; can give us a sense of what is
most likely to be encountered and worth optimizing for.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-much-can-we-change&quot;&gt;How much can we change?&lt;/h2&gt;

&lt;p&gt;For identifying high-value projects, we can winnow many by making best-case
assumptions for the project: We can completely eliminate the bottleneck and so
on. While this is a helpful simplifying assumption, we often need to estimate
how much we can move the needle by to get more precision when needed.&lt;/p&gt;

&lt;h3 id=&quot;past-performance&quot;&gt;Past performance&lt;/h3&gt;

&lt;p&gt;Analogous past projects can help form a baseline for the estimates. For example,
if job reshaping improved performance for a variety of workloads by
&lt;a href=&quot;https://www.oreilly.com/content/rethinking-task-size-in-sre/&quot;&gt;15% or more&lt;/a&gt;, we
might apply a similar rule of thumb to our own reshaping project.&lt;/p&gt;

&lt;p&gt;Temporarily disabling an optimization can give us a sense of how sensitive a
workload is to a particular parameter. Ablating an existing optimization can be
easier to implement than a prototype.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Adaptive Prefetching modulates HW prefetchers based on the machine’s memory
bandwidth usage. While beneficial in aggregate, slicing by function allowed
us to identify functions that were
&lt;a href=&quot;https://storage.googleapis.com/gweb-research2023-media/pubtools/7758.pdf&quot;&gt;more sensitive to prefetching&lt;/a&gt;
that were good candidates for software prefetching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;speed-of-light&quot;&gt;Speed of light&lt;/h3&gt;

&lt;p&gt;Comparing a simpler implementation that isn’t fit for purpose can tell us how
close our current implementation is to the speed of light of the hardware. This
can tell us about the cost of factors like data movement that we cannot make any
faster without reworking data structures or the problem altogether.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memset&lt;/code&gt; can be a ready stand-in for many data processing functions,
since they simply move data without performing computation. If an existing
implementation is already close to these substitutes, the headroom for
optimization might be small.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://sre.google/static/pdf/rule-of-thumb-latency-numbers-letter.pdf&quot;&gt;Latency rules of thumb&lt;/a&gt;
or known hardware characteristics can give us another lower bound.&lt;/p&gt;

&lt;h3 id=&quot;analytical&quot;&gt;Analytical methods&lt;/h3&gt;

&lt;p&gt;We may be able to deduce a fraction based on the known properties of a library.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SwissMap doubles its capacity on resize and supports a maximum load factor
of 87.5%, so its minimum load factor is typically 43.75%.&lt;/li&gt;
  &lt;li&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; typically doubles when full, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size()/capacity()&lt;/code&gt; will be
at least 50%.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple mean of the two extremes might be a good enough approximation. When
profiles are &lt;a href=&quot;/fast/26&quot;&gt;available for the container&lt;/a&gt;, we can be even more
precise.&lt;/p&gt;

&lt;p&gt;Combining different pieces of information may also help us estimate headroom.
While job reshaping has substantial tried-and-true savings results to draw from,
plotting memory usage against load can let us deduce the fixed overheads of a
workload. An actual job reshape might save even more by improving cache
locality, but the estimate might be sufficient to guide prioritization.&lt;/p&gt;

&lt;h3 id=&quot;refactoring&quot;&gt;Refactoring&lt;/h3&gt;

&lt;p&gt;We may want to refactor the code to make the opportunity more clear in our
profiles. A small inline function adds no costs at runtime, but the debug
information that we add at build time allows us to disambiguate the costs in our
profile more easily.&lt;/p&gt;

&lt;p&gt;Consider a function that does some work and may take a lock to update shared
state afterwards. If we want to optimize lock contention, knowing where we spend
time under that lock can help us identify the functions we want to prioritize
for optimization.&lt;/p&gt;

&lt;h3 id=&quot;partial-prototyping&quot;&gt;Partial prototyping&lt;/h3&gt;

&lt;p&gt;A &lt;a href=&quot;/fast/72&quot;&gt;prototype&lt;/a&gt; that does not handle all edge cases can refine our
estimates of what a complete implementation will provide.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/fast/75&quot;&gt;Microbenchmarks&lt;/a&gt; can provide an estimate of how much faster we can
make a library. While we can make them arbitrarily complex and realistic, we are
likely better off &lt;a href=&quot;/fast/39&quot;&gt;moving to other methods&lt;/a&gt; or even production. We may
want to ask ourselves how a result will change our decision path:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Is a neutral result likely to suspend our work, or would we try to make the
microbenchmark “more realistic” by adding complexity?&lt;/li&gt;
  &lt;li&gt;Will we use the benchmark to fine tune the implementation? This can be
helpful for improving our OODA loop, but we risk overfitting due to its
pitfalls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another scenario we might encounter is that we have an implementation, but it
does not support all edge cases yet. These might lead to performance
regressions, or could be hard blockers due to correctness. With an
implementation that covers common use cases, we can run load tests to get a
sense of where an optimization works and by how much.&lt;/p&gt;

&lt;p&gt;A partial prototype can let us test our hypothesis. If we don’t see the expected
performance delta despite shortcuts, our initial estimate may have been overly
optimistic. If we do see a performance benefit (and it is &lt;a href=&quot;/fast/64&quot;&gt;correct&lt;/a&gt;),
we may be able to land it and iterate from there.&lt;/p&gt;

&lt;h3 id=&quot;partial-deployment-and-counterfactuals&quot;&gt;Partial deployment and counterfactuals&lt;/h3&gt;

&lt;p&gt;Counterfactual deployments can give us information in a lower-risk setting.
Consider a situation where we can use multiple compression algorithms. Making a
wholesale change to which algorithm we use in a system could be risky: We don’t
know whether the new ratio would be better or what its performance
characteristics are like.&lt;/p&gt;

&lt;p&gt;By choosing an alternative algorithm on a small sample of data and discarding
the actual compressed bytes, we can collect data about the performance of the
new algorithm. While this comes at a small runtime cost–double compression for
perhaps 1-in-1000 samples–that cost is low and only temporary.&lt;/p&gt;

&lt;h2 id=&quot;things-to-look-out-for&quot;&gt;Things to look out for&lt;/h2&gt;

&lt;p&gt;We want to avoid analysis paralysis. Carefully and precisely estimating every
possible idea before commencing work could keep us busy indefinitely.&lt;/p&gt;

&lt;p&gt;Many of these techniques are geared towards optimistic assumptions: We assume we
can address the entire market. While the “worst case” might be no improvement
that we land, we may want to scope where these scenarios can arise as well.&lt;/p&gt;

&lt;p&gt;Using multiple strategies for producing an estimate can give us increased
confidence in it. While we need to be cautious about anchoring bias and making a
catastrophic, common assumption, having two (or three) distinct approaches land
in the same ballpark can tell us that it might be a reasonable one.&lt;/p&gt;

&lt;p&gt;It is valuable to understand where numbers in prior estimates came from. For
example, if someone estimated a bottleneck could be improved by “10%”
out-of-thin-air, we shouldn’t anchor on that assumption indefinitely. The
improvement could be entirely correct–or entirely wrong–but we should
challenge the assumptions when comparing against our own analysis.&lt;/p&gt;

&lt;h2 id=&quot;calibrate&quot;&gt;Calibrate&lt;/h2&gt;

&lt;p&gt;After a project concludes, it’s useful to understand why our estimates were high
or low compared to how a &lt;a href=&quot;/fast/88&quot;&gt;project actually came in&lt;/a&gt;. There’s no right
or wrong answer here, so we don’t want to penalize ourselves for being wrong.
Our goal is to learn from our misses to improve our thought processes in the
future.&lt;/p&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing words&lt;/h2&gt;

&lt;p&gt;Judicious use of estimates can guide optimization work, allowing us to identify
the most impactful projects and design decisions.&lt;/p&gt;
</description>
          <pubDate>2025-02-06T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/90</link>
          <guid isPermaLink="true">https://abseil.io/fast/90</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #88: Measurement methodology: Avoid the jelly beans trap</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #88 on November 7, 2024&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:patrickx@google.com&quot;&gt;Patrick Xia&lt;/a&gt; and &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2024-11-18&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/88&quot;&gt;abseil.io/fast/88&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Measurement of performance optimizations often requires in-depth analysis due to
the inherent stochasticity of workloads. We need to gather data to calculate the
&lt;a href=&quot;/fast/70&quot;&gt;metrics we’ve selected&lt;/a&gt;. In this episode, we discuss the importance
of defining your measurement methodology ahead of time rather than fishing for
possible sources of significance after the data has been collected.&lt;/p&gt;

&lt;h2 id=&quot;choose&quot;&gt;Choose a methodology, without peeking&lt;/h2&gt;

&lt;p&gt;Choose &lt;em&gt;and publish&lt;/em&gt; a methodology before looking at the data. Ideally, this
process is completed before any changes land. It is otherwise easy to pick the
methodology that tells the best story (the “biggest number”) unwittingly after
the fact. Preregistration of experiment methodology also helps avoid false
positives in statistical analysis.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://xkcd.com/882/&quot;&gt;Jelly Beans XKCD comic&lt;/a&gt; offers a humorous take on
this situation, which is referred to alternately as
&lt;a href=&quot;https://en.wikipedia.org/wiki/Data_dredging&quot;&gt;data dredging or &lt;em&gt;p&lt;/em&gt;-hacking&lt;/a&gt;.
Even keeping this sort of situation in mind, data dredging remains a pernicious
problem. Less obvious data dredging can occur in many ways.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Prefer simpler methodologies. Simpler methodologies offer fewer parameters
to abuse and thus result in sounder analyses. Filters quickly combine to
form a similar effect as the green jelly beans from the comic. A statement
like “this performance optimization only has an effect during Australian
business hours” would be generally suspect.&lt;/li&gt;
  &lt;li&gt;Identify which metrics are
&lt;a href=&quot;/fast/70&quot;&gt;primary and which are secondary proxies&lt;/a&gt;. For example, if we ran
an A/B experiment, we might have &lt;a href=&quot;/fast/7&quot;&gt;multiple performance metrics&lt;/a&gt;
that we could consider. If we deferred making the choice of which metric to
use, we might find post hoc reasons for preferring one metric or the other.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Reuse measurement techniques when appropriate. While we shouldn’t shy away
from improving our techniques over time, reusing an approach reduces the
risk that we’ve overfit our analysis to the results.&lt;/p&gt;

    &lt;p&gt;If we are making a number of similar changes, we should generally strive for
measurement consistency across them.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Publish the observation interval of the analysis.
&lt;a href=&quot;https://en.wikipedia.org/wiki/Data_dredging#Optional_stopping&quot;&gt;Optional stopping&lt;/a&gt;
of experiments increases the risk of false positives. A sufficiently random
experiment that is run for an arbitrary amount of time will explore the
entire outcome space. Stopping the experiment when we reach that outcome
biases us towards finding a signal where there is none.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Precommit to a launch bar. For changes that add complexity, we want to be
cautious that the results merit the &lt;a href=&quot;/fast/9&quot;&gt;long-term cost&lt;/a&gt;. The error
bars for a very weakly positive result might overlap with zero.&lt;/p&gt;

    &lt;p&gt;If we’re removing complexity–deleting an unused calculation, cleaning up
dead flags, etc., we would likely be inclined to do so &lt;em&gt;anyway&lt;/em&gt; independent
of the efficiency savings that are merely a nice-to-have bonus.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Publishing the methodology also means that we have fewer chances to add
post-collection changes to analysis. Trivial-looking changes (“clearly errant
outlier data points can be deleted”) may negatively affect the soundness of
experiments.&lt;/p&gt;

&lt;h2 id=&quot;anchoring-bias&quot;&gt;Anchoring bias&lt;/h2&gt;

&lt;p&gt;Estimation is an important part of our &lt;a href=&quot;/fast/72&quot;&gt;project planning process&lt;/a&gt;. We
worked on particular optimizations because we think it was important enough to
be worth our time.&lt;/p&gt;

&lt;p&gt;When we read out the result of our hard work, we need to put our estimate aside
and not anchor on it. The estimate was intentionally rough. It only needed to be
“good enough” to break ties in our decision making to prioritize project A over
project B over project C.&lt;/p&gt;

&lt;p&gt;We should avoid scrutinizing a result simply because it differs from our prior
estimates and
&lt;a href=&quot;https://calteches.library.caltech.edu/51/2/CargoCult.htm#:~:text=We%20have%20learned,of%20a%20disease.&quot;&gt;results&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A lower-than-expected result might be from optimistic assumptions that we
made when estimating. Our “speed of light” for optimization might be that we
would fully eliminate the cost of something, but the result in practice
could be entirely different. To realize an earlier landing, we might have
carved out exceptions and edge cases, rather than fully tackling them.&lt;/li&gt;
  &lt;li&gt;A higher-than-expected result might come about from a missed consideration.
For example, when we enabled huge page-backed text, most of the upfront
focus was on iTLB pressure because the optimization had “text” in the name.
In practice, we also moved most of the executable’s constant global data
onto huge pages as well, producing a drop in dTLB misses as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While we want to have a good calibration for our estimates, we can learn from
the estimation mistakes as well. A “surprise” in either direction might indicate
an opportunity that we did not notice upfront.&lt;/p&gt;

&lt;p&gt;Nevertheless, extraordinary claims in either direction require extraordinary
evidence. Sometimes an optimization appears to have an impact many times larger
than we expect, or even than the apparent opportunity. Sometimes these are real
due to step functions in cost or non-linear behavior around lock contention.
More often, it is mismeasurement, and unexpectedly fortuitous results deserve
the extra scrutiny and cross-validation.&lt;/p&gt;

&lt;h2 id=&quot;follow-through-on-the-published-methodology&quot;&gt;Follow-through on the published methodology&lt;/h2&gt;

&lt;p&gt;After we have published a methodology, we should &lt;em&gt;actually follow that
methodology when reporting results&lt;/em&gt;. When going through the process of data
analysis, the data shape may look completely different than expectations. It is
important to obtain the results using the original methodology for posterity’s
sake even when this occurs. Future adjustments may refine a readout of the
impact of the project, but the number from the original methodology should still
be produced.&lt;/p&gt;

&lt;p&gt;It’s important to re-emphasize that we don’t anchor on the original estimate of
impact. The shape of the data may look different because previous estimates were
not accurate.&lt;/p&gt;

&lt;h2 id=&quot;post-measurement-adjustments&quot;&gt;Post-measurement adjustments&lt;/h2&gt;

&lt;p&gt;After analyzing the data, it may become clear that some part of the methodology
was lacking; for example, a confounding variable that was earlier not considered
may become apparent in the analyzed data. Adjustments at this stage are
incredibly prone to bias and statistical error, so additional caution is
mandatory. The null hypothesis of a neutral result is also a perfectly
acceptable result as well.&lt;/p&gt;

&lt;p&gt;When considering a potential confounder, we want to have a scientifically sound
mechanism to explain why we should include it. Suppose after we changed function
A, we saw an unexpected improvement in function B. We could update our analysis
to include the impact on function B, but we should be able to explain why we’re
not including functions C or D as well.&lt;/p&gt;

&lt;p&gt;The simplest criteria–all functions that use a particular data structure that
we modified–is a more sound one than cherry-picking an arbitrary set of
functions (e.g. all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; functions affecting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutable&lt;/code&gt; members). “We included
B because it improved and excluded C and D because they regressed” would be
suspicious. When adding more criteria after-the-fact, we should be able to
define them without peeking at the results from doing so.&lt;/p&gt;

&lt;p&gt;While convenient, longitudinal analysis can pick up truly unrelated confounders
from changes in usage:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Did another major optimization land to an application in the same release?&lt;/li&gt;
  &lt;li&gt;Did usage patterns for a library we were optimizing change?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tossing data points after the fact because they “seem irrelevant” or “due to
mix-shift” has a high bar. It’s very easy to bias our analysis by
disproportionately suppressing negative outliers.&lt;/p&gt;

&lt;p&gt;A/B experimentation takes more effort, but it can control for many of these
variables and mix-shifts by isolating a single independent variable. Ablating or
rolling back a change can also provide a compelling case for causality: If it
did cause the unanticipated changes we saw, those should revert back as well
with similar but reversed magnitude.&lt;/p&gt;

&lt;p&gt;Unanticipated improvements can be a source of future opportunities by
highlighting promising areas to look for more ideas, but this only works if the
improvements are real. If we fool ourselves into believing there was an
oversized effect, our follow-on projects may fail to pan out.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Committing to a measurement methodology ahead of time helps us preserve rigor
when we might otherwise fish for possible sources of significance after the data
has been collected.&lt;/p&gt;
</description>
          <pubDate>2024-11-18T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/88</link>
          <guid isPermaLink="true">https://abseil.io/fast/88</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #87: Two-way doors</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #87 on October 16, 2024&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-11-17&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/87&quot;&gt;abseil.io/fast/87&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jeff Bezos &lt;a href=&quot;https://www.youtube.com/watch?v=rxsdOQa_QkM&quot;&gt;divides decisions&lt;/a&gt;
between “one-way doors”–ones that are hard to reverse–and “two-way
doors”–those that are easy to reverse. Different optimizations fall on each
side of this divide. In this episode, we discuss patterns common to two-way
doors to reduce risk without exhaustively analyzing the situation. Good
decisions endure, while missteps can be corrected along the way.&lt;/p&gt;

&lt;h2 id=&quot;assessing-reversibility&quot;&gt;Assessing reversibility&lt;/h2&gt;

&lt;p&gt;As we explore a new optimization idea, we want to prioritize blockers to landing
and &lt;a href=&quot;/fast/72&quot;&gt;ignore (for now) less important details&lt;/a&gt;. This is easier said
than done, since we need to figure out which subproblems are actually on our
critical path and those which can be ignored.&lt;/p&gt;

&lt;p&gt;Outside of major technical blockers–does a proposed optimization work at all,
or to a sufficient degree to be meaningful–an important consideration is which
decisions we need to make upfront because they are hard to change later. We
approach this with a strong prior that &lt;em&gt;most&lt;/em&gt; software decisions are easy to
reverse, but discuss the hallmarks of those that are harder to.&lt;/p&gt;

&lt;h2 id=&quot;feature-flags&quot;&gt;Feature flags&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#continuous_delivery-id00035&quot;&gt;Feature flags&lt;/a&gt;
are a common technique for gating new functionality so that it can be developed
and gradually tested before being rolled out. If an issue is recognized with a
release, the flag update can be rolled back and the system restored to the
previous, good known state.&lt;/p&gt;

&lt;p&gt;Broadly speaking, fine-grained flag changes are easy to undo and thus two-way
doors. The system was working before and we can go back to the drawing board, if
and when a problem arises, to remedy it if we need to rollback.&lt;/p&gt;

&lt;p&gt;Flags aren’t all equally important: A flag to launch (or turn down) a major
product feature is far more weighty than a flag that controls the size of a
cache as part of an optimization. Flags gating major product features, however,
undergo far more consideration as part of the
&lt;a href=&quot;https://sre.google/sre-book/reliable-product-launches/&quot;&gt;launch process&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;apis&quot;&gt;APIs&lt;/h2&gt;

&lt;p&gt;Unlike flags where we can make a central decision to roll forward or roll back a
particular setting and even adopt application-specific values (at least
&lt;a href=&quot;/fast/52&quot;&gt;temporarily&lt;/a&gt;), new API surfaces can prove to be more of a one-way
door at times.&lt;/p&gt;

&lt;p&gt;While a new library is being developed, a build visibility rule might help
constrain adoption to a manageable set of users. This can provide invaluable
feedback on the ergonomics of the library and further battletesting while
leaving things in a tractable enough state to “undo” later and migrate away from
it.&lt;/p&gt;

&lt;p&gt;For optimization projects, we might consider how impact scales with adoption.
For example, adopting RCU might get most of its benefits from tackling a handful
of the most contended data structures, but a
&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2125r0.pdf&quot;&gt;vocabulary type&lt;/a&gt;
like SwissMap might need thousands of usages to get meaningful traction. For
SwissMap, nearly
&lt;a href=&quot;https://abseil.io/docs/cpp/guides/container&quot;&gt;drop-in API compatibility&lt;/a&gt; makes a
hypothetical rollback possible, whether by changing usage or by making the
implementation a wrapper for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt;. SwissMap makes strictly fewer
guarantees with respect to actually being unordered and iterator/pointer
stability, so it could be easily substituted for the existing implementation.&lt;/p&gt;

&lt;p&gt;At the other end of the spectrum are new programming paradigms. While a simple
API might be possible to decompose in terms of other libraries, moving back and
forth between coroutines and other asynchronous primitives might be challenging
at the very least.&lt;/p&gt;

&lt;p&gt;Similar considerations apply to releasing open source libraries: Having internal
experience first, where it’s possible to talk to every user and
&lt;a href=&quot;https://research.google/pubs/why-google-stores-billions-of-lines-of-code-in-a-single-repository/&quot;&gt;update them&lt;/a&gt;
as needed, can provide needed confidence that rough edges have been sanded down.
Once released, &lt;a href=&quot;https://abseil.io/about/compatibility&quot;&gt;compatibility guarantees&lt;/a&gt;
might make it more challenging to make substantial changes without breaking
existing users.&lt;/p&gt;

&lt;h2 id=&quot;data-at-rest-versus-data-in-flight&quot;&gt;Data at rest versus data in flight&lt;/h2&gt;

&lt;p&gt;Data formats that only live “in flight,” for example, during an active RPC, face
far different reversibility considerations than data that lives at rest, for
example, if stored to disk.&lt;/p&gt;

&lt;p&gt;Protocol buffers serve both of these roles by joining an in-memory
representation to a wire format.&lt;/p&gt;

&lt;p&gt;If we change an implementation detail of the in-memory format, whether by
optimizing our parsing routines or changing how we lay out fields, we can
improve efficiency without long-term ramifications. The data is “in flight” and
the layout doesn’t have to be consistent or compatible with future (or past)
binaries.&lt;/p&gt;

&lt;p&gt;When we look at the wire format, some data will be serialized, sent over the
network, and immediately decoded by another server. If we were to introduce a
new wire format, we might consider negotiating this new version and &lt;em&gt;only if&lt;/em&gt;
both ends of the connection supported it, use the new format instead. This
transition period of limiting ourselves to “in flight” data gives us a series of
breadcrumbs to follow for undoing it: We can stop negotiating the new format and
phase it out if we need to.&lt;/p&gt;

&lt;p&gt;Once this data is persisted to disk where it becomes “at rest” data, we face a
different set of considerations: We need to be able to read that data for as
long as it is useful. Practically speaking, this might be “forever” if we cannot
centrally transcode formats.&lt;/p&gt;

&lt;h2 id=&quot;experimentation&quot;&gt;Experimentation&lt;/h2&gt;

&lt;p&gt;In their &lt;a href=&quot;/fast/52&quot;&gt;ideal lifecycle&lt;/a&gt;, feature flags aid the rollout of features
and then are removed when we get to complete adoption. One challenge might be
where a new feature introduces drastically different tradeoffs between
applications, for example, one that saves CPU but causes some applications to
use more RAM. While it might be &lt;a href=&quot;/fast/79&quot;&gt;best to avoid this altogether&lt;/a&gt; or to
self-tune, these still might be desirable optimizations.&lt;/p&gt;

&lt;p&gt;Experiments can help us dip our toe into the waters of a change while still
allowing us to centrally roll things back. By making the change over a small
slice of each application, we can avoid “getting stuck” in a half-way state
between some users having the new feature and others not. Even if the change is
very beneficial for some users who might be hesitant to see it rolled back, the
narrow slice minimizes how sticky it might be. This can allow us to fine-tune
things to sandblast away the roughest parts of the tradeoff.&lt;/p&gt;

&lt;h2 id=&quot;dark-and-counterfactual-launches&quot;&gt;Dark and counterfactual launches&lt;/h2&gt;

&lt;p&gt;A distinct kind of running experimental functionality in production is to enable
it in parallel with the status quo in dark launch. For example, to consider
different compression algorithms, we can compress a small fraction of the data
using experimental settings, discarding it. Comparing this counterfactual data
with the still-enabled primary compression algorithm we can choose the best
settings for the given application. This approach isn’t always applicable–for
example, we can’t use it for decompression–but when it works it is a useful
tool in higher-risk scenarios such as experimenting with data-at-rest.&lt;/p&gt;

&lt;h2 id=&quot;latency-injection-and-slo-brownouts&quot;&gt;Latency injection and SLO brownouts&lt;/h2&gt;

&lt;p&gt;Systems sometime underpromise on SLOs and overdeliver on actual performance.
This can make it challenging to determine whether higher-level services depend
on the better-than-promised performance characteristics.&lt;/p&gt;

&lt;p&gt;To mitigate this, one approach is to implement intentional
&lt;a href=&quot;https://sre.google/sre-book/service-level-objectives/&quot;&gt;brownouts&lt;/a&gt; for a
service. For example, Chubby did that in the past for its global instance,
ensuring that users experienced the letter of the SLO, allowing infeasible
dependencies to be uncovered in a controlled manner.&lt;/p&gt;

&lt;p&gt;Similarly, injecting latency can allow us to simulate a slower implementation,
which we might consider as part of a tradeoff of compute for other resources. An
implementation to add latency is straightforward to build and easy to turn on
and off.&lt;/p&gt;

&lt;p&gt;By handling this in a controlled setting, we can rapidly turn off the injection
experiment or availability brownout if we uncover downstream issues. This can
help mitigate the risk of building on the assumption that a particular tradeoff
was possible, only to discover a late-arrising issue partway through a large
scale rollout.&lt;/p&gt;

&lt;h2 id=&quot;handling-bugs-and-regressions&quot;&gt;Handling bugs and regressions&lt;/h2&gt;

&lt;p&gt;Bugs, regressions, and outages are never fun, but they are inevitable as the
system changes, whether intentionally (code updates) or unintentionally
(workloads shift). The goal isn’t to get to
&lt;a href=&quot;https://sre.google/sre-book/embracing-risk/&quot;&gt;zero risk&lt;/a&gt;, but instead is to
manage it. The possibility of a bug does not make the door one-way.&lt;/p&gt;

&lt;p&gt;Regardless of the type of change we’re making, we still need to do testing,
&lt;a href=&quot;https://sre.google/sre-book/service-best-practices/&quot;&gt;progressive rollouts&lt;/a&gt;, and
monitoring to look for issues. When we are trying to decide how to proceed, we
should aim for how additional flight miles can let us gain new information to
make progress, since no amount of analysis will ever completely derisk things.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Thinking about how reversible decisions are can help avoid analysis paralysis.
Many software decisions are easily reversed, allowing us to mitigate the risk of
regressions from changes and to shift our focus onto the more consequential
decisions.&lt;/p&gt;
</description>
          <pubDate>2024-11-08T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/87</link>
          <guid isPermaLink="true">https://abseil.io/fast/87</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #234: Pass by Value, by Pointer, or by Reference?</title>
          <description>&lt;p&gt;Originally posted as TotW #234 on August 29, 2024&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:wangsteve@google.com&quot;&gt;Steve Wang&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2024-09-30&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/234&quot;&gt;abseil.io/tips/234&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;p&gt;Many programming languages, such as Java and Python, always access objects via
references, and functions that accept objects get their own reference to the
caller’s object. Others, such as C and Go, allow you to explicitly specify
pointers to objects. C++ further allows you to choose whether to pass by value,
giving the called function a copy of the argument, or to pass by reference,
giving the called function access to the caller’s object. This tip will
illustrate the various ways input-only function parameters are passed in C++ and
provide recommendations and caveats.&lt;/p&gt;

&lt;p&gt;When we talk about passing by value, we explicitly mean that the language
ensures that the scope of the function call has an exclusive copy of its
argument[^elision]. Reassigning a new value to this variable does not mutate the
corresponding object in the caller’s scope. However, invoking the argument’s
methods may still mutate its underlying state.&lt;/p&gt;

&lt;p&gt;Meanwhile, when we talk about passing by reference, we effectively bring the
object from the caller’s scope into the current function’s scope, and
reassignment will mutate the underlying object.&lt;/p&gt;

&lt;p&gt;Passing by pointer has some similarities to passing by reference, yet is
technically a special case of pass-by-value, as the pointer itself is a value
that corresponds to the address of the underlying object (or a null pointer,
which refers to no object at all).&lt;/p&gt;

&lt;p&gt;Consider the following:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void AddOneToValue(int x) {
  ++x;
}

void AddOneToReference(int&amp;amp; x) {
  ++x;
}

// Here, the pointer points at a &quot;pointee&quot;; we&apos;re adding one to the
// pointed-at object.
void AddOneToPointee(int* x) {
  ++*x;
}

...

int x = 5;
AddOneToValue(x);
// x is still 5.
AddOneToReference(x);
// x is now 6.
AddOneToPointee(&amp;amp;x);
// x is now 7.
&lt;/pre&gt;

&lt;p&gt;As a result, when writing functions in C++, the language makes us consider how
to pass parameters – should we pass by value, by pointer, by reference (if so,
which kind)?&lt;/p&gt;

&lt;h2 id=&quot;why-do-we-care-about-passing-by-value&quot;&gt;Why Do We Care About Passing by Value?&lt;/h2&gt;

&lt;p&gt;The astute reader might wonder what the issues are with always passing by
reference. First off, having unnecessary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt; (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Add(const int&amp;amp; a,
const int&amp;amp; b)&lt;/code&gt;) adds visual clutter.&lt;/p&gt;

&lt;p&gt;Second, in C++, as mentioned above, a reference is largely syntactic sugar for a
pointer[^const_ref], with the associated overhead of a memory lookup when we
want to use it unless the compiler is able to optimize that away. By passing
small types by value, we can pass them in registers instead of needing to store
them on the stack.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Passing a small value by value, the compiler can avoid a stack allocation and
// pass it in a register.
int foo = 5;
Bar(foo);

// However, passing a small value by reference requires `foo` to be copied
// (&quot;spilled&quot;) to the stack since you can&apos;t take the address of a register.
int foo = 5;
Bar(&amp;amp;foo);
&lt;/pre&gt;

&lt;p&gt;Of course, if the variable is already on the stack or heap (e.g., it’s part of
an array) then this concern is irrelevant, but we should still prefer to pass by
value to avoid some cache misses and memory pressure if it’s already loaded in a
register.&lt;/p&gt;

&lt;p&gt;Regardless, references can further introduce concerns regarding
&lt;em&gt;aliasing&lt;/em&gt;[^aliasing] – since the function does not have an exclusive copy of
the object, we have no guarantees that the object will remain unchanged
throughout the lifetime of the function, even if we have a reference-to-const
(which is only a promise that we will not mutate it &lt;em&gt;through that particular
parameter&lt;/em&gt;).&lt;/p&gt;

&lt;h2 id=&quot;why-do-we-care-about-passing-by-reference&quot;&gt;Why Do We Care About Passing by Reference?&lt;/h2&gt;

&lt;p&gt;On the opposite end of the spectrum, one might wonder why we don’t just pass all
input parameters by value.&lt;/p&gt;

&lt;p&gt;In C++, if you pass a variable by value, depending on how the function is called
the variable’s value may be copied or moved (or neither)[^names]. On the other
hand, passing by reference (or pointer) allows you to refer to an existing
object and therefore avoid a copy entirely. So, in general, the larger an
object, the more you should prefer passing by reference.&lt;/p&gt;

&lt;p&gt;Passing by value can have benefits as well as drawbacks from the perspective of
memory safety. On one hand, if you have the only copy of an object, then you
don’t have to worry about other threads stomping over its state. On the other
hand, if you retain a reference to this object, once it goes out of scope, then
you have a use-after-free bug (just as for any other local variable).&lt;/p&gt;

&lt;h2 id=&quot;guidelines&quot;&gt;Guidelines&lt;/h2&gt;

&lt;p&gt;All of these rules apply equally. If none of them apply, a safe option is to
pass by reference-to-const for required parameters, and by pointer for optional
ones.&lt;/p&gt;

&lt;h3 id=&quot;pass-by-value&quot;&gt;Pass by Value&lt;/h3&gt;

&lt;p&gt;Passing by value can be more &lt;em&gt;efficient&lt;/em&gt; in some cases (when the relevant types
are small enough that moving or copying them is more efficient than working via
pointers), and is helpful for conveying ownership (typically when the called
function wants to own the value, to move from it, or to otherwise modify its own
copy).&lt;/p&gt;

&lt;p&gt;Specifically, the types listed below should usually be passed by value:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Numeric and enumeration types (including protobuf enums).&lt;/li&gt;
  &lt;li&gt;Smart pointers, when the called function takes ownership unconditionally.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some additional types can be efficiently passed by value, as an optimization:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Types that provide an efficient move constructor, &lt;strong&gt;only if the called
function needs its own copy of the value&lt;/strong&gt;. Examples include
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&amp;lt;T&amp;gt;&lt;/code&gt; and other
containers that don’t store their contents inline[^proto_move].&lt;/p&gt;

    &lt;p&gt;In these cases, you should pass by value, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move&lt;/code&gt; at the callsite
when needed (or pass in a temporary which is subject to mandatory copy
elision per &lt;a href=&quot;/tips/166&quot;&gt;Tip #166&lt;/a&gt;). See &lt;a href=&quot;/tips/117&quot;&gt;Tip #117&lt;/a&gt; for
supplemental reading on copy elision and pass-by-value.&lt;/p&gt;

    &lt;p&gt;Passing by value is especially common in a constructor that stores one of
these types in a member variable.&lt;/p&gt;

    &lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Foo {
  public:
    // Here, we pass bar by reference and copy it into bar_.
    Foo(const std::vector&amp;lt;int&amp;gt;&amp;amp; bar) : bar_(bar) {}

    // But, we can instead use std::vector&apos;s move constructor to avoid
    // the expensive copy entirely, in some cases.
    Foo(std::vector&amp;lt;int&amp;gt; bar) : bar_(std::move(bar)) {}
  private:
    std::vector&amp;lt;int&amp;gt; bar_;
};
&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;, where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(T) &amp;lt;= 16&lt;/code&gt;&lt;sup id=&quot;fnref:abi&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:abi&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is either a scalar type such as
an integer or a pointer type, or a class[^calls] such that:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;It has a non-deleted copy constructor or move constructor.&lt;/li&gt;
      &lt;li&gt;All copy and move operations are trivial – one requirement is that they
must either be omitted or explicitly defaulted (&lt;a href=&quot;/tips/131&quot;&gt;Tip #131&lt;/a&gt;).&lt;/li&gt;
      &lt;li&gt;The destructor is trivial and non-deleted.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;For types that your team does not own[^hyrum], you should only rely on this
behavior if they explicitly document that they should be passed by value,
such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spanner::Database&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Duration&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;T&amp;gt;&lt;/code&gt;, where passing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; by value applies.&lt;/p&gt;

    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;T&amp;gt;&lt;/code&gt; adds some size overhead compared to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;, which further
limits the types that can be passed by value efficiently. So, for instance,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;std::span&amp;lt;U&amp;gt;&amp;gt;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;absl::string_view&amp;gt;&lt;/code&gt; are too
big, as each of these wrapped types is 16 bytes before accounting for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt;’s overhead.&lt;/p&gt;

    &lt;p&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(std::optional&amp;lt;T&amp;gt;) &amp;gt; 16&lt;/code&gt;, or if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; has a nontrivial copy
constructor, then prefer passing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Nullable&amp;lt;const T*&amp;gt;&lt;/code&gt;
(&lt;a href=&quot;/tips/163&quot;&gt;Tip #163&lt;/a&gt;), and use a null pointer to represent the case that
would otherwise be captured by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::nullopt&lt;/code&gt;.&lt;/p&gt;

    &lt;p&gt;Note that &lt;a href=&quot;/tips/163&quot;&gt;Tip #163&lt;/a&gt; applies here – if all callers will always
have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;T&amp;gt;&lt;/code&gt;, then you may pass by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&amp;amp;&lt;/code&gt;.&lt;/p&gt;

    &lt;p&gt;Do not use this idiom with smart pointers or other types that have a
representation for “no value”. For instance, do not write
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;std::unique_ptr&amp;lt;U&amp;gt;&amp;gt;&lt;/code&gt;; instead, prefer to use
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;U&amp;gt;&lt;/code&gt; directly, and pass a null pointer to represent “no
value”.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;pass-by-reference-or-by-pointer&quot;&gt;Pass by Reference or by Pointer&lt;/h3&gt;

&lt;p&gt;Note: If an argument &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; in a call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(x)&lt;/code&gt; is required to outlive the function
call,
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs&quot;&gt;do not pass it by reference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The types listed below should usually be passed by reference (for required
parameters) or by pointer (for optional parameters).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Smart pointers (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;T&amp;gt;&lt;/code&gt;) where you don’t want to transfer
ownership: dereference the smart pointer to pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt; if the
pointed-at value is always known (and required) to be non-null; else pass
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Nullable&amp;lt;const T*&amp;gt;&lt;/code&gt; (&lt;a href=&quot;/tips/188&quot;&gt;Tip #188&lt;/a&gt;).&lt;/p&gt;

    &lt;p&gt;In cases of shared ownership[^shared_ptr] where you only &lt;em&gt;sometimes&lt;/em&gt; want to
take ownership, you may want to pass a reference to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::shared_ptr&lt;/code&gt; to
avoid the slight overhead of updating reference counts.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Containers that store their contents inline, e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::array&amp;lt;T, N&amp;gt;&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InlinedVector&amp;lt;T, N&amp;gt;&lt;/code&gt;.&lt;/p&gt;

    &lt;p&gt;While &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::array&amp;lt;T, N&amp;gt;&lt;/code&gt; can be efficient to pass by value if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(T) * N
&amp;lt;= 16&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InlinedVector&amp;lt;T, N&amp;gt;&lt;/code&gt; has a non-trivial copy constructor and
thus will never be passed in a register.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Types with non-trivial copy constructors, where you don’t intend to use move
semantics.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Protocol buffers.&lt;/p&gt;

    &lt;p&gt;You might think that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Duration&lt;/code&gt; type defined by&lt;/p&gt;

    &lt;pre class=&quot;prettyprint code&quot;&gt;
edition = &quot;2023&quot;;

message Duration {
  int64 seconds = 1;
  int32 nanos = 2;
}
&lt;/pre&gt;

    &lt;p&gt;only contains an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64&lt;/code&gt; (8 bytes) and an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int32&lt;/code&gt; (4 bytes) and is therefore
12 bytes (padded out to 16 bytes), but that’s not correct because protobufs
may have a vtable pointer (8 bytes) or other metadata. Additionally, you
shouldn’t pass protos by value by default (even if they don’t have many
fields) because they do not promise that they can be trivially copied (and
in practice they usually cannot).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;pass-a-view-by-value&quot;&gt;Pass a View (by Value)&lt;/h3&gt;

&lt;p&gt;For some types, a corresponding &lt;em&gt;view&lt;/em&gt; type – a type that gives read-only
access to the underlying data, and might support various different underlying
types – can be a good way to accept inputs to a function that does not need its
own copy of those inputs.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;For functions accepting a string argument, whether as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt;, defining the parameter as an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; is efficient and supports all of these inputs types (see
&lt;a href=&quot;/tips/179&quot;&gt;Tip #179&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;For functions accepting a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;T&amp;gt;&lt;/code&gt;, defining the parameter as an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Span&amp;lt;const T&amp;gt;&lt;/code&gt; is more efficient and more flexible (see
&lt;a href=&quot;/tips/93&quot;&gt;Tip #93&lt;/a&gt;), though using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::vector&amp;lt;T&amp;gt;&amp;amp;&lt;/code&gt; can be a
reasonable choice if constraints make &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Span&lt;/code&gt; impractical.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;For functions that accept a callable object, such as a lambda, we can choose
between defining a function parameter as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const Fn&amp;amp;&lt;/code&gt; (where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fn&lt;/code&gt; is a
template parameter) or as a type-erased callable such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::FunctionRef&lt;/code&gt;
(see &lt;a href=&quot;/tips/145&quot;&gt;Tip #145&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing Words&lt;/h2&gt;

&lt;p&gt;While passing function parameters by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&amp;amp;&lt;/code&gt; is a good default choice, there
are plenty of cases where it’s not the best option. The guidelines in this tip
can help to weigh the relevant factors and design safe and efficient APIs.&lt;/p&gt;

&lt;p&gt;We want to emphasize that they are just guidelines, though, and if you have good
reason to deviate from these (e.g., benchmarking or profiling identifies
potential performance gains), we encourage you to do so (and to document your
rationale for the next reader).&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:abi&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;In typical Google production environments, namely x86-64 Linux. See
section 3.2.3 of the
&lt;a href=&quot;https://gitlab.com/x86-psABIs/x86-64-ABI&quot;&gt;ELF x86-64 ABI spec&lt;/a&gt;.
&lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#parameter-passing&quot;&gt;On Windows&lt;/a&gt;,
only types that are 8 bytes or fewer are passed in registers.
[^aliasing]: In best-case scenarios, pointer aliasing prevents the compiler from
making certain optimizations. In worst-case scenarios, pointer
aliasing can result in violated preconditions, logic bugs, and
buffer overflows.
[^calls]: Formally, this class must not be “non-trivial for the purpose of
calls”. This is very similar, but not quite identical, to a trivially
copyable class in C++. See the
&lt;a href=&quot;https://itanium-cxx-abi.github.io/cxx-abi/abi.html&quot;&gt;ABI specification&lt;/a&gt;
for the formal definition of this term.
[^const_ref]: const-references are somewhat more complex – for one, they can
bind to temporaries. Further, references cannot be null, so we
generally recommend passing references instead of pointers for
required input parameters that don’t need to outlive the function
call.
[^elision]: This does not necessarily mean that the function creates a separate
copy of its argument, as &lt;a href=&quot;/tips/166&quot;&gt;copy elision&lt;/a&gt; may have taken
place.
[^hyrum]: While it can be more efficient to pass small types by value, you may
accidentally make it harder to add new fields to those types or
otherwise change the internal representation (see go/hyrums-law),
since you’re adding an implicit dependency on the size of the type, as
well as on the constructors and destructors that it defines.
[^names]: To a first approximation, this results in a copy when you pass in a
named object (such as a non-reference stack variable or data member).
&lt;a href=&quot;/tips/166&quot;&gt;Tip #166&lt;/a&gt; covers this in more detail.
[^proto_move]: Protocol buffers also define a move constructor that is usually
comparable to a shallow copy – the exception is if you’re moving
between two messages that live on different arenas, or between a
heap-allocated message and an arena-allocated message, in which
case it is comparable to a deep copy.
go/proto-cpp-arena-allocation#message-class-methods has more
details.
[^shared_ptr]: As stated in the
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Ownership_and_Smart_Pointers&quot;&gt;style guide&lt;/a&gt;,
shared ownership should only be used with good reason, and not as
a way to avoid thinking about object lifetimes. &lt;a href=&quot;#fnref:abi&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
          <pubDate>2024-09-30T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/234</link>
          <guid isPermaLink="true">https://abseil.io/tips/234</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #232: When to Use &lt;code&gt;auto&lt;/code&gt; for Variable Declarations</title>
          <description>&lt;p&gt;Originally posted as TotW #232 on June 20, 2024&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:kinoue@google.com&quot;&gt;Kenji Inoue&lt;/a&gt; and Michael Diamond, Google Engineer&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2024-09-30&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/232&quot;&gt;abseil.io/tips/232&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The style guide says in the
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Type_deduction&quot;&gt;Type Deduction (including auto)&lt;/a&gt;
section:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Use type deduction only if it makes the code clearer to readers who aren’t
familiar with the project, or if it makes the code safer. Do not use it merely
to avoid the inconvenience of writing an explicit type.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ironically, overuse of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; often leads to code becoming less clear. Over
time, however, several patterns have emerged where using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; can improve code
clarity and safety, such as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In situations where specifying the type correctly can be difficult and
specifying the wrong type can lead to performance or correctness issues,
e.g., range-based &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loops over a map.&lt;/li&gt;
  &lt;li&gt;In situations where the type information is truly redundant and
specification of the full type is distracting, e.g., commonly-used templated
factory functions and some iterator uses.&lt;/li&gt;
  &lt;li&gt;In generic code where the type itself is not important as long as it is
syntactically correct.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll discuss each of those cases below, with an eye toward clarifying the cases
in which &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; makes code safer or clearer.&lt;/p&gt;

&lt;h2 id=&quot;range-based-for-loops-over-a-map&quot;&gt;Range-Based For Loops Over a Map&lt;/h2&gt;

&lt;p&gt;The following code has a problem that each element in the map is unintentionally
copied:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
absl::flat_hash_map&amp;lt;std::string, DogBreed&amp;gt; dog_breeds_by_name = ...;
// `name_and_breed` is copy-constructed for each element of the map.
for (const std::pair&amp;lt;std::string, DogBreed&amp;gt;&amp;amp; name_and_breed :
     dog_breeds_by_name) {
  ...
}
&lt;/pre&gt;

&lt;p&gt;The unintended copy happens because the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_type&lt;/code&gt; of associative containers
is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair&amp;lt;const Key, Value&amp;gt;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair&lt;/code&gt; allows implicit conversions
between pair objects if their underlying types can be implicitly converted.
Because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair::first_type&lt;/code&gt; here is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; and the map entry here has
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair::first_type&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::string&lt;/code&gt;, the pairs are not the same type
and an implicit conversion occurs, copying the contents of the pair despite
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name_and_breed&lt;/code&gt; being declared as a reference.&lt;/p&gt;

&lt;p&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt;, possibly in conjunction with structured bindings
(&lt;a href=&quot;/tips/169&quot;&gt;Tip #169&lt;/a&gt;), can make the code safer and more performant:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
absl::flat_hash_map&amp;lt;std::string, DogBreed&amp;gt; dog_breeds_by_name = ...;

// `auto` with structured bindings - if the element types are clear from local
// context.
for (const auto&amp;amp; [name, breed] : dog_breeds_by_name) {
  ...
}
&lt;/pre&gt;

&lt;p&gt;Sometimes, the element types are not obvious from local context. In that case,
you can do this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// `auto` without structured bindings - allows specifying the element types.
for (const auto&amp;amp; name_and_breed : dog_breeds_by_name) {
  const std::string&amp;amp; name = name_and_breed.first;
  const DogBreed&amp;amp; breed = name_and_breed.second;
  ...
}
&lt;/pre&gt;

&lt;h2 id=&quot;iterators&quot;&gt;Iterators&lt;/h2&gt;

&lt;p&gt;The names of iterator types are verbose and often provide redundant type
information when the type of the container is visible nearby.&lt;/p&gt;

&lt;p&gt;Here is an example code snippet that assigns an iterator to a local variable.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::vector&amp;lt;std::string&amp;gt; names = ...;
std::vector&amp;lt;std::string&amp;gt;::iterator name_it = names.begin();
while (name_it != names.end()) {
  ...
}
&lt;/pre&gt;

&lt;p&gt;All containers expose &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;begin()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;end()&lt;/code&gt; functions which return iterators,
and these iterators have type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContainerType::iterator&lt;/code&gt; or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContainerType::const_iterator&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When the type of the container is visible nearby, calling out these types would
only have a small benefit of differentiating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iterator&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const_iterator&lt;/code&gt;
because the container type part (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;std::string&amp;gt;&lt;/code&gt;) is the same
as that of the container. In this case, we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; to remove redundancy
without hiding helpful information:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::vector&amp;lt;std::string&amp;gt; names = ...;
auto name_it = names.begin();
while (name_it != names.end()) {
  ...
}
&lt;/pre&gt;

&lt;p&gt;When the container type is not visible locally, prefer to spell out the full
iterator type or element type:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::vector&amp;lt;std::string&amp;gt;::iterator name_it = names_.begin();
while (name_it != names_.end()) {
  ...
}
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
auto name_it = names_.begin();
while (name_it != names_.end()) {
  const std::string&amp;amp; name = *name_it;
  ...
}
&lt;/pre&gt;

&lt;h2 id=&quot;stdmake_unique-and-other-google-wide-factory-functions&quot;&gt;&lt;code&gt;std::make_unique&lt;/code&gt; and Other Google-wide Factory Functions&lt;/h2&gt;

&lt;p&gt;In the following code snippet, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proto2::MakeArenaSafeUnique&lt;/code&gt; specify the types to be instantiated.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::unique_ptr&amp;lt;MyFavoriteType&amp;gt; my_type =
    std::make_unique&amp;lt;MyFavoriteType&amp;gt;(...);

proto2::ArenaSafeUniquePtr&amp;lt;MyFavoriteProto&amp;gt; my_proto =
    proto2::MakeArenaSafeUnique&amp;lt;MyFavoriteProto&amp;gt;(arena);
&lt;/pre&gt;

&lt;p&gt;It is widely known throughout Google that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&amp;lt;T&amp;gt;&lt;/code&gt; returns
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proto2::MakeArenaSafeUnique&amp;lt;T&amp;gt;&lt;/code&gt; returns
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proto2::ArenaSafeUniquePtr&amp;lt;T&amp;gt;&lt;/code&gt;. In particular, the important part of the
resulting type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is specified on the right-hand side (RHS) expression, and it
is company-wide knowledge rather than project-specific knowledge. We can use
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; here to remove redundancy without hiding helpful information:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
auto my_type = std::make_unique&amp;lt;MyFavoriteType&amp;gt;(...);

auto my_proto = proto2::MakeArenaSafeUnique&amp;lt;MyFavoriteProto&amp;gt;(arena);
&lt;/pre&gt;

&lt;h2 id=&quot;generic-code&quot;&gt;Generic Code&lt;/h2&gt;

&lt;p&gt;In some circumstances when writing generic code, such as templates or GoogleTest
matchers, the type may be impossible or very difficult to specify (e.g., a type
written with template metaprogramming or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;decltype&lt;/code&gt;). In these cases &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; may
also be appropriate. However, these situations should be rare.&lt;/p&gt;

&lt;h2 id=&quot;otherwise-avoid-using-auto&quot;&gt;Otherwise: Avoid Using &lt;code&gt;auto&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;While it can be tempting to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; in situations where the type is long and
seems obvious to &lt;em&gt;you&lt;/em&gt;, remember that future readers of the code may not be
familiar with your project and the types it uses
(&lt;a href=&quot;http://go/readability#why&quot;&gt;why&lt;/a&gt;). For example, consider a common pattern of
nested proto access.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// Of course `breed` has type `const DetailedDomesticCatBreed&amp;amp;`!
const auto&amp;amp; breed = cat.pedigree().detailed_breed();
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; may also hide basic semantics like constness, whether a type is a
pointer, and whether a copy is being made (&lt;a href=&quot;/tips/44&quot;&gt;Tip #44&lt;/a&gt;).&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// Did the author mean to make a copy here?
// It is not obvious to all readers that `breed` is not a reference even though
// `detailed_breed()` returns a reference!
auto breed = cat.pedigree().detailed_breed();
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Type and semantics are clear.
const DetailedDomesticCatBreed&amp;amp; breed = cat.pedigree().detailed_breed();
&lt;/pre&gt;

&lt;h2 id=&quot;summary-of-recommendations&quot;&gt;Summary of Recommendations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; when manually writing out a more specific type would incur a high
risk of correctness or performance problems.&lt;/li&gt;
  &lt;li&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; to remove redundancy without hiding helpful information when the
useful type information is visible locally.&lt;/li&gt;
  &lt;li&gt;For some generic code where the type is impossible or very difficult to
specify, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; may be appropriate; these situations should be rare.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Avoid using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; in other situations&lt;/strong&gt;: while it may make it easier for
you to write the code or allow you to avoid a line-break, it probably makes
the code harder to understand for someone unfamiliar with your project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;see-also&quot;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;https://google.github.io/styleguide/cppguide.html#auto for the authoritative
guidance&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/4&quot;&gt;Tip #4&lt;/a&gt;: Tip of the Week #4: Automatic for the People&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/44&quot;&gt;Tip #44&lt;/a&gt;: Tip of the Week #44: Qualifying auto&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2024-09-30T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/232</link>
          <guid isPermaLink="true">https://abseil.io/tips/232</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #231: Between Here and There: Some Minor Overlooked Algorithms</title>
          <description>&lt;p&gt;Originally posted as TotW #231 on March 7, 2024&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;James Dennett&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2024-09-30&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/231&quot;&gt;abseil.io/tips/231&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;p&gt;In recent C++ versions the Standard Library has added a few functions whose sole
job is to supply some (specific!) point somewhere between two other points &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;: &lt;a href=&quot;https://en.cppreference.com/w/cpp/algorithm/clamp&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp&lt;/code&gt;&lt;/a&gt; (from
C++17), and
&lt;a href=&quot;https://en.cppreference.com/w/cpp/numeric/midpoint&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::midpoint&lt;/code&gt;&lt;/a&gt; and
&lt;a href=&quot;https://en.cppreference.com/w/cpp/numeric/lerp&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp&lt;/code&gt;&lt;/a&gt; (from C++20).&lt;/p&gt;

&lt;p&gt;Adding these function templates to the Standard Library serves two main
purposes. First, it establishes common terminology (vocabulary) for these
operations, that is likely to be widely recognized. Second, and particularly in
the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::midpoint&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp&lt;/code&gt;, it ensures the availability of high
quality implementations that
&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0811r3.html&quot;&gt;avoid common pitfalls&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All of these operations are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt;, meaning that they can be used both at
runtime and at compile time. The types that can be passed to them depend on the
specific operation; they all support floating point types, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::midpoint&lt;/code&gt;
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp&lt;/code&gt; offer additional flexibility. Read on for the details.&lt;/p&gt;

&lt;h3 id=&quot;stdclamp&quot;&gt;&lt;code&gt;std::clamp&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp(x, min, max)&lt;/code&gt; “clamps” x to the range [&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;min&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max&lt;/code&gt;]. More
explicitly, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; is already in the range &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;min&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max&lt;/code&gt; (inclusive) then
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp(x, min, max)&lt;/code&gt; returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;, and for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; outside of that range
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp&lt;/code&gt; returns whichever of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;min&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max&lt;/code&gt; is closest to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;. This is
equivalent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::max(std::min(x, max), min)&lt;/code&gt; except for being a more direct
way to express the intent (and much less of a puzzle for readers).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Warning: While &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp&lt;/code&gt; returns a &lt;em&gt;reference&lt;/em&gt;, code depending on that is
subtle and unusual, and would warrant a comment to alert readers. It is easy
to accidentally create a dangling reference by passing a temporary to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp&lt;/code&gt; and binding the result to a temporary:&lt;/p&gt;

  &lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// `std::clamp(1, 3, 4)` returns a reference to a temporary int initialized
// from `3`, which must not be used beyond the lifetime of the temporary.
// See [Tip #101](/tips/101).
const int&amp;amp; dangling = std::clamp(1, 3, 4);
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp&lt;/code&gt; works for any type that can be compared with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;&lt;/code&gt; (or with a
user-supplied comparator passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp(x, min, max, cmp&lt;/code&gt;).&lt;/p&gt;

&lt;h3 id=&quot;stdmidpoint&quot;&gt;&lt;code&gt;std::midpoint&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;There are no surprises in what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::midpoint&lt;/code&gt; does: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::midpoint(x, y)&lt;/code&gt;
returns a point halfway between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt; (rounding towards &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt; are of an integral type).&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::midpoint(x, y)&lt;/code&gt; works for values &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt; of any floating point or
integral type (not including &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;). As a bonus, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::midpoint(p, q)&lt;/code&gt; also
works for pointers &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;q&lt;/code&gt; into an array.&lt;/p&gt;

&lt;h3 id=&quot;stdlerp&quot;&gt;&lt;code&gt;std::lerp&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lerp&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp&lt;/code&gt; is short for “linear interpolation”, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp(x,
y, t)&lt;/code&gt; returns a value some fraction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt; of the way from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;. For
example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp(x, y, 0)&lt;/code&gt; returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp(x, y, 1)&lt;/code&gt; returns y, and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp(x, y, 0.5)&lt;/code&gt; can be simplified to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::midpoint(x, y)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note: In spite of the name, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp&lt;/code&gt; can also be used for extrapolation if we
pass a value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt; outside of the range &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0, 1]&lt;/code&gt;. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp(100,
101, -2)&lt;/code&gt; evaluates to 98, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp(100, 101, +2)&lt;/code&gt; is 102.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp&lt;/code&gt; works on floating point types.&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;One of the main benefits of these library functions is that they provide a
common vocabulary. As always, prefer to use these standard facilities
instead of writing them from scratch.&lt;/li&gt;
  &lt;li&gt;Prefer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::midpoint(x, y)&lt;/code&gt; over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::lerp(x, y, 0.5)&lt;/code&gt; when applicable.&lt;/li&gt;
  &lt;li&gt;Avoid declaring a reference to the result of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::clamp&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
</description>
          <pubDate>2024-09-30T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/231</link>
          <guid isPermaLink="true">https://abseil.io/tips/231</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #83: Reducing memory indirections</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #83 on June 17, 2024&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-08-23&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/83&quot;&gt;abseil.io/fast/83&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Memory indirections are a &lt;a href=&quot;/fast/62&quot;&gt;frequent cause&lt;/a&gt; for latency and memory
bandwidth bottlenecks. By forcing the processor to follow pointers to get to the
useful data it needs, our programs incur slowdowns and require more memory
bandwidth than they might need from a more efficient layout. In this episode, we
discuss tools for identifying inefficient data structures and improving them.&lt;/p&gt;

&lt;h2 id=&quot;latency-and-throughput&quot;&gt;Latency and throughput&lt;/h2&gt;

&lt;p&gt;In Google’s fleet, our processors spend
&lt;a href=&quot;https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/44271.pdf&quot;&gt;40-50% of their time&lt;/a&gt;
waiting for data coming from their caches or main memory. Memory access latency
and throughput are inextricably linked:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;As the software makes more accesses, it essentially rolls the dice each time
that it will incur cache misses. Further, as the rate of accesses over time
increases, the core sees higher access latencies due to memory bandwidth
saturation.&lt;/li&gt;
  &lt;li&gt;For every access, the program incurs more latency if the processor needs to
access data from an outermost cache or main memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can tackle both of these factors as we think about how to lay out data in our
programs. We can work to reduce accesses or choose layouts that increase the
likelihood of something already being reused. Improving this allows us to do
more useful work with fewer CPUs.&lt;/p&gt;

&lt;h2 id=&quot;helping-the-hardware-help-us&quot;&gt;Helping the hardware help us&lt;/h2&gt;

&lt;p&gt;PMU events are &lt;a href=&quot;/fast/70&quot;&gt;proxies&lt;/a&gt; that we use for understanding accesses and
identifying changes to code to make it friendlier to the cache hierarchy.
Consider a &lt;a href=&quot;/fast/62&quot;&gt;linked list&lt;/a&gt;: The individual nodes are unlikely to be
physically contiguous since they are allocated on the heap. Without this
correlation, the hardware prefetcher can’t help us hide access latency (at best)
and might even issue accesses to (logically) unrelated, neighboring cachelines
that our program won’t need, wasting bandwidth.&lt;/p&gt;

&lt;p&gt;While &lt;a href=&quot;https://protobuf.dev/reference/cpp/arenas/&quot;&gt;Arenas&lt;/a&gt; are an incredibly
useful tool, it’s best to apply this after optimizing the data structure, not
before. A more convoluted, but Arena-allocated data structure is likely worse
than using the
&lt;a href=&quot;https://youtu.be/JZE3_0qvrMg?t=2575s&quot;&gt;best one in the first place&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;surveying-data-structures&quot;&gt;Surveying data structures&lt;/h2&gt;

&lt;p&gt;Consider the problem of finding an element in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::list&lt;/code&gt;, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::set&lt;/code&gt;, an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_set&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_set&lt;/code&gt;. We can construct the benchmark
in two ways: doing lookups one after another with no dependency, or chaining the
output of one lookup to influence the next to suss out
&lt;a href=&quot;/fast/75&quot;&gt;latency characteristics&lt;/a&gt;.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
template&amp;lt;typename T&amp;gt;
void BM_LookupSpeed(benchmark::State&amp;amp; state) {
  using ValueType = T::value_type;

  const int size = std::max&amp;lt;int&amp;gt;(1, state.range(0) / sizeof(ValueType));

  // Choose size random integers, then populate our container with it.
  absl::BitGen rng;
  std::vector&amp;lt;std::remove_cv_t&amp;lt;typename ValueType::first_type&amp;gt;&amp;gt; v;
  v.reserve(size);
  for (int i = 0; i &amp;lt; size; ++i) {
    v.push_back(absl::Uniform(rng, std::numeric_limits&amp;lt;typename ValueType::first_type&amp;gt;::min(),
                              std::numeric_limits&amp;lt;typename ValueType::first_type&amp;gt;::max()));
  }

  T container;
  for (auto u : v) {
    if constexpr (std::is_same&amp;lt;T, std::list&amp;lt;ValueType&amp;gt;&amp;gt;::value) {
      container.emplace_back(u, u);
    } else {
      container.emplace(u, u);
    }
  }

  const auto begin = container.begin();
  const auto end = container.end();

  // Use a small state PRNG for selecting indices to avoid confounding access
  // counts that might occur with larger state RNGs (like Mersenne Twister).
  std::minstd_rand lcg;
  uint32_t last = 0;
  uint64_t sum = 0;
  for (auto _ : state) {
    const size_t index = (lcg() + last) % size;
    const auto value = v[index];

    typename T::const_iterator it;
    if constexpr (std::is_same&amp;lt;T, std::list&amp;lt;ValueType&amp;gt;&amp;gt;::value) {
      it = std::find(begin, end, std::make_pair(value, value));
    } else {
      it = container.find(value);
    }
    ABSL_DCHECK(it != end);
    auto found = it-&amp;gt;second;
    sum += found;

    // Introduce a deliberate dependency from this lookup on the key for the
    // next value.
    last = found;
  }

  ABSL_CHECK_NE(sum, 0);
}

// std::list is O(N), so reduce the data set size 100x for reasonable running
// time.  The reported numbers are per operation, so they are still comparable.
BENCHMARK_TEMPLATE(BM_LookupSpeed, std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;)
   -&amp;gt;Range(1, benchmark::CPUInfo::Get().caches.back().size / 100);
BENCHMARK_TEMPLATE(BM_LookupSpeed, std::map&amp;lt;uint32_t, uint32_t&amp;gt;)
   -&amp;gt;Range(1, benchmark::CPUInfo::Get().caches.back().size);
BENCHMARK_TEMPLATE(BM_LookupSpeed, absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;)
   -&amp;gt;Range(1, benchmark::CPUInfo::Get().caches.back().size);
BENCHMARK_TEMPLATE(BM_LookupSpeed, absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;)
   -&amp;gt;Range(1, benchmark::CPUInfo::Get().caches.back().size);
&lt;/pre&gt;

&lt;p&gt;We can run this benchmark gathering &lt;a href=&quot;/fast/53&quot;&gt;PMU counters concurrently&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The full output from the benchmark:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;name                                                              CYCLES/op
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/1          44.8 ±27%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/8          39.5 ±22%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/64         71.4 ± 6%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/512         181 ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/4096      1.08k ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/32768     13.2k ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/262144     102k ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/403701     164k ± 1%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/1                      44.2 ±12%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/8                      47.1 ±21%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/64                     84.1 ± 8%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/512                     126 ± 3%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/4096                    162 ± 2%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/32768                   247 ± 1%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/262144                  426 ± 2%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/2097152                 780 ± 2%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/16777216              1.93k ± 2%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/40370176              2.53k ± 3%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/1           0.25 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/8           0.25 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/64          81.0 ± 9%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/512         76.8 ± 4%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/4096        77.0 ± 1%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/32768        103 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/262144       118 ± 1%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/2097152      289 ± 3%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/16777216     572 ± 2%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/40370176     871 ± 2%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/1           0.25 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/8           0.25 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/64          71.3 ± 9%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/512         72.1 ± 2%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/4096        71.7 ± 1%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/32768       86.5 ± 1%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/262144       102 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/2097152      210 ± 3%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/16777216     331 ± 3%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/40370176     546 ± 9%

name                                                              MEM_INST_RETIRED:ALL_LOADS/op
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/1          3.00 ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/8          3.00 ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/64         10.0 ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/512        66.0 ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/4096        514 ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/32768     4.10k ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/262144    32.7k ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/403701    50.5k ± 1%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/1                      5.00 ± 0%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/8                      5.00 ± 0%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/64                     9.60 ± 7%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/512                    15.5 ± 1%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/4096                   21.5 ± 1%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/32768                  27.7 ± 0%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/262144                 33.7 ± 0%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/2097152                39.8 ± 0%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/16777216               45.9 ± 0%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/40370176               48.5 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/1           0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/8           0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/64          8.20 ± 4%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/512         8.00 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/4096        8.01 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/32768       8.01 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/262144      8.01 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/2097152     8.01 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/16777216    8.01 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/40370176    8.01 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/1           0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/8           0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/64          7.00 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/512         7.00 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/4096        7.01 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/32768       7.00 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/262144      7.00 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/2097152     7.00 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/16777216    7.00 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/40370176    7.01 ± 0%

name                                                              MEM_LOAD_RETIRED.L1_MISS/op
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/1          0.00 ±NaN%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/8          0.00 ±NaN%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/64         0.00 ±NaN%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/512        0.00 ±NaN%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/4096       0.01 ±22%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/32768       109 ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/262144      705 ± 0%
BM_LookupSpeed&amp;lt;std::list&amp;lt;std::pair&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;&amp;gt;/403701    1.04k ± 1%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/1                      0.00 ±NaN%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/8                      0.00 ±NaN%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/64                     0.00 ±NaN%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/512                    0.00 ±NaN%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/4096                   0.23 ± 4%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/32768                  5.52 ± 1%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/262144                 9.45 ± 0%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/2097152                12.9 ± 0%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/16777216               16.3 ± 0%
BM_LookupSpeed&amp;lt;std::map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/40370176               17.7 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/1           0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/8           0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/64          0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/512         0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/4096        0.00 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/32768       2.30 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/262144      3.58 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/2097152     3.75 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/16777216    3.77 ± 0%
BM_LookupSpeed&amp;lt;absl::node_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/40370176    3.77 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/1           0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/8           0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/64          0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/512         0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/4096        0.00 ±NaN%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/32768       1.20 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/262144      2.55 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/2097152     2.74 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/16777216    2.76 ± 0%
BM_LookupSpeed&amp;lt;absl::flat_hash_map&amp;lt;uint32_t, uint32_t&amp;gt;&amp;gt;/40370176    2.77 ± 0%
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While there are clear differences in these containers due to their asymptotic
complexity, the memory subsystem adds an appreciable scaling factor to their
performance as well.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The microbenchmark &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALL_LOADS&lt;/code&gt; data correlates with our expectations. A
256KB list of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint32_t&lt;/code&gt;’s has 64K elements. The benchmark needs to scan
half of those on average to do a lookup, but the scan &lt;em&gt;also&lt;/em&gt; requires
reading the pointer to find the next node, doubling the number of accesses.
This control data is cached but not intrinsically useful to our program. We
need a different number of memory accesses (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MEM_INST_RETIRED:ALL_LOADS&lt;/code&gt;)
per lookup, depending on our data structure. For the hashtables, each lookup
in our microbenchmark makes 4 accesses: 1 for the vector of values (part of
our harness), 1 for the SwissMap’s control bytes, 1 for checking the key
match, and 1 for finally retrieving the value. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;node&lt;/code&gt; has an additional
indirection here.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;L1_MISS&lt;/code&gt; lets us differentiate on the efficiency of accesses in terms of
how many cachelines the program accesses. Many of the program’s loads are to
the same cacheline–it needs to access both the metadata of pointers to the
next node and a value, or it need to access both the key and the mapped
value when the program finally looks up the value.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;finding-unneeded-indirections&quot;&gt;Finding unneeded indirections&lt;/h2&gt;

&lt;p&gt;To find unneeded indirections, we focus on heap allocations and their access
patterns, since many accesses are to these data structures. Globals tend to have
less complexity: A command line flag holding a value is fairly common, but a
complex, allocation-free data structure is comparatively rare.&lt;/p&gt;

&lt;p&gt;We are also looking for allocations that are accessed &lt;em&gt;frequently.&lt;/em&gt; This is a
qualitative, rather than quantitative threshold, depending on the circumstances.
Flattening a data structure that is too cold might prove to be too costly in
terms of RAM, or even harmful to cache efficiency.&lt;/p&gt;

&lt;p&gt;Combining these two factors, we are often looking for places where the lifetime
of one is a superset of the other. For example, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; member
variable might be initialized at construction and freed in the destructor. In
contrast, something held in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::shared_ptr&lt;/code&gt; might have an indeterminate
lifetime, making it less suitable for coupling the two.&lt;/p&gt;

&lt;h3 id=&quot;allocations&quot;&gt;Allocations&lt;/h3&gt;

&lt;p&gt;Small, frequently made allocations are good candidates for optimization.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A small allocation is cacheline-inefficient, since we need storage for both
the pointer to the allocation and the object itself (and potentially
unrelated, neighboring data too).&lt;/li&gt;
  &lt;li&gt;Short lifetimes bound our error if we don’t use all of the data. They also
give us a rough proxy for access frequency–the bytes of every allocation
should generally be touched once, otherwise we could make the allocation
smaller. Containers with amortized growth (like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt;) might be
larger than needed by a small constant factor (typically 2x), but a large
constant factor would only occur if we called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reserve&lt;/code&gt; with too large an
argument.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can find these by using TCMalloc’s deallocation profiler to explicitly filter
on lifetime, or combine its allocation profile with heap profiles.&lt;/p&gt;

&lt;p&gt;Examining frequent allocations can also help find opportunities for eliminating
the allocation altogether.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
  rpc::StreamStatsInfo* stats_info = new rpc::StreamStatsInfo;
  // ...populate stats_info...
  data.stats_info = stats_info;
  // ...populate data...
  GetStreamMultiplexer()-&amp;gt;HandleBytes(&amp;amp;data);
  delete stats_info;
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
  rpc::StreamStatsInfo stats_info;
  // ...populate stats_info...
  data.stats_info = &amp;stats_info;
  // ...populate data...
  GetStreamMultiplexer()-&amp;gt;HandleBytes(&amp;amp;data);
  // stats_info destroyed when it goes out of scope
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stats_info&lt;/code&gt; was only 120 bytes, so accessing its fields from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data.stats_info&lt;/code&gt;
might entail 4 cachelines: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data.stats_info&lt;/code&gt; itself, and 2-3 for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*stats_info&lt;/code&gt;
depending on how it was aligned. Using the stack doesn’t zero out the cache
footprint of the object, but it is far more likely that those cachelines will
already be resident and their contiguous nature makes it far more prefetchable
(if not).&lt;/p&gt;

&lt;p&gt;In another case, we replaced a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; with an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InlinedVector&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
  std::vector&amp;lt;const Table*&amp;gt; new_tables(count_of_new_objects);
  const Table* new_table = to;
  for (int i = count_of_new_objects - 1; i &amp;gt;= 0; i--) {
    new_tables[i] = new_table;
    new_table = new_table-&amp;gt;parent();
  }
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
  absl::InlinedVector&amp;lt;const Table*, 4&amp;gt; new_tables(count_of_new_objects);
  const Table* new_table = to;
  for (int i = count_of_new_objects - 1; i &amp;gt;= 0; i--) {
    new_tables[i] = new_table;
    new_table = new_table-&amp;gt;parent();
  }
&lt;/pre&gt;

&lt;p&gt;The vector was only used for the duration of the function call and allocation
profiles showed that all allocations were 32-bytes or smaller. While we can’t
statically guarantee that, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InlinedVector&lt;/code&gt; gracefully handles the
situation where we need more elements.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Data indirections are a frequent source of cache misses that can hurt
performance. Using profiling tools, we can identify allocations that cause these
misses and choose better data structures to reduce them.&lt;/p&gt;
</description>
          <pubDate>2024-09-04T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/83</link>
          <guid isPermaLink="true">https://abseil.io/fast/83</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #79: Make at most one tradeoff at a time</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #79 on January 19, 2024&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt; and &lt;a href=&quot;mailto:kfm@google.com&quot;&gt;Matt Kulukundis&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-06-20&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/79&quot;&gt;abseil.io/fast/79&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developing and enabling optimizations can often involve tradeoffs: using more
RAM and less CPU, choosing which problems to solve right away and which to
defer, and so on. In this episode, we discuss examples and strategies for
breaking down projects into smaller steps to &lt;a href=&quot;/fast/72&quot;&gt;increase velocity&lt;/a&gt; and
maximize area under the curve.&lt;/p&gt;

&lt;h2 id=&quot;step-by-step-migrations-swisstable&quot;&gt;Step-by-step migrations: SwissTable&lt;/h2&gt;

&lt;p&gt;Hash tables have many different implicit and explicit properties that affect
their contracts and behaviors. In designing
&lt;a href=&quot;https://abseil.io/about/design/swisstables&quot;&gt;SwissTables&lt;/a&gt; and planning for their
associated migrations, we made careful choices to defer, avoid, or consciously
embrace a great number of tradeoffs when modifying implementation contracts.&lt;/p&gt;

&lt;p&gt;The SwissTable migration primarily focused on iteration order, deferring several
other valuable changes. In the SwissMap implementation, we introduced code that
deliberately randomized hashtable iteration order so that future improvements
would not have to deal with brittle tests relying on iteration order again.&lt;/p&gt;

&lt;p&gt;Because of the randomization we had placed into both SwissTables and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt;, we were able to make multiple optimizations to the underlying
structure of both of these, changing the behavior for small sizes, adjusting the
way windowing works, and completely replacing the core hash function. All of
these optimizations were made after launch, because every step in the process
was a net positive.&lt;/p&gt;

&lt;p&gt;TIP: When fixing &lt;a href=&quot;https://www.hyrumslaw.com&quot;&gt;Hyrum’s Law&lt;/a&gt; issues, look for ways
to deliberately perturb the behavior so future changes are easier.&lt;/p&gt;

&lt;p&gt;Pointer stability of entries is extremely visible in a Hyrum’s Law sense. The
SwissTable migration decided to deliberately defer this choice, by providing a
pointer stable variant, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_map&lt;/code&gt;, that we directly migrated users
to. We published guidance encouraging users to migrate themselves from
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_map&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&lt;/code&gt;, but focused our own efforts on
getting people to take the first step. Users found the secondary step, migrating
to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&lt;/code&gt;, significantly easier because of the randomization we
had already in place for SwissTable.&lt;/p&gt;

&lt;p&gt;TIP: Stable intermediate states can form good stopping points for a migration to
allow progress to be made without jumping all the way to the final state. Even
when you cannot move people to the final state immediately, be clear in your
written guidance what the best case should be.&lt;/p&gt;

&lt;p&gt;When we started the SwissTable migration, we knew that we would likely want to
release it in Abseil and that we wanted to build a new hashing framework (now
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt;) for it. But those steps weren’t ready. Rather than delay the
launch until we had all the parts in place, we began the SwissTable migration
without a custom hashing framework, and later migrated the spelling from a
different namespace to its final home in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;TIP: Shipping early allows you to capture wins earlier and get important
feedback from users.&lt;/p&gt;

&lt;p&gt;Once &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt; was ready, we made sure to have built-in randomization and
switched the default hasher for SwissTable to it. Because it worked by default
and made the well lit path easier for customers, its adoption went incredibly
smoothly.&lt;/p&gt;

&lt;p&gt;TIP: Prefer switching defaults to migrating code if you can.&lt;/p&gt;

&lt;p&gt;When we introduced
&lt;a href=&quot;/fast/26&quot;&gt;hashtable profiling for monitoring tables fleet wide&lt;/a&gt;, some users
were surprised that tables could be sampled (triggering additional system
calls). If we had tried to have sampled monitoring from the start, the migration
would have had a new class of issues to debug. This also allowed us to have a
&lt;a href=&quot;/fast/52&quot;&gt;very clear opt-out for this specific feature&lt;/a&gt; without delaying the
entire rollout. Additionally, the folks doing the migrations didn’t have to
debug as many distinct types of failures, so each launch could be handled much
faster!&lt;/p&gt;

&lt;p&gt;TIP: Separate changes into distinct launches to isolate debugging to a distinct
class of issues at a time.&lt;/p&gt;

&lt;h2 id=&quot;iterative-improvement-deploying-tcmallocs-cpu-caches&quot;&gt;Iterative improvement: Deploying TCMalloc’s CPU caches&lt;/h2&gt;

&lt;p&gt;When &lt;a href=&quot;github.com/google/tcmalloc/blob/master/docs/index.html&quot;&gt;TCMalloc&lt;/a&gt; was
first introduced, it used per-thread caches, hence its name,
“&lt;a href=&quot;https://goog-perftools.sourceforge.net/doc/tcmalloc.html&quot;&gt;Thread-Caching Malloc&lt;/a&gt;.”
As thread counts continued to increase, per-thread caches suffered from two
growing problems: a per-process cache size was divided over more and more
threads, making each cache on average smaller, and more idle threads (threads »
cores) meant more RAM was effectively inaccessible.&lt;/p&gt;

&lt;p&gt;Initially, Andrew Hunter added support for per-CPU caches. Rather than cache
memory for each thread, the implementation had a cache for each physical core on
the machine. If a thread was descheduled, another thread would be able to reuse
that same cache. Over time, organic adoption brought per-CPU cache usage to
roughly half of the fleet’s CPU usage and memory allocations.&lt;/p&gt;

&lt;p&gt;After extensive early adoption, TCMalloc’s default changed: unless otherwise
requested, per-CPU caches were used. Due to the extra metadata per-CPU caches,
this made a tradeoff of RAM for CPU. Rather than completely eliminate this cost,
we opted to make this intentional tradeoff. While later optimizations minimized
the RAM overhead of per-CPU caches, they would not materialize for several
years, so this strategy allowed us to realize incremental benefits years
earlier.&lt;/p&gt;

&lt;p&gt;TIP: Identify ways to iteratively land improvements. This allows optimizations
to be deployed when ready, without the R&amp;amp;D of implementing all anticipated
optimizations upfront. This can help maximize the savings area-under-curve.&lt;/p&gt;

&lt;p&gt;As years went by, though, core counts for the typical server had increased
dramatically. Since the per-CPU cache uses an array–indexed by physical CPU
ID–of caches, more metadata had to be allocated even though the number of cores
used by a typical application had not grown commensurately. Additionally, since
a job configured to use 16 cores might move around across a socket with 128
cores, we could populate caches on each of these cores even though the
application might not actively run on them. These observations motivated
development of
&lt;a href=&quot;https://research.google/pubs/characterizing-a-memory-allocator-at-warehouse-scale/&quot;&gt;several optimizations&lt;/a&gt;.
TCMalloc includes extensive telemetry that enabled us to calculate the amount of
memory being used for per-vCPU caches which provided estimates of the potential
opportunity - to motivate the work - and measure the final impact - for
recognising the benefit.&lt;/p&gt;

&lt;p&gt;TIP: Tracking metrics that we intend to optimize later, even if not right away,
can help identify when an idea is worth pursuing and prioritizing. By monitoring
metadata memory usage and the number of active caches, we were able to identify
when the problem had grown to be &lt;a href=&quot;/fast/72&quot;&gt;worth solving&lt;/a&gt; compared to other
opportunities.&lt;/p&gt;

&lt;h2 id=&quot;decoupled-rollouts-limoncello&quot;&gt;Decoupled rollouts: Limoncello&lt;/h2&gt;

&lt;p&gt;Experiments to
&lt;a href=&quot;https://research.google/pubs/limoncello-prefetchers-for-scale/&quot;&gt;switch-off hardware prefetchers&lt;/a&gt;
under high system &lt;a href=&quot;/fast/62&quot;&gt;memory bandwidth&lt;/a&gt; usage showed significant
performance improvements for the fleet. Analysis of the data showed that most
workloads showed broad improvements, but a handful saw regressions.&lt;/p&gt;

&lt;p&gt;By exploring the data at a per-function granularity, we were able to recognize
the functions that most significantly regressed in A/B testing. Many of these
regressions were in core libraries with streaming access patterns. By adding
software prefetches to them, we were able to recover their performance when HW
prefetchers were disabled.&lt;/p&gt;

&lt;p&gt;TIP: A regression in one dimension or slice of data can sometimes become the
kernel of an idea for a new opportunity.&lt;/p&gt;

&lt;p&gt;While these prefetches primarily recover performance when the hardware stream
prefetchers are turned off, they also help performance even when HW prefetchers
are turned on. Hardware prefetchers require a warmup period to learn about the
access pattern, and unlike higher-level C++ code, lack knowledge about when to
stop prefetching when streams are short. Software prefetches can avoid a warmup
period and maintain high precision. While turning off the HW prefetchers had
illuminated the opportunity, the instantaneous warmup period and high precision
meant that SW prefetchers were deployable right away without consideration for
whether the HW prefetchers were on or off.&lt;/p&gt;

&lt;p&gt;Once several prefetches were in place, the project was reevaluated with several
teams that had previously seen regressions. Thanks to the SW prefetches, these
gaps had narrowed dramatically. Since these were located in a handful of
carefully studied and frequently optimized core libraries, maintaining the
prefetches is feasible, even over successive hardware generations.&lt;/p&gt;

&lt;p&gt;TIP: Rolling out changes independently from one another avoids unneeded
couplings and simplifies rollout strategies.&lt;/p&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing words&lt;/h2&gt;

&lt;p&gt;Structuring how we identify and roll out optimizations can help us move faster.
By keeping our tradeoffs as simple and straightforward as possible, or better
yet, avoiding tradeoffs altogether, we can iteratively improve performance
without hitting stumbling blocks. Exporting &lt;a href=&quot;/fast/60&quot;&gt;metrics along the way&lt;/a&gt;
allows us to identify the biggest opportunities as workloads and hardware
evolve.&lt;/p&gt;
</description>
          <pubDate>2024-09-04T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/79</link>
          <guid isPermaLink="true">https://abseil.io/fast/79</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #72: Optimizing optimization</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #72 on August 7, 2023&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-08-23&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/72&quot;&gt;abseil.io/fast/72&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finding optimizations is increasingly crucial as Moore’s Law ends and we can no
longer expect a free lunch from continued hardware innovation. In this episode,
we discuss the process of finding and developing optimizations to work on.&lt;/p&gt;

&lt;h2 id=&quot;planning&quot;&gt;Planning&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Plans are worthless, but planning is everything”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just as efficiency projects are trying to maximize the productivity of our
hardware, the projects themselves can be optimized by effective planning.
Project selection makes a huge difference in outcomes and impact.&lt;/p&gt;

&lt;p&gt;Realized impact of a project is the product of several factors. When we are
first starting to think about an optimization, we
&lt;a href=&quot;/fast/90&quot;&gt;estimate all of these factors&lt;/a&gt;. While it’s rewarding for our
estimates to be correct, the primary goal is to have just enough information to
&lt;a href=&quot;/fast/60&quot;&gt;make a better decision&lt;/a&gt; and set priorities–to preferentially work on
optimization “A” over optimization “B” because “A” has a larger expected ROI.
Oftentimes, we only need a
&lt;a href=&quot;https://en.wikipedia.org/wiki/Significant_figures&quot;&gt;single significant figure&lt;/a&gt;
to do so: Spending more time making a better estimate or
&lt;a href=&quot;/fast/94&quot;&gt;gathering more data&lt;/a&gt; does not make things more efficient by itself.
When new information arrives, we can update our priors accordingly.&lt;/p&gt;

&lt;p&gt;Once we have identified an area to work in, we can shift to thinking about ways
of tackling problems in that area.&lt;/p&gt;

&lt;h3 id=&quot;upper-bound&quot;&gt;What is the largest potential win?&lt;/h3&gt;

&lt;p&gt;For example, we have limited headroom to optimize a function using a single CPU
core out of entire warehouse-scale computers. Even if we can drive its cost to
&lt;em&gt;zero&lt;/em&gt;, the impact is low. In contrast, the opportunity cost of &lt;em&gt;not&lt;/em&gt; working on
more important areas is high.&lt;/p&gt;

&lt;h3 id=&quot;delta&quot;&gt;How much can we do about it?&lt;/h3&gt;

&lt;p&gt;It is not enough to observe “X is expensive”: We need to be able to change X
too.&lt;/p&gt;

&lt;p&gt;“Speed of light” analysis might provide a helpful upper bound here. If an
operation needs to read data from memory, process it, and write it out, it’s
hard for it to be substantially faster than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt;. Performance does not need
to ultimately converge with our rough analogue, but if we’re already close, it
may be hard to meaningfully affect the performance of X.&lt;/p&gt;

&lt;p&gt;An operation may already be as simplified as it can be–for example, it is hard
to speed up adding two integers. We may need to look further up the stack–add
less often–to realize performance gains.&lt;/p&gt;

&lt;h3 id=&quot;measurement&quot;&gt;Can we measure what changed, if so, how?&lt;/h3&gt;

&lt;p&gt;An unmeasured optimization is a tree that fell in the woods with no one around.&lt;/p&gt;

&lt;p&gt;For example, some changes can have highly non-local effects that can make
accurate measurement more challenging. TCMalloc has an “expensive” prefetch
which makes TCMalloc look more expensive, but improves
&lt;a href=&quot;/fast/39&quot;&gt;topline application performance&lt;/a&gt;. In a distributed system, changing
the requests sent by a client to a server can dramatically impact the server’s
costs, but not necessarily affect &lt;a href=&quot;/fast/70&quot;&gt;the metrics the client sees&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;likelihood&quot;&gt;What is our likelihood of success?&lt;/h3&gt;

&lt;p&gt;Changing a minor implementation detail can be straightforward, or we can uncover
Hyrum’s Law dependencies on existing quirks. A &lt;a href=&quot;/fast/64&quot;&gt;brand new API&lt;/a&gt; may be
easy to implement, but challenging to grow adoption for. If others have looked
at the same problem before, things might be &lt;a href=&quot;/fast/9&quot;&gt;different this time&lt;/a&gt;, but
we may want to temper our optimism.&lt;/p&gt;

&lt;h3 id=&quot;how-long&quot;&gt;How long will it take?&lt;/h3&gt;

&lt;p&gt;This estimate should include preliminary analysis, implementation, code review,
debugging, rollout, measurement, and a period of refinement after launch.&lt;/p&gt;

&lt;p&gt;We want to save several multiples in resource costs as our time investment, both
to ensure a positive return on investment and to balance against errors in our
estimates.&lt;/p&gt;

&lt;h3 id=&quot;lifespan&quot;&gt;How long will it live?&lt;/h3&gt;

&lt;p&gt;Optimizing code that is there to stay for years is a safer bet. When the system
in question is likely to be replaced soon, we should consider the expected
lifespan of our work.&lt;/p&gt;

&lt;p&gt;Sometimes it makes sense the leave the idea alone and move on to the next item
in the stack rank.&lt;/p&gt;

&lt;p&gt;In other cases the optimization work is transferrable or it raises the
efficiency bar for the new system so the economic effect of the optimization
outlives the original implementation.&lt;/p&gt;

&lt;h2 id=&quot;standing-on-the-shoulders-of-giants&quot;&gt;Standing on the shoulders of giants&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Great artists steal”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Frequently, we can find opportunities by growing adoption or enhancing existing
optimizations.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Historically, “hugepage text” was used to reduce iTLB misses for only a
portion of servers in the fleet. For the remainder, realizing an improvement
in &lt;a href=&quot;/fast/7&quot;&gt;application productivity&lt;/a&gt; was a single flag-flip away. A lot of
factors that go into planning were already de-risked: We knew it would
appreciably move the needle for a large portion of the fleet if enabled,
leaving us to focus on how to get there.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;AutoFDO uses &lt;a href=&quot;https://research.google/pubs/autofdo-automatic-feedback-directed-optimization-for-warehouse-scale-applications/&quot;&gt;production profiles to provide feedback to the compiler to
optimize program
performance&lt;/a&gt;.
Once the initial infrastructure was built, we were able to get further
savings with a multi-pronged approach: increasing adoption, improving
profile quality, and building further optimizations like
&lt;a href=&quot;https://lists.llvm.org/pipermail/llvm-dev/2020-November/146694.html&quot;&gt;FS-AFDO&lt;/a&gt;,
&lt;a href=&quot;https://discourse.llvm.org/t/rfc-cmov-vs-branch-optimization/6040&quot;&gt;cmov-vs-branch&lt;/a&gt;,
and
&lt;a href=&quot;https://groups.google.com/g/llvm-dev/c/RUegaMg-iqc/m/wFAVxa6fCgAJ&quot;&gt;function splitting&lt;/a&gt;
on top of it.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Borrowing ideas, even if seemingly simple, from another area, can go a long way.
“Don’t do extra work” sounds obvious, but bringing fresh eyes to a problem and
cross-pollinating ideas can be very effective.&lt;/p&gt;

&lt;p&gt;Once we have some ideas to try out, we want to shift towards evaluating them
systematically.&lt;/p&gt;

&lt;h2 id=&quot;optimization-lifecycle&quot;&gt;Optimization lifecycle&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;“If it disagrees with experiment, it’s wrong. In that simple statement is the
key to science.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;derisking-an-idea&quot;&gt;Derisking an idea&lt;/h3&gt;

&lt;p&gt;In our initial planning, we made a few assumptions to estimate the probable
return on investment from a project. Our first priority is to de-risk those
assumptions by prototyping our change and evaluating it.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Benchmark to &lt;a href=&quot;/fast/39&quot;&gt;improve estimates&lt;/a&gt;. This lets us iteratively improve
our estimates, with more effort to achieve higher fidelity.&lt;/li&gt;
  &lt;li&gt;Evaluate impact on &lt;a href=&quot;/fast/70&quot;&gt;secondary metrics&lt;/a&gt;. Even if we can’t see the
end-to-end, fleetwide impact immediately, proxies–PMU events, profiles, or
even individual applications–can tell us if we’re on the right track.&lt;/li&gt;
  &lt;li&gt;Cut every corner. Making simplifying assumptions or bypassing edge cases can
get us data sooner. Even if we’re not in a necessarily optimal place, we can
confirm that our hunch about an opportunity was valid. This exercise also
helps with differentiating which project dependencies are truly critical and
those that are merely nice to have.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we try out an idea and cannot move the metrics we expected to, our hypothesis
might be wrong. We might realize that something couldn’t be optimized after all,
or it wasn’t on the critical path as expected. These explanations can let us
tweak our plans, scrub things altogether, or inform future areas of
investigation.&lt;/p&gt;

&lt;p&gt;Once we’ve demonstrated that we have a viable optimization in-hand, we can focus
on the steps towards landing it.&lt;/p&gt;

&lt;h3 id=&quot;building-the-idea-out&quot;&gt;Building the idea out&lt;/h3&gt;

&lt;p&gt;Test failures can point us to edge cases that constrain our implementation. This
may require tweaking our implementation to retain behaviors or clean up usage
that is no longer permitted. The choice is largely a judgment call: Having a
simpler implementation will be easier to
&lt;a href=&quot;/fast/64&quot;&gt;optimize further in the long run&lt;/a&gt;, but a herculean cleanup may
prevent us from landing anything at all. This may also indicate a good time to
insert randomization and other defenses to make future optimizations in this
space smoother.&lt;/p&gt;

&lt;p&gt;With benchmarks, we can fine-tune our idea to try out different parameters and
make sure that it improves performance in a variety of situations.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We need not find the precisely &lt;em&gt;optimal&lt;/em&gt; parameters, since we’re liable to
simply overfit to our model or loadtest. Optimality might be an illusion.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Making an initial change to a library can often be the hardest as we uncover
unknown unknowns, especially when we move forward with it. Optimizing every
cycle or byte of RAM doesn’t matter until we actually overcome the hurdles
of turning it on.&lt;/p&gt;

    &lt;p&gt;For example, moving from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GoodFastHash&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::hash&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt;
improved performance, but required taming Hyrum’s Law by introducing a
randomized hash algorithm and identifying brittle tests. Once those issues
were surmounted, we were able to iterate from there, replacing
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt;’s algorithm with a different, more efficient one.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we have something that works well and has sufficient polish, we can move
forward with it.&lt;/p&gt;

&lt;h3 id=&quot;launching&quot;&gt;Launching&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;/fast/39&quot;&gt;Production is ultimately what matters&lt;/a&gt; and our goal is to bring the
optimization there for evaluation. Launching and iterating on an optimization
helps in several ways.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It delivers value sooner. The area under the curve of efficiency over time
is larger by having small, successive landings than if we tried to realize
the “better” optimization all at once, but took much longer to deliver it.
We doubled the impact of TCMalloc’s
“&lt;a href=&quot;https://storage.googleapis.com/gweb-research2023-media/pubtools/6170.pdf&quot;&gt;Temeraire&lt;/a&gt;”
optimization in
&lt;a href=&quot;https://storage.googleapis.com/gweb-research2023-media/pubtools/7777.pdf&quot;&gt;following years&lt;/a&gt;,
but launching early provided benefits years earlier than if we had waited.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Things may perform differently, for better or worse, than we expected. This
can inform next steps for where to look for further ideas, allowing us to
stand on our own shoulders so to speak.&lt;/p&gt;

    &lt;p&gt;For an optimization enabled broadly, opt-outs can tell us about what edge
cases have proven to be truly important and need more attention, leading to
further optimization insights. For example, a single, long-standing opt-out
from Temeraire informed two distinct optimizations.&lt;/p&gt;

    &lt;p&gt;Success in one area brings opportunities for cross-pollination. We can take
the same solution, an
&lt;a href=&quot;https://research.google/pubs/pub50370.pdf#page=7&quot;&gt;algorithm&lt;/a&gt; (pages on huge
pages) or data structure, and apply the idea to a
&lt;a href=&quot;https://storage.googleapis.com/gweb-research2023-media/pubtools/7777.pdf#page=9&quot;&gt;related but different area&lt;/a&gt;
(objects on pages, or “span” prioritization). Without the original landing,
though, we might have never realized this.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Circumstances are continually changing. The assumptions that started a
project years ago may be invalid by the time the project is ready.
Intermediate milestones allow us to validate assumptions along the way.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;We may have bypassed non-critical dependencies for the sake of expediency.
When those dependencies are ready, we can revisit our choices to enhance our
optimization. For example, a library might have required extensive
refactoring to fully enable a particular optimization, so we opted to get
most of the benefit upfront and realize the rest later when the refactoring
was completed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;landing&quot;&gt;Landing&lt;/h3&gt;

&lt;p&gt;Once we’ve launched an optimization, we want to land it and for that we &lt;em&gt;must&lt;/em&gt;
measure it. We are primarily interested in measuring our primary metric, for
example, seeing queries-per-CPU go up. Our
&lt;a href=&quot;/fast/70&quot;&gt;secondary, proxy metrics&lt;/a&gt;–CPU time in a particular function, PMU
events like cache or TLB misses–help to confirm and support the claim that the
optimization had the intended effect. This distinguishes the outcome from mere
coincidence–did we actually speed something up, or did another change somewhere
else happen to make the application faster? While we relied on estimates to
guide starting to work in an area, we also don’t want those
&lt;a href=&quot;https://calteches.library.caltech.edu/51/2/CargoCult.htm&quot;&gt;expectations to bias our measurements&lt;/a&gt;
either: The actual data might be better (or worse) than what we anticipated and
reality is what matters.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Project selection and project execution can greatly impact optimization
outcomes. By judiciously selecting the areas we dig and adopting a strategy of
launching-and-iterating, we can unlock significant savings.&lt;/p&gt;
</description>
          <pubDate>2024-09-04T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/72</link>
          <guid isPermaLink="true">https://abseil.io/fast/72</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #62: Identifying and reducing memory bandwidth needs</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #62 on July 7, 2022&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;, &lt;a href=&quot;mailto:lotero@google.com&quot;&gt;Luis Otero&lt;/a&gt; and &lt;a href=&quot;mailto:villavieja@google.com&quot;&gt;Carlos Villavieja&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-09-15&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/62&quot;&gt;abseil.io/fast/62&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To accomplish useful work with processors, programs need to access main memory.
The rate that programs can transfer data to/from main memory has not grown as
fast as processors getting greater per-core performance and more cores. The
Memory Wall, &lt;a href=&quot;https://dl.acm.org/doi/10.1145/216585.216588&quot;&gt;long predicted&lt;/a&gt;, is
here. Memory bandwidth is increasingly the bottleneck for how much useful work
modern data centers can accomplish with its CPUs. Optimizing for memory
bandwidth productivity can make code faster–by reducing memory stalls–and RAM
footprints smaller. In this episode, we discuss techniques for identifying
hotspots and reducing their impact.&lt;/p&gt;

&lt;h2 id=&quot;memory-bandwidth-basics&quot;&gt;Memory bandwidth basics&lt;/h2&gt;

&lt;p&gt;Reads and writes while a program is running trigger accesses to memory.
Accessing RAM is slow–approximately
&lt;a href=&quot;https://sre.google/static/pdf/rule-of-thumb-latency-numbers-letter.pdf&quot;&gt;100 nanoseconds&lt;/a&gt;–so
processors have added layers of caches in between the execution units and the
physical modules of RAM. On x86, this started with a single kilobyte-sized cache
on the 386, but modern processors have several layers of caches (L1/L2/L3). The
closer to the processor, the smaller but faster the caches typically are.&lt;/p&gt;

&lt;p&gt;The processor’s caches work at a granularity of a &lt;em&gt;cache line&lt;/em&gt;, typically a
64-byte chunk of data. This simplifies the hardware–which can track whether a
cache line is &lt;em&gt;dirty&lt;/em&gt; and needs to be written to main memory at the cache line
level–rather than say tracking byte-by-byte. This abstraction is also useful in
practice–common primitive data types like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T*&lt;/code&gt; all span several
bytes. Accessing the cache line from main memory is an all-or-nothing affair:
Loading any one byte means the whole line is read from memory.&lt;/p&gt;

&lt;p&gt;In addition to a program’s loads and stores, the processor can issue prefetches
for data at the hardware level. These prefetches need to be timely, the data
needs to be ready before the program actually needs it, but not so early that it
is evicted from the cache before it can be used. Prefetches also need to be
useful: Pulling in a cache line that ends up being unaccessed consumes memory
bandwidth without the benefit of avoiding a cache miss on the critical path.&lt;/p&gt;

&lt;p&gt;The processor’s memory bus can handle thousands of transfers per second, limited
by technology, power requirements, and physics. While cache sizes and the memory
bus differ across different architectures, the same general principles apply. At
the socket level, this can give the processor several GB/second of &lt;em&gt;memory
bandwidth&lt;/em&gt;. These windows to transfer data are akin to seats on an airplane,
though: If the airline oversells a flight and everyone shows up at the airport,
several passengers will be forced to wait for the next flight (in the case of
CPUs there aren’t any refunds). Bursts in memory accesses, especially across
many cores, can saturate our memory bus, even if the average over time is
relatively low. Similarly, once a plane takes off, any unsold seats are wasted
and cannot aid future bursts.&lt;/p&gt;

&lt;p&gt;This perspective suggests two paths to reducing how much data needs to move to
and from main memory: 1) access fewer things; 2) increase the reuse of the data
the program accesses.&lt;/p&gt;

&lt;p&gt;Making a program’s working set more cacheable allows it to be less bottlenecked
on memory bandwidth and fewer cache misses reduce memory latency, allowing the
program to speed up.&lt;/p&gt;

&lt;h2 id=&quot;finding-bottlenecks&quot;&gt;Finding bottlenecks&lt;/h2&gt;

&lt;p&gt;We can use data collected with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;perf&lt;/code&gt; tool on a locally executed process.&lt;/p&gt;

&lt;p&gt;While LLC misses are only an approximation–this event only tracks misses on
loads–it can be quite effective for finding and fixing bottlenecks. Hardware
performance counter limitations largely restrict to load events while
simultaneously having precise attribution. Attribution to functions is what
allows us to find source code-level optimizations. A cache miss on a load is
&lt;em&gt;most likely&lt;/em&gt; a read transaction on the memory bus and also &lt;em&gt;probably&lt;/em&gt;
corresponds to a previous cache eviction at some earlier point in time. The
absolute numbers of misses are less important for finding places to look for
optimizations than their &lt;em&gt;relative&lt;/em&gt; rankings.&lt;/p&gt;

&lt;h2 id=&quot;how-to-measure&quot;&gt;How to measure&lt;/h2&gt;

&lt;p&gt;A key part of optimization work is measuring the outcomes. While
&lt;a href=&quot;/fast/39&quot;&gt;production is ultimately what matters&lt;/a&gt;, smaller scale proxies such as
microbenchmarks can help with exploring the solution space.&lt;/p&gt;

&lt;p&gt;One challenge for optimizing for cache misses with a microbenchmark is that the
working set may be too small and its data will fit neatly into the processor’s
caches. One strategy used for
&lt;a href=&quot;https://abseil.io/about/design/swisstables&quot;&gt;Abseil’s Hashtables&lt;/a&gt; is to have
“hot” and “cold” microbenchmarks. The “hot” versions stress a single instance,
whose data footprint fits into the processor’s L1 cache. The “cold” versions
work with many instances, ensuring the working set does not fit into the cache.
On modern machines, the cache hierarchy can be several hundred MBs. While an
individual service on a multitenant machine may have to contend with neighbors
also using cache space, a microbenchmark run on an otherwise idle machine can
use the processors caches more completely. While
&lt;a href=&quot;/fast/75&quot;&gt;neither of these extremes exactly represents production&lt;/a&gt;, they show
the contrasts of the computational cost (arithmetic) and memory access costs
required for hashtable operations.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;perf stat -d path/to/benchmark&lt;/code&gt; can provide a quick summary of important
performance counters, including cache misses.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ bazel build -c opt //fleetbench/swissmap:all

$ perf stat -d bazel-bin/fleetbench/swissmap/hot_swissmap_benchmark \
    --benchmark_filter=BM_FindMiss_Hot.*flat.*64.*16.*0

-----------------------------------------------------------------------------------------------------------
Benchmark                                                                 Time             CPU   Iterations
-----------------------------------------------------------------------------------------------------------

BM_FindMiss_Hot&amp;lt;::absl::flat_hash_set, 64&amp;gt;/set_size:16/density:0       1.36 ns         1.36 ns    518389760

 Performance counter stats for &apos;bazel-bin/fleetbench/swissmap/hot_swissmap_benchmark...&apos;:

          1,271.48 msec task-clock                #    0.984 CPUs utilized
                13      context-switches          #   10.224 /sec
                 0      cpu-migrations            #    0.000 /sec
               435      page-faults               #  342.120 /sec
     5,299,599,301      cycles                    #    4.168 GHz                      (49.96%)
    22,698,862,872      instructions              #    4.28  insn per cycle           (62.86%)
     2,843,135,458      branches                  #    2.236 G/sec                    (63.17%)
         2,161,178      branch-misses             #    0.08% of all branches          (63.20%)
     5,548,863,804      L1-dcache-loads           #    4.364 G/sec                    (63.19%)
         1,304,138      L1-dcache-load-misses     #    0.02% of all L1-dcache accesses  (62.31%)**
           153,564      LLC-loads                 #  120.775 K/sec                    (49.10%)
            90,977      LLC-load-misses           #   59.24% of all LL-cache accesses  (49.07%)**

$ perf stat -d bazel-bin/fleetbench/swissmap/cold_swissmap_benchmark \
    --benchmark_filter=BM_FindMiss_Cold.*flat.*64.*16.*0

------------------------------------------------------------------------------------------------------------
Benchmark                                                                  Time             CPU   Iterations
------------------------------------------------------------------------------------------------------------

BM_FindMiss_Cold&amp;lt;::absl::flat_hash_set, 64&amp;gt;/set_size:16/density:0       **22.5 ns         22.4 ns**     37748952

 Performance counter stats for &apos;bazel-bin/fleetbench/swissmap/cold_swissmap_benchmark...&apos;:

          1,502.60 msec task-clock                #    0.984 CPUs utilized
                17      context-switches          #   11.314 /sec
                 3      cpu-migrations            #    1.997 /sec
           111,346      page-faults               #   74.102 K/sec
     4,051,264,336      cycles                    #    2.696 GHz                      (50.00%)
     4,765,057,295      instructions              #    1.18  insn per cycle           (62.51%)
       567,678,472      branches                  #  377.799 M/sec                    (62.51%)
         6,199,555      branch-misses             #    1.09% of all branches          (62.50%)
       982,319,844      L1-dcache-loads           #  653.749 M/sec                    (62.78%)
       157,288,870      L1-dcache-load-misses     #   16.01% of all L1-dcache accesses  (62.51%)**
        19,126,293      LLC-loads                 #   12.729 M/sec                    (49.96%)
        15,576,980      LLC-load-misses           #   81.44% of all LL-cache accesses  (49.73%)**
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The benchmark’s large working set made its workload harder to fit into cache,
leading to corresponding increases in L1 and LLC misses. Due to the presence of
cache misses, the same operation–looking up an absent key from a
hashtable–went from ~1.36 nanoseconds to ~22.5 nanoseconds. Worse cache
locality doesn’t just consume more memory bandwidth, it also hampers the
performance and CPU efficiency of programs.&lt;/p&gt;

&lt;p&gt;Additionally, Google’s C++ microbenchmark tool
(https://github.com/google/benchmark/blob/main/docs/user_guide.md) supports
&lt;a href=&quot;/fast/53&quot;&gt;collecting hardware performance counters&lt;/a&gt;. This can be helpful for
isolating the counters to when the benchmark is actually running and to
individual benchmark operations. In contrast, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;perf stat&lt;/code&gt; captures the benchmark
harness’ own setup and its numbers cover the entirety of all microbenchmark
cases being run.&lt;/p&gt;

&lt;h2 id=&quot;optimization-strategies&quot;&gt;Optimization strategies&lt;/h2&gt;

&lt;p&gt;Our goal is to maximize the productivity of our accesses to cache lines, making
sure our programs accomplish as much useful work as possible for each memory
access. This is not just useful for reducing memory bandwidth needs, but it can
improve CPU and RAM productivity as well. Accessing more data and cachelines
than we need is a source of false demand that we can optimize.&lt;/p&gt;

&lt;h3 id=&quot;avoid-unnecessary-indirections&quot;&gt;Avoid unnecessary indirections&lt;/h3&gt;

&lt;p&gt;Consider a simple linked list containing integers:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Node { Node* next; int value; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In memory, this will fill part of a cache line (16 bytes out of 64) and each
node is likely to fall on its own cache line, separate from other nodes. Over
time, a program’s memory allocations will trend towards being random due to the
mix of allocations and deletions that have left gaps.&lt;/p&gt;

&lt;p&gt;This is inefficient to access in several ways:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; pointers, while important to the linked list, aren’t holding
&lt;em&gt;useful&lt;/em&gt; data.&lt;/li&gt;
  &lt;li&gt;Accessing a cache line pulls in only a single 4-byte integer at a time. If
the program were to use a contiguous data structure like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt;,
accessing the first element means it likely &lt;em&gt;also&lt;/em&gt; accessed the cache line
for the second and so on.&lt;/li&gt;
  &lt;li&gt;Due to alignment requirements, each node has 4 bytes of padding going
unused.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::list&lt;/code&gt; is quite rare, many containers have similar &lt;em&gt;implicit&lt;/em&gt;
linked-list like layouts. Matt Kulukundis discussed this in his
&lt;a href=&quot;https://www.youtube.com/watch?v=ncHmEUmJZf4&quot;&gt;2017 CppCon presentation&lt;/a&gt; on
Abseil’s hashtables: Containers like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt; and to a lesser
extent, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_map&lt;/code&gt; achieve pointer stability by separately allocating
each key-value pair. This guarantee comes at a cost, since the data structure
requires an extra memory access to get to the logical value the program is
accessing.&lt;/p&gt;

&lt;p&gt;Similarly, one common pattern is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;std::unique_ptr&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; where there
is an indirection that makes logically adjacent objects not colocated in memory.
It is important to look with a critical eye at whether this indirection is
necessary. Sometimes it exists because T is not copyable/movable. In that case
it may be possible to remove the indirection by fixing the type semantics or by
using a container type that allows non-movable content like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::FixedArray&lt;/code&gt;
or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::deque&lt;/code&gt;. In other cases the indirection may be used to exercise
polymorphic behavior, and techniques like tag-based dispatch may help. There is
no one size fits all solution for this but practical options do exist.&lt;/p&gt;

&lt;h3 id=&quot;minimize-copies&quot;&gt;Minimize copies&lt;/h3&gt;

&lt;p&gt;Copies are sometimes needed for API or correctness reasons, but extraneous ones
require the processor to do more work. For example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
void DoStuff(Protobuf);

void Process(const std::vector&amp;lt;Protobuf&amp;gt;&amp;amp; elements) {
  for (Protobuf element : elements) { // Creates a copy of each element.
    DoStuff(element);
  }
}
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void DoStuff(Protobuf);

void Process(const std::vector&amp;lt;Protobuf&amp;gt;&amp;amp; elements) {
  for (const Protobuf&amp;amp; element : elements) { // Avoids a copy.
    DoStuff(element);
  }
}
&lt;/pre&gt;

&lt;p&gt;The program is copying each element from the vector and then processing that
copy, when no copy would have sufficed. This increases its working set–it has
all of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;elements&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;element&lt;/code&gt;–and increases pressure on the processor’s
cache, making it more likely that the program will trigger evictions and misses.
In addition to the demands on the memory system, the program is also less
productive in terms of its CPU usage–copying isn’t helping us process
faster–and RAM usage–its extraneous copy isn’t needed.&lt;/p&gt;

&lt;p&gt;While this is just an example–and Clang Tidy can recommend fixes for this one
automatically–copies of much larger data structures such as protobufs can
commonly arise.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
void Populate(MyProto* msg, int n) {
  for (int i = 0; i &amp;lt; n; ++i) {
    MySubmessage s;
    s.set_value(i);
    s.mutable_foo()-&amp;gt;set_bar(i);
    *msg-&amp;gt;add_submessage() = s; // Copies, including complex heap allocated structure.
  }
}
&lt;/pre&gt;

&lt;p&gt;Populating data in its final destination can minimize the working set size and
improve efficiency:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void Populate(MyProto* msg, int n) {
  for (int i = 0; i &amp;lt; n; ++i) {
    MySubmessage&amp;amp; s = *msg-&amp;gt;add_submessage();  // Places s in its destination.
    s.set_value(i);
    s.mutable_foo()-&amp;gt;set_bar(i);
  }
}
&lt;/pre&gt;

&lt;p&gt;Similarly, many containers guarantee amortized growth, growing by a
multiplicative factor to achieve this guarantee. With each step in growth, we
allocate another buffer, move elements over, and deallocate the old one. Where
we know the final size, a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reserve&lt;/code&gt; can avoid these copies and reduce
our working set size.&lt;/p&gt;

&lt;h3 id=&quot;densify-data&quot;&gt;Densify data&lt;/h3&gt;

&lt;p&gt;As explained above, allocating objects contiguously can be particularly
beneficial for memory bandwidth, especially if the access patterns will require
us to traverse objects in sequence. However, the benefits will exist to the
extent that the traversed objects are sufficiently small and can be packed
neatly into cache lines.&lt;/p&gt;

&lt;p&gt;In general, densifying data in a way that goes in accordance with its access
patterns can cause improvements to the memory bandwidth consumption of an
application. This lets us use each cache line we access to its fullest. Also, it
helps as prefetchers tend to bring continuous or easy to predict cache lines
into the cache.&lt;/p&gt;

&lt;p&gt;Based on this principle and its implications, consider the following guidelines
when writing an application:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Compact data structures as much as possible by reducing padding and
eliminating fields which are never accessed.&lt;/li&gt;
  &lt;li&gt;When processing large amounts of data, narrower data types can increase data
density when values have constrained ranges. Integers over a small range
might fit in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int8_t&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int16_t&lt;/code&gt;, rather than an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64_t&lt;/code&gt;. Representing a
small set of values is best done with a narrow &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt;, rather than a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;If some fields are accessed more frequently than others, consider breaking
down the objects into two distinct classes (i.e. “hot” and “cold”) such that
arrays of hotter fields/objects are closer in memory.&lt;/li&gt;
  &lt;li&gt;In the extreme of this technique, prefer using
&lt;a href=&quot;https://en.wikipedia.org/wiki/AoS_and_SoA&quot;&gt;Structure-of-Arrays (SoA) than Array-of-Structures (AoS)&lt;/a&gt;
to define the layout of the data structures in your program.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a concrete example of SoA vs. AoS, consider the following code snippet (AoS):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
struct Point3D {
  float x;
  float y;
  float z;
};

float AddAllY(const std::vector&amp;lt;Point3D&amp;gt;&amp;amp; elements) {
  float result = 0;
  for (const auto&amp;amp; element : elements) {
    result += element.y;
  }
  return result;
}
&lt;/pre&gt;

&lt;p&gt;A more optimal alternative could be the following (SoA):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct PointList3D {
  std::vector&amp;lt;float&amp;gt; x;
  std::vector&amp;lt;float&amp;gt; y;
  std::vector&amp;lt;float&amp;gt; z;
};

float AddAllY(const PointList3D&amp;amp; elements) {
  float result = 0;
  for (auto element : elements.y) {  // Traverse the array of &quot;y&quot; coordinates.
    result += element;
  }
  return result;
}
&lt;/pre&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;As with CPU and RAM usage, memory bandwidth is another dimension that we can
optimize for, maximizing &lt;a href=&quot;/fast/7&quot;&gt;the amount of useful work&lt;/a&gt; we can do with the
minimal amount of memory bandwidth. Reducing cache misses and improving data
locality can also bring improvements to CPU performance and reducing required
RAM footprints.&lt;/p&gt;

&lt;h2 id=&quot;additional-reading&quot;&gt;Additional reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Chandler Carruth’s 2017 CppCon talk
“&lt;a href=&quot;https://www.youtube.com/watch?v=2EWejmkKlxs&amp;amp;t=1s&quot;&gt;Going Nowhere Faster&lt;/a&gt;”&lt;/li&gt;
  &lt;li&gt;Matt Kulukundis’s 2017 CppCon talk
“&lt;a href=&quot;https://www.youtube.com/watch?v=ncHmEUmJZf4&quot;&gt;Designing a Fast, Efficient, Cache-friendly Hash Table, Step by Step&lt;/a&gt;”&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2024-09-04T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/62</link>
          <guid isPermaLink="true">https://abseil.io/fast/62</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #197: Reader Locks Should Be Rare</title>
          <description>&lt;p&gt;Originally posted as TotW #197 on July 29, 2021&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:titus@cs.ucr.edu&quot;&gt;Titus Winters&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2024-04-01&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/197&quot;&gt;abseil.io/tips/197&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“Ah, how good it is to be among people who are reading.” - &lt;em&gt;Rainer Maria Rilke&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Mutex&lt;/code&gt; class has supported two styles of locking for many years now:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Exclusive locks, in which exactly one thread holds the lock.&lt;/li&gt;
  &lt;li&gt;Shared locks, which have two modes. If they are held “for writing” they use
an exclusive lock, but they also have a different mode in which many threads
can hold the lock “for reading.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How can a shared lock be acceptable? Isn’t the whole point of having a lock to
gain exclusive access to an object? The perceived value in shared locks is when
we need read-only access to the underlying data/objects. Remember that we get
data races and API races when two threads access the same data without
synchronization, and at least one of those accesses is a write. If we use a
shared-lock when many threads only need to read data, and always use exclusive
locks when writing data, we can avoid contention among the readers and still
avoid data and API races.&lt;/p&gt;

&lt;p&gt;To support this, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Mutex&lt;/code&gt; has both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mutex::Lock()&lt;/code&gt; (and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mutex::WriterLock()&lt;/code&gt;, an alternate name for the same exclusive behavior) as
well as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mutex::ReaderLock()&lt;/code&gt;. From reading through those interfaces, you might
think that we should prefer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReaderLock()&lt;/code&gt; when we’re only reading from the data
protected by the lock.&lt;/p&gt;

&lt;p&gt;In many cases you’d be wrong.&lt;/p&gt;

&lt;h3 id=&quot;readerlock-is-slow&quot;&gt;ReaderLock Is Slow&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReaderLock&lt;/code&gt; inherently does more bookkeeping and requires more overhead than a
standard exclusive lock. As a result, in many cases using the more specialized
form (shared locks) is actually a performance loss, as we have to do quite a bit
more work in the lock machinery itself. This cost is minor in the absence of
contention, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReaderLock&lt;/code&gt; underperforms &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lock&lt;/code&gt; under contention for short
critical sections. Without contention, the value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReaderLock&lt;/code&gt; provides is less
significant in the first place.&lt;/p&gt;

&lt;p&gt;Consider the logic in an exclusive lock vs. a shared lock. A shared lock
generally must also have an exclusive lock mode - if there are no writers, no
data race can occur, and thus there is no need for locking in the first place.
Shared locking is therefore inherently more complex, requiring checks on whether
other readers hold locks, or modifications to the (atomic) count of readers,
etc.&lt;/p&gt;

&lt;h3 id=&quot;when-are-shared-locks-useful&quot;&gt;When are Shared Locks Useful?&lt;/h3&gt;

&lt;p&gt;Shared locks are primarily a benefit when the lock is going to be held for a
comparatively long time and it’s likely that multiple readers will concurrently
obtain the &lt;em&gt;shared&lt;/em&gt; lock. For example, if you’re going to do a lot of work while
holding the lock (e.g. iterating over a large container, not just doing a single
lookup), then a shared locking scheme may be valuable. The dominant question is
not “am I writing to the data”, it’s “how long do I expect the lock to be held
by readers (compared to how long it takes to acquire the lock)?”&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// This is bad - the amount of work done under the lock is insignificant.
// The added complexity of using reader locks is going to cost more in aggregate
// than the contention saved by having multiple threads able to call this
// function concurrently.
int Foo::GetElementSize() const {
  absl::ReaderMutexLock l(&amp;amp;lock_);
  return element_size_;
}
&lt;/pre&gt;

&lt;p&gt;Even when the amount of computation performed under a lock is larger, and reader
locks become more useful, we often find we have better special-case interfaces
to avoid contention entirely - see https://abseil.io/fast and
https://abseil.io/docs/cpp/guides/synchronization for more. RCU (“Read Copy
Update”) abstractions provide a particularly common solution here, making the
read path essentially free.&lt;/p&gt;

&lt;h3 id=&quot;what-should-we-do&quot;&gt;What Should We Do?&lt;/h3&gt;

&lt;p&gt;Be on the lookout for use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReaderLock&lt;/code&gt; - the overwhelming majority of uses of
it are actually a pessimization … but we can’t statically determine that
definitively to rewrite code to use exclusive locking instead. (Reasoning about
concurrency properties in C++ is still too hard for most refactoring work.)&lt;/p&gt;

&lt;p&gt;If you spot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReaderLock&lt;/code&gt;, especially new uses of it, try to ask “Is the
computation under this lock often long?” If it’s just looking up a value in a
container, an exclusive lock is almost certainly a better solution.&lt;/p&gt;

&lt;p&gt;In the end, profiling may be the only way to be sure - contention tracking is
particularly valuable here.&lt;/p&gt;
</description>
          <pubDate>2024-06-25T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/197</link>
          <guid isPermaLink="true">https://abseil.io/tips/197</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #229: Ranked Overloads for Template Metaprogramming</title>
          <description>&lt;p&gt;Originally posted as TotW #229 on February 5, 2024&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:mcyoung@mit.edu&quot;&gt;Miguel Young de la Sota&lt;/a&gt; and &lt;a href=&quot;mailto:kfm@google.com&quot;&gt;Matt Kulukundis&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2024-02-20&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/229&quot;&gt;abseil.io/tips/229&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Warning: This is an advanced tip for folks doing template metaprogramming. In
general, avoid template metaprogramming unless you have a very, very good
reason. If you are reading this, it’s because you need to do some template
metaprogramming or just want to learn something nifty.&lt;/p&gt;

&lt;h2 id=&quot;one-cool-trick&quot;&gt;One Cool Trick&lt;/h2&gt;

&lt;p&gt;Ordinarily, C++ requires every function invocation to resolve to a single “best”
function or it produces an ambiguity error. The exact definition of “best” is
more complex than we want to go into, but involves things like implicit
conversions and type qualifiers.&lt;/p&gt;

&lt;p&gt;In situations that would produce ambiguity errors, we can use explicit class
hierarchies to force the definition of “best” to be what we prefer. This “ranked
overloads” technique uses structures with a class hierarchy so they have a
priority ordering and the compiler will select the highest priority method
first. We’ll define a family of empty &lt;a href=&quot;/tips/198&quot;&gt;tag types&lt;/a&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rank0&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rank1&lt;/code&gt;,
etc., that are related by inheritance, and use those to guide the overload
resolution process.&lt;sup id=&quot;fnref:rank&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:rank&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Public API with good comments.
template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; t);

// Everything below here is a working example of ranked overloads, that
// you can copy and paste to get you started!
namespace internal_size {

// Use [Tip #229](/tips/229) for dispatching.
struct Rank0 {};
struct Rank1 : Rank0 {};
struct Rank2 : Rank1 {};
struct Rank3 : Rank2 {};

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank3, const std::optional&amp;lt;T&amp;gt;&amp;amp; x) {
  return x.has_value() ? Size(*x) : 0;
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank3, const std::vector&amp;lt;T&amp;gt;&amp;amp; v) {
  size_t res = 0;
  for (const auto&amp;amp; e : v) res += Size(e);
  return res;
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank3, const T&amp;amp; t)
  requires std::convertible_to&amp;lt;T, absl::string_view&amp;gt;
{
  return absl::string_view{t}.size();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank2, const T&amp;amp; x)
  requires requires { x.length(); }
{
  return x.length();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank1, const T&amp;amp; x)
  requires requires { x.size(); }
{
  return x.size();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank0, const T&amp;amp; x) { return 1; }

}  // namespace internal_size

template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; t) {
  // Start with the highest rank, Rank3.
  return internal_size::SizeImpl(internal_size::Rank3{}, t);
}

auto i = Size(&quot;foo&quot;);                      // hits the string_view overload
auto j = Size(std::vector&amp;lt;int&amp;gt;{1, 2, 3});  // hits the vector overload
auto k = Size(17);                         // hits the lowest rank &quot;catch all&quot;
&lt;/pre&gt;

&lt;p&gt;Note that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; overloads
use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rank3&lt;/code&gt;. When overloads are mutually incompatible (the call &lt;em&gt;can’t&lt;/em&gt; be
ambiguous by construction), the same rank type can be used. You can think of all
overloads with the same rank as being tried in parallel.&lt;/p&gt;

&lt;p&gt;NOTE: The astute reader may wonder why the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; overload is
declared as a template. Doing so ensures that no implicit conversions will take
place in the signature other than the one for the rank structs. If this overload
were declared with an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; parameter then the call would be
ambiguous: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rank2{}&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rank0{}&lt;/code&gt; would count as a conversion but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char[]&lt;/code&gt;
to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; would also and the call would become
&lt;a href=&quot;https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGe1wAyeAyYAHI%2BAEaYxCBmAJykAA6oCoRODB7evnrJqY4CQSHhLFEx8baY9vkMQgRMxASZPn5cFVXptfUEhWGR0bEJCnUNTdmtQ109xaUDAJS2qF7EyOwc5gDMwcjeWADUJuseidViB9gmGgCCG1s7mPuHQ8TBwAD6AG54mADuZxfXZk2DG2Xj2BzcTxefyuN2BdwebgIAE9EphXgRiExCApoQCgSCwYd3pgHCRcf8APQU3bKLwRWh4ZC7S7KACSu2%2BhAQu2AqAwuzQLDYggUADp/gRMCxEgZJQjkajmGxdgAVXGpABeaIIuyEeC1EDQDCGqvMADZdgRZgcrDCrkrMApEkwVrtgpLiMxaK9NfcTAB2W2XKm7RT3XkUzEMADWmHQAFpUMTiLRUEx0ApdvxiLt8E6mARkAgXuKrk8vA5dgAlQzRjT7QMBgAiNv%2B5crNZjXF2IGrtfrAas/pb6yD7Z1nejZh7fa7DaHI7HGIrE9r6xnk%2B7g%2Bbrbtl0l0tlfsOCsYrHuavW5zL%2Bu1utvrMPEEn61IAoEJqG6BAIFQx3SpyHJe5xmBaqizPO/y7LsxCYAQSwMLsqiiggTAKB8YheJgEAQQcABi94GgAVOBM4aLu1zDv8EpSjKBbHoiKJnsqwFtre6KEZgj4ys%2Ba5vkan4EN%2BIDEqSxDgqxoG7O8uGNlc0G%2BhxsGZgcTa7ORo5QVmJC7IaH46kwXhEOauz3L2MkwY6%2ByWKpnEQJg1qafJlnwZ6lk4k5lEtnuik6nqWrcbQvExq%2Buxfj%2BkJGB8XzfJaslBtBsGuYhBCir6OEUTue4HnRcrgqeDqmlebFahx/lcU%2Bk5mPx%2BmmlJ4FabBACOXh4MplktW1VmDkhor0EYBAIBlo4Nt5lEJS5CG9f1wCDcNQZZdcVw5Ue8pMYVrE3qVfkPpVtatO%2Bxo6mq9XWs5zWte1F1dSpga9eljkWKN1FyZciVwVNyEPZlVHZbRq35et55Fdely%2BZxgXBXWNVHXVYHxZNblcDaz17s20Ehg6%2Bauu60Rej6t7Uct/30WtirA5tYPsTtBoCcdJlWpBzkhp0DQclyloIPcxbAFzJpRtGjUfW5uOemIBNaj%2B5WQ6L%2BO%2Bj%2BL7bsOb5Wj9Y3/IZRBug8anlRA5hmPwqAG490Fm%2BbFuWxj1LFgQmaDfckVvJ8Py7Em0SpumGtGaguzaDrdnhSJJJEOJhzun8gYHdVuzrM2pu7CGtv21z0khzp7spmm6De1r0YB3rXD%2BgnVul6XSfYpz9ypt8jo6gL1lmKIhbcmItAGxw8y0JwACsvB%2BBwWikKgnBuNY1hhYsyx%2BoCPCkAQmid/M0YgD3XCimYPc9/EAAc6zrP6XAH2Y/r6Jwkj94vw%2BcLwCggBo8%2BL/McCwDAiAoKg0p0NE5CUIKiTfxiNsQwbxlwxj4HQD0d8IARCvhEYI9QkScDnvA5gxAkQAHkIjaBDsg3ggphQEAwQwWgSDB68CwBELwwA3BtzvtwChUoQHiAYaQfAsEHB4GJPQoemBVAkiMqsOeuNu7kP0HgCImJ0EeCwFfDEeAWB4PmFQAwwAFAADUYoYMVHgmQggRBiHYFIPR8glBqCvroVoBgjAoHHpYcREQ76wAdCAJgjjMB0FIMmEAYDoyzHmH%2Bao9D4xflUqYGylgzD1l4JnZ4WAnE4TaCHdILgGDuE8M0fwaSph9BiK0XIaQBCjBaEkFIhSGA5JKP0cYlRkkCFZo0DJYwkmcPqcMbowRehVLybYdpxS9ATAaJUmYXB5gKCnisCQXde6XzESPDgSEd5mnjGaSQAprHAF0r4iCEBcCEB0hsUZvAF7kP8aQFePcH6iIvqQRRlzSADyHvM2%2B99H6nNIC/d%2BiwCCJCMr/PSX96DEFCOeTgqglkrLWcAowWziBeBjLMXgcZ9lxL0PwfRohxDGPRaYlQ6gxGWNIN8TEiQlFnw4H3B5V95kYKMr8nUqAqCLOWas9ZIDYXwr8bpDwgLojWXWEct5Wgzlc3TP0RJ1zeB3Ifo8mJN9bCvJOcK5eIBJA71FP6SQkh/QaC4GaM0Zglkn1fKI9YsynnyqVUvclZhzVyo4Mcp%2B8xkypGcJIIAA%3D%3D&quot;&gt;ambiguous again&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;detailed-example&quot;&gt;Detailed Example&lt;/h2&gt;

&lt;p&gt;Let’s suppose we want &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Size(x)&lt;/code&gt; to return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x.length()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x.size()&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;
depending on what the passed type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; implements. The naive approach does not
work:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; x)
  requires requires { x.length(); }
{
  return x.length();
}

template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; x)
  requires requires { x.size(); }
{
  return x.size();
}

template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; x) { return 1; }

auto i = Size(std::string(&quot;foo&quot;));  // Ambiguous.
&lt;/pre&gt;

&lt;p&gt;Because the size and length overloads are of equal rank, they are equally good
matches for the call. Because overload resolution does not eliminate all but one
candidate, the compiler declares the callsite ambiguous. There are clever tricks
using variadic functions or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;long&lt;/code&gt; promotion to create an ordering for two
options, but these do not scale to having N descending ranks of overloads.&lt;/p&gt;

&lt;p&gt;Using ranked overloads as we’ve suggested attaches &lt;em&gt;explicit ranks&lt;/em&gt; in the form
of inheritance to specific overloads. This rank is based on the following rule:
overloads with more derived classes have higher rank than overloads with less
specific ones. That is, if two overloads differ by a single argument’s type, and
both are bases of the argument, the type closest in the inheritance hierarchy
has higher rank and is a better match.&lt;/p&gt;

&lt;p&gt;This means we can build a tower of empty structs, each deriving from the
previous, to put an &lt;em&gt;explicit, numeric rank&lt;/em&gt; on each overload. Using this trick,
we would write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Size&lt;/code&gt; like this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Public API with good comments.
template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; t);

namespace internal_size {

// Use go/ranked-overloads for dispatching.
struct Rank0 {};
struct Rank1 : Rank0 {};
struct Rank2 : Rank1 {};

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank2, const T&amp;amp; x)
  requires requires { x.length(); }
{
  return x.length();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank1, const T&amp;amp; x)
  requires requires { x.size(); }
{
  return x.size();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank0, const T&amp;amp; x) { return 1; }

}  // namespace internal_size

template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; t) {
  // Start with the highest rank
  return internal_size::SizeImpl(internal_size::Rank2{}, t);
}

auto i = Size(std::string(&quot;foo&quot;));  // 3
&lt;/pre&gt;

&lt;p&gt;The overloads can now be read as an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt; chain. First we try the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rank2&lt;/code&gt;
overload; if substitution fails, we fall back to the next rank, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rank1&lt;/code&gt;, and
then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rank0&lt;/code&gt;. Of course, this particular method will treat
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Size(std::string(&quot;foo&quot;))&lt;/code&gt; differently from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Size(&quot;foo&quot;)&lt;/code&gt;. This highlights some
of the dangers of generic programming, though the fix is relatively
straightforward: add an explicit rank to handle strings, as below.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Public API with good comments.
template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; t);

namespace internal_size {
// Use go/ranked-overloads for dispatching.
struct Rank0 {};
struct Rank1 : Rank0 {};
struct Rank2 : Rank1 {};
struct Rank3 : Rank2 {};

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank3, const T&amp;amp; t)
  requires std::convertible_to&amp;lt;T, absl::string_view&amp;gt;
{
  return absl::string_view{t}.size();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank2, const T&amp;amp; x)
  requires requires { x.length(); }
{
  return x.length();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank1, const T&amp;amp; x)
  requires requires { x.size(); }
{
  return x.size();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank0, const T&amp;amp; x) { return 1; }

}  // namespace internal_size

template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; t) {
  // Start with the highest rank
  return internal_size::SizeImpl(internal_size::Rank3{}, t);
}

auto i = Size(&quot;foo&quot;);  // 3
&lt;/pre&gt;

&lt;p&gt;Now extending this to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&lt;/code&gt; is quite straightforward!&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Public API with good comments.
template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; t);

namespace internal_size {
// Use go/ranked-overloads for dispatching.
struct Rank0 {};
struct Rank1 : Rank0 {};
struct Rank2 : Rank1 {};
struct Rank3 : Rank2 {};

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank3, const std::optional&amp;lt;T&amp;gt;&amp;amp; x) {
  return x.has_value() ? Size(*x) : 0;
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank3, const std::vector&amp;lt;T&amp;gt;&amp;amp; v) {
  size_t res = 0;
  for (const auto&amp;amp; e : v) res += Size(e);
  return res;
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank3, const T&amp;amp; t)
  requires std::convertible_to&amp;lt;T, absl::string_view&amp;gt;
{
  return absl::string_view{t}.size();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank2, const T&amp;amp; x)
  requires requires { x.length(); }
{
  return x.length();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank1, const T&amp;amp; x)
  requires requires { x.size(); }
{
  return x.size();
}

template &amp;lt;typename T&amp;gt;
size_t SizeImpl(Rank0, const T&amp;amp; x) { return 1; }

}  // namespace internal_size

template &amp;lt;typename T&amp;gt;
size_t Size(const T&amp;amp; t) {
  // Start with the highest rank
  return internal_size::SizeImpl(internal_size::Rank3{}, t);
}

auto i = Size(&quot;foo&quot;);                      // hits the string_view overload
auto j = Size(std::vector&amp;lt;int&amp;gt;{1, 2, 3});  // hits the vector overload
auto k = Size(17);                         // hits the lowest rank &quot;catch all&quot;
&lt;/pre&gt;

&lt;h2 id=&quot;parting-thoughts&quot;&gt;Parting Thoughts&lt;/h2&gt;

&lt;p&gt;Now that you have learned this awesome power, please remember to use it
sparingly. As we saw with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; overload, generic programming
is subtle and can lead to unexpected results.&lt;/p&gt;

&lt;!-- note: footnotes need to be after any end-of-document links --&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:rank&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Note that “rank” here is used in a colloquial sense and is unrelated to
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/usual_arithmetic_conversions&quot;&gt;conversion ranks&lt;/a&gt;
for integers and floating point values. &lt;a href=&quot;#fnref:rank&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
          <pubDate>2024-03-21T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/229</link>
          <guid isPermaLink="true">https://abseil.io/tips/229</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #227: Be Careful with Empty Containers and Unsigned Arithmetic</title>
          <description>&lt;p&gt;Originally posted as TotW #227 on November 16, 2023&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;James Dennett&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2024-03-11&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/227&quot;&gt;abseil.io/tips/227&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;index-based-loops-still-have-their-uses&quot;&gt;Index-Based Loops (Still Have Their Uses)&lt;/h2&gt;

&lt;p&gt;Modern C++ code uses index-based &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loops much less often now that
range-based &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loops are available, but there are still times when we need to
use an index while we iterate. Parallel iteration over multiple containers is
one such case; another is when we want to process multiple adjacent elements
from a single container. In this tip we’ll look at a pitfall for the second of
these.&lt;/p&gt;

&lt;h2 id=&quot;plausible-code&quot;&gt;Plausible Code&lt;/h2&gt;

&lt;p&gt;Let’s start by looking at some code that might be correct:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
for (int64_t i = 0; i &amp;lt; v.size() - 1; ++i) {
  ProcessPair(v[i], v[i+1]);
}
&lt;/pre&gt;

&lt;p&gt;This code wisely takes some care to check for valid indexes before calling
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessPair()&lt;/code&gt;, so why do we say that it only “might” be correct? A careful
unit test (or almost any &lt;a href=&quot;https://en.wikipedia.org/wiki/Fuzzing&quot;&gt;fuzz test&lt;/a&gt;)
will cover the case where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; is empty. If the code surrounding our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loop
ensures that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loop is never reached in that case, all is well. But if
we execute our loop with an empty &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt;, C++ makes trouble for us.&lt;/p&gt;

&lt;h2 id=&quot;unsigned-types-to-the-unrescue&quot;&gt;Unsigned Types to the Unrescue&lt;/h2&gt;

&lt;p&gt;Recall that
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#on_unsigned_integers&quot;&gt;our style guide warns&lt;/a&gt;
against use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unsigned&lt;/code&gt; types in C++. The style guide also says&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Because of historical accident, the C++ standard also uses unsigned integers
to represent the &lt;strong&gt;size of containers&lt;/strong&gt; - many members of the standards body
believe this to be a mistake, but it is effectively impossible to fix at this
point.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(emphasis added)&lt;/p&gt;

&lt;p&gt;Looking carefully, we can see that our example falls afoul of the exact problem
discussed in the style guide. When checking whether we have valid &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v[i]&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v[i+1]&lt;/code&gt; elements, we are seemingly correct in checking whether &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt; is less than
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v.size() - 1&lt;/code&gt; given that both elements need to be valid. However, for an empty
container &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v.size()&lt;/code&gt; is zero (so far, so good!), but because the type of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v.size()&lt;/code&gt; is unsigned, when we subtract one from that zero, we don’t get the
value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-1&lt;/code&gt;, but instead we get the &lt;em&gt;maximum&lt;/em&gt; value of the given type. Then the
check for whether &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt; is less than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v.size() - 1&lt;/code&gt; evaluates as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; for any
small value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt;, and so the code will use out-of-bounds indexes for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; -
yielding undefined behavior.&lt;/p&gt;

&lt;h2 id=&quot;how-should-we-fix-this&quot;&gt;How Should We Fix This?&lt;/h2&gt;

&lt;p&gt;Interestingly, if we make the code express its intent a little more directly,
our problem goes away.&lt;/p&gt;

&lt;p&gt;What do we mean by “express its intent a little more directly”? What is the
intent here? The purpose of the loop condition here is to ensure that the
indexes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i + 1&lt;/code&gt; used to index into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; are valid.&lt;/p&gt;

&lt;p&gt;Given that indexes in C++ are zero-based, we test whether a (non-negative) index
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt; into a container is valid by checking &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i &amp;lt; v.size()&lt;/code&gt;. It would be redundant
to check validity of both indexes (though we could do so if we wished): if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i +
1&lt;/code&gt; is valid then we know that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt; is (because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt; is never negative here). “&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i +
1&lt;/code&gt; is valid” translates directly into C++ as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i + 1 &amp;lt; v.size()&lt;/code&gt;. Our original
code &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i &amp;lt; v.size() - 1&lt;/code&gt; does not have such a direct translation as a statement
about the validity of an index.&lt;/p&gt;

&lt;p&gt;The rewritten code &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i + 1 &amp;lt; v.size()&lt;/code&gt; looks almost the same as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i &amp;lt; v.size() -
1&lt;/code&gt;, but it is crucially different in that we never subtract, so we avoid the
danger of wrapping around to a huge positive value. Did we swap this for a risk
of overflowing when we calculate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i + 1&lt;/code&gt;? Only if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt; is already the largest
value of its type (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64_t&lt;/code&gt;) – so we are safe. This difference is sometimes
characterized by noting that the common, useful values of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64_t&lt;/code&gt; are a long
way away from overflowing, whereas with unsigned types such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint64_t&lt;/code&gt;, the
very common value 0 is the smallest value of the type, so it’s much easier to
unintentionally wrap around.&lt;/p&gt;

&lt;h2 id=&quot;fixed-code-fuzz-free&quot;&gt;Fixed Code, Fuzz Free&lt;/h2&gt;

&lt;p&gt;With this one small change, our now-robust code looks like this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
for (int64_t i = 0; i + 1 &amp;lt; v.size(); ++i) {
  ProcessPair(v[i], v[i+1]);
}
&lt;/pre&gt;

&lt;p&gt;The indexes into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; are clearly safe, without a need to look further afield to
know whether &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; might be empty.&lt;/p&gt;

&lt;p&gt;Now we can let our fuzzer loose on the fixed code, and feel warm fuzzy feelings
that our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loop is bug-free and reviewer-friendly.&lt;/p&gt;

&lt;p&gt;Note: This is just one (robust) way to write this loop; there are many others.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;While our fix doesn’t change many bytes of source code, it touches on a number
of ideas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;As the style guide
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#on_unsigned_integers&quot;&gt;says&lt;/a&gt;,
be wary of arithmetic on unsigned types in C++.&lt;/li&gt;
  &lt;li&gt;Remember that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;container.size()&lt;/code&gt; yields an unsigned type.&lt;/li&gt;
  &lt;li&gt;Prefer code where correctness can be verified as locally as possible.&lt;/li&gt;
  &lt;li&gt;Try to make code correspond as directly as possible to the underlying
intent.&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2024-03-21T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/227</link>
          <guid isPermaLink="true">https://abseil.io/tips/227</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #224: Avoid &lt;code&gt;vector.at()&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #224 on August 24, 2023&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:titus@cs.ucr.edu&quot;&gt;Titus Winters&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2024-01-24&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/224&quot;&gt;abseil.io/tips/224&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is no good use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&amp;lt;T&amp;gt;::at()&lt;/code&gt; in google3, and fairly few good uses
in other C++ environments. The same reasoning applies to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; on other
random-access sequences like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RepeatedPtrField&lt;/code&gt; in protobuf, as well as to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value()&lt;/code&gt; on wrapper types like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-does-at-do&quot;&gt;What Does &lt;code&gt;at()&lt;/code&gt; Do?&lt;/h2&gt;

&lt;p&gt;The specification of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at(size_type pos)&lt;/code&gt; is as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Returns a reference to the element at specified location &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pos&lt;/code&gt;, with bounds
checking. If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pos&lt;/code&gt; is not within the range of the container, an exception of
type std::out_of_range is thrown.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means we could view the contract of this method as two distinct behaviors:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Check whether &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pos &amp;gt;= size()&lt;/code&gt;, and if so then throw a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::out_of_range&lt;/code&gt;
exception.&lt;/li&gt;
  &lt;li&gt;Otherwise, return the element at index &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pos&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: The specification does not directly address the case of code passing a
negative index, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::out_of_range&lt;/code&gt; will be thrown for that case too –
because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size_type&lt;/code&gt; is an &lt;em&gt;unsigned&lt;/em&gt; integral type, a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at(-5)&lt;/code&gt; will
yield a very large positive value for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pos&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;when-would-we-use-at&quot;&gt;When Would We Use &lt;code&gt;at()&lt;/code&gt;?&lt;/h2&gt;

&lt;p&gt;Since the contract of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; depends on the bounds-checking logic, we can break
this into two cases: either we know by construction that the index is valid, or
we don’t.&lt;/p&gt;

&lt;p&gt;If we already know that the sequence is sufficiently large and the lookup will
succeed, the extra bounds check is overhead. Most &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; accesses, for
instance, are as part of a loop from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size()&lt;/code&gt; and we already know the
operation will succeed. Therefore, in cases where we already know the bounds
check will be successful, it’s likely that we want the more common
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator[]()&lt;/code&gt;.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt; {.bad}
for (int i = 0; i + 1 &amp;lt; vec.size(); ++i) {
  ProcessPair(vec.at(i), vec.at(i + 1));
}
&lt;/pre&gt;

&lt;p&gt;becomes&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt; {.good}
for (int i = 0; i + 1  &amp;lt; vec.size(); ++i) {
  ProcessPair(vec[i], vec[i + 1]);
}
&lt;/pre&gt;

&lt;p&gt;If we do &lt;strong&gt;not&lt;/strong&gt; know that the sequence is sufficiently large, is throwing an
exception the right way to handle that? Usually not. In google3 builds, throwing
an exception will terminate the program, messily. Many (perhaps most) readers
won’t necessarily spot an innocuously named method like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; as a process
termination risk.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt; {.bad}
std::vector&amp;lt;absl::string_view&amp;gt; tokens = absl::StrSplit(user_string, ByChar(&apos;,&apos;));
LOG(INFO) &amp;lt;&amp;lt; &quot;Got leading token &quot; &amp;lt;&amp;lt; tokens.at(0);
&lt;/pre&gt;

&lt;p&gt;is probably better as&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt; {.good}
std::vector&amp;lt;absl::string_view&amp;gt; tokens = absl::StrSplit(user_string, ByChar(&apos;,&apos;));
if (tokens.empty()) {
  return absl::InvalidArgumentError(&quot;Invalid user_string, expected &apos;,&apos;&quot;);
}
&lt;/pre&gt;

&lt;p&gt;or if aborting the program is preferable&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt; {.good}
std::vector&amp;lt;absl::string_view&amp;gt; tokens = absl::StrSplit(user_string, ByChar(&apos;,&apos;));
CHECK(!tokens.empty()) &amp;lt;&amp;lt; &quot;Invalid user_string &quot;
                       &amp;lt;&amp;lt; std::quoted(user_string)
                       &amp;lt;&amp;lt; &quot;, expected at least one &apos;,&apos;&quot;;
&lt;/pre&gt;

&lt;p&gt;So at least in a google3 context, none of the uses of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; are really useful —
for any given use case, there is a more preferred alternative.&lt;/p&gt;

&lt;h2 id=&quot;what-about-ub&quot;&gt;What About UB?&lt;/h2&gt;

&lt;p&gt;Unfortunately, reality is hardly so clean as “we know or we don’t”: we make
mistakes and code can change over time, invalidating originally correct
assumptions. Given that humans are fallible, we can &lt;em&gt;imagine&lt;/em&gt; a use-case for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt;. Specifically, if we are completely consistent in using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; instead of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator[]&lt;/code&gt;, we might ensure that even if we’re crashing messily (&lt;em&gt;bad&lt;/em&gt;), we
don’t trigger &lt;a href=&quot;/tips/labs/ub-and-you&quot;&gt;undefined behavior (UB)&lt;/a&gt; (&lt;em&gt;worse&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;While we believe “avoid UB” is a very legitimate goal, we still don’t endorse
the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt;, specifically, because of its exception-entangled semantics,
discussed above. The ideal future solution is a hardened-by-default
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator[]&lt;/code&gt;, with compiler optimizations to remove bounds checking, when
provably safe. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; method is a bad approximation of this solution.&lt;/p&gt;

&lt;p&gt;Instead, we encourage users to stick with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator[]&lt;/code&gt; and reduce exposure to UB
by other means, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;If your project can afford it, we recommend also enabling bounds check in
production in other libraries where available.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If you run your code with &lt;a href=&quot;https://github.com/google/sanitizers/wiki/AddressSanitizer&quot;&gt;ASAN&lt;/a&gt; you’ll &lt;em&gt;also&lt;/em&gt; get diagnostics if you
access an element out of range.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In fact, your project is likely already relying on some of these protections!&lt;/p&gt;

&lt;h2 id=&quot;what-about-maps&quot;&gt;What About Maps?&lt;/h2&gt;

&lt;p&gt;In &lt;a href=&quot;/tips/202&quot;&gt;Tip #202&lt;/a&gt; we discussed the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; on associative
containers like maps and sets. In general, the error-handling logic above
applies: it’s likely the case that a missing key should be handled by logging or
returning an error, rather than messily crashing the process.&lt;/p&gt;

&lt;p&gt;However, the “bounds checking” overhead logic is different for these containers.
In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; case, the compute cost of doing the bounds check is similar
to the cost of doing the actual work (returning the indicated reference). For
associative containers, the “bounds check” equivalent is doing the (necessary)
lookup, whether that is tree traversal, hashing, etc.&lt;/p&gt;

&lt;p&gt;Following that reasoning, we might use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; when we know the key is present
already (no exception throwing) but were unable to keep an iterator or
reference, so it is necessary to perform the lookup again. This is pretty rare:
see &lt;a href=&quot;/tips/132&quot;&gt;Tip #132&lt;/a&gt; for ways to avoid redundant map lookups.&lt;/p&gt;

&lt;p&gt;In the end, there’s some minor room for usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; in associative
containers. There is more room for nuance in those cases than there is for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-about-c-with-exceptions&quot;&gt;What About C++ With Exceptions?&lt;/h2&gt;

&lt;p&gt;In an exceptions-enabled environment, opinions may differ a bit more when it
comes to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt;. It’s still broadly the case that explicit bounds checking is
likely better performance (and harder to mess up) than relying on exceptions. An
argument could be made for defense-in-depth prevention of UB, but it’s fairly
clear that the idiom is (and will continue to be) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator[]()&lt;/code&gt; rather than
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ideally, code should make as few assumptions as it can about the environment in
which it will work. Reasoning about code based on which toolchains will be used
to compile it is often fragile. For code that uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; (or another
exception-based API) to be correct, it needs to be correct for two different
build modes: it must be acceptable to terminate the entire process &lt;em&gt;and&lt;/em&gt; it must
be acceptable for code at a higher level to catch the exception and continue
execution, so the library code must preserve all invariants. In practice that
means that the code must be exception-safe &lt;em&gt;and&lt;/em&gt; that it must be OK for any
out-of-bounds use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; to terminate the process.&lt;/p&gt;

&lt;p&gt;The best advice we can give about use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at()&lt;/code&gt; in an exception-enabled
environment is perhaps that it trades a reduction in potential UB for hidden and
often unnecessary error handling. That isn’t always a clear tradeoff, but it
still seems unlikely to be commonly worth the cost.&lt;/p&gt;

&lt;h2 id=&quot;closing-thoughts&quot;&gt;Closing Thoughts&lt;/h2&gt;

&lt;p&gt;When indexing into a container, be mindful of which case we are in: is the index
“correct by construction”, or does the code need to detect and handle invalid
indexes? In both cases we can do better than using the exception-based
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;T&amp;gt;::at()&lt;/code&gt; API.&lt;/p&gt;

&lt;p&gt;Similar thinking applies to other exception-based APIs such as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;T&amp;gt;::value()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;::value()&lt;/code&gt; (See
&lt;a href=&quot;/tips/181&quot;&gt;Tip #181&lt;/a&gt;). For error handling in non-concurrent C++ code, prefer to
“look before you leap” – and then, having checked that things are in order,
avoid APIs that include their own checking.&lt;/p&gt;

</description>
          <pubDate>2024-03-21T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/224</link>
          <guid isPermaLink="true">https://abseil.io/tips/224</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #75: How to microbenchmark</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #75 on September 29, 2023&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-10-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/75&quot;&gt;abseil.io/fast/75&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine having access to two Oracles. One gives 90% accurate predictions and
responds in 10 minutes and one that gives 99% accurate predictions and responds
in 1 month. With access to these secret seers, which will let us be best able to
make good decisions?&lt;/p&gt;

&lt;p&gt;“&lt;a href=&quot;/fast/39&quot;&gt;Production is ultimately what matters&lt;/a&gt;” might obviate the need for
microbenchmarks altogether, but they are a useful tool in the performance
optimization toolbox. While reduced fidelity doesn’t sound desirable at face
value, it comes with an important tradeoff: speed.&lt;/p&gt;

&lt;p&gt;In this episode, we discuss techniques for using microbenchmarks as an important
tool for decision-making. Full documentation for the microbenchmark framework is
available at https://github.com/google/benchmark/blob/main/docs/user_guide.md.&lt;/p&gt;

&lt;h2 id=&quot;preliminaries&quot;&gt;Preliminaries&lt;/h2&gt;

&lt;p&gt;Eli Bendersky has written about a
&lt;a href=&quot;https://eli.thegreenplace.net/2023/common-pitfalls-in-go-benchmarking/&quot;&gt;number of pitfalls&lt;/a&gt;
that can come up when using microbenchmarks. In writing our own series of
microbenchmarks to evaluate a
&lt;a href=&quot;https://protobuf.dev/programming-guides/encoding/#varints&quot;&gt;varint&lt;/a&gt; parser,
we’ll apply several of these techniques to get useful answers.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
template&amp;lt;bool DoBMI = false&amp;gt;
const uint8_t* ParseVarint32(const uint8_t* buf, uint32_t* value) {
  uint8_t byte;
  int count = 0;
  uint32_t tmp = 0;
  if (DoBMI) {
#ifdef __BMI2__
#ifndef ABSL_IS_LITTLE_ENDIAN
#error &quot;Only supports little endian architectures&quot;
#endif
    // Read 8 bytes.   This requires our input buffer be appropriately padded to
    // permit an overread.
    uint64_t r;
    memcpy(&amp;amp;r, buf, sizeof(r));

    int length = (absl::countr_zero(~r &amp;amp; uint64_t{0x8080808080}) &amp;gt;&amp;gt; 3) + 1;
    buf = buf + length;
    *value = _bzhi_u64(_pext_u64(r, uint64_t{0x7F7F7F7F7F}), 7 * length);
    return buf;
#endif  // __BMI2__
  }
  do {
    byte = buf[0];
    tmp |= (byte &amp;amp; 0x7F) &amp;lt;&amp;lt; (7 * count);
    ++buf;
    ++count;
  } while (byte &amp;amp; 0x80);
  *value = tmp;
  return buf;
}

void BM_OneshotVarintParsing(benchmark::State&amp;amp; state) {
  absl::BitGen rng;
  const uint32_t target = absl::Uniform(rng, 0u, std::numeric_limits&amp;lt;uint32_t&amp;gt;::max());
  uint8_t buf[10];
  const uint8_t* end_buf = WriteVarint32(buf, target);
  ABSL_CHECK(end_buf &amp;lt;= buf + sizeof(buf));

  for (auto s : state) {
    uint32_t read;
    ParseVarint32(buf, &amp;amp;read);
  }
}

BENCHMARK(BM_OneshotVarintParsing);
&lt;/pre&gt;

&lt;p&gt;Running this benchmark shows us spending 0 nanoseconds parsing. This result is
implausible and should give cause for concern.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;------------------------------------------------------------------
Benchmark                        Time             CPU   Iterations
------------------------------------------------------------------
BM_OneshotVarintParsing      0.000 ns        0.000 ns   1000000000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Annotating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt; with
&lt;a href=&quot;https://github.com/google/benchmark/blob/main/docs/user_guide.md#preventing-optimization&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;benchmark::DoNotOptimize&lt;/code&gt;&lt;/a&gt;
produces more realistic results. This prevents the compiler from recognizing
that the return value is unused and eliminating the loop body. We also add
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ABSL_DCHECK_EQ&lt;/code&gt; to verify the result is correct. While this will be a no-op in
optimized builds, this is a lightweight way to double-check the calculation to
make sure our microbenchmark is functionally correct.&lt;/p&gt;

&lt;p&gt;Nevertheless, the benchmark varies from run-to-run:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;------------------------------------------------------------------
Benchmark                        Time             CPU   Iterations
------------------------------------------------------------------
BM_OneshotVarintParsing       5.31 ns         5.29 ns    131846276
...
BM_OneshotVarintParsing       4.37 ns         4.36 ns    132147859
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since we are targeting a variable length integer, chosen via a random number
generator, we aren’t doing a consistent amount of work. The vast majority of
integers in the range &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0, UINT_MAX]&lt;/code&gt; will be encoded as several bytes, but
sometimes we’ll choose a small integer and skew our benchmark results.
Separately benchmarking by varint size lets us differentiate these cases.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
void BM_OneshotVarintParsingSingleWidth(benchmark::State&amp;amp; state) {
  const int shift = state.range(0);
  absl::BitGen rng;
  const uint64_t lo = 1u &amp;lt;&amp;lt; (7 * shift);
  const uint64_t hi = std::min&amp;lt;uint64_t&amp;gt;((lo &amp;lt;&amp;lt; 7) - 1u, UINT_MAX);
  const uint32_t target = absl::Uniform&amp;lt;uint32_t&amp;gt;(rng, lo, hi);

  uint8_t buf[10];
  const uint8_t* end_buf = WriteVarint32(buf, target);
  ABSL_CHECK(end_buf &amp;lt;= buf + sizeof(buf));

  for (auto s : state) {
    uint32_t read;
    ParseVarint32(buf, &amp;amp;read);
    benchmark::DoNotOptimize(read);
    ABSL_DCHECK_EQ(read, target);
  }
}

BENCHMARK(BM_OneshotVarintParsingSingleWidth)-&amp;gt;DenseRange(0, 4);
&lt;/pre&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BM_OneshotVarintParsingSingleWidth/0              0.955 ns        0.955 ns    749769481
BM_OneshotVarintParsingSingleWidth/1               1.61 ns         1.61 ns    434548050
BM_OneshotVarintParsingSingleWidth/2               2.12 ns         2.12 ns    333038803
BM_OneshotVarintParsingSingleWidth/3               2.80 ns         2.80 ns    250300587
BM_OneshotVarintParsingSingleWidth/4               3.27 ns         3.27 ns    215507384
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;gauging-latency&quot;&gt;Gauging latency&lt;/h2&gt;

&lt;p&gt;Real-world parsing does not parse a single varint at a time like the previous
benchmark does, and that can have some profound effects on what we measure. For
example, there, since we’re iterating over the same buffer, and there’s no
dependency on the last value, the processor is very likely to be able to
speculatively start the next iteration and won’t need to undo the work. This
converts a benchmark that we’d like to measure as a
&lt;a href=&quot;/fast/99&quot;&gt;chain of dependencies&lt;/a&gt; into a measurement of the number of pipelines
that the processor has (or the duration of the dependency chain divided by the
number of parallel executions).&lt;/p&gt;

&lt;p&gt;To make the benchmark more realistic, we can instead parse from a larger buffer
of varints serialized end-on-end:&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
void BM_VarintParsingEndOnEnd(benchmark::State&amp;amp; state) {
  const int shift = state.range(0);
  absl::BitGen rng;
  const uint64_t lo = 1u &amp;lt;&amp;lt; (7 * shift);
  const uint64_t hi = std::min&amp;lt;uint64_t&amp;gt;((lo &amp;lt;&amp;lt; 7) - 1u, UINT_MAX);
  const uint32_t target = absl::Uniform&amp;lt;uint32_t&amp;gt;(rng, lo, hi);

  const int kNumVarints = 10000;
  std::vector&amp;lt;uint8_t&amp;gt; v(5 * kNumVarints, 0);
  uint8_t* buf = &amp;amp;v[0];
  for (int i = 0; i &amp;lt; kNumVarints; ++i) {
    buf = WriteVarint32(buf, target);
  }
  const uint8_t* const end_buf = buf;

  // Use KeepRunningBatch to get an accurate, per-item timing.
  while (state.KeepRunningBatch(kNumVarints)) {
    // Start from the top, so we don&apos;t just run a single meaningful
    // iteration and stop.
    const uint8_t* read_buf = &amp;amp;v[0];
    while (read_buf &amp;lt; end_buf) {
      uint32_t read;
      read_buf = ParseVarint32(read_buf, &amp;amp;read);
      benchmark::DoNotOptimize(read);
      ABSL_DCHECK_EQ(read, target);
    }
  }

  state.SetItemsProcessed(state.iterations() * kNumVarints);
}
&lt;/pre&gt;

&lt;p&gt;We use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;KeepRunningBatch&lt;/code&gt; since each iteration is processing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kNumVarint&lt;/code&gt;
elements at a time, rather than 1 element.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BM_VarintParsingEndOnEnd/0                        0.933 ns        0.933 ns    749030000 bytes_per_second=1022.04Mi/s items_per_second=1.07169G/s
BM_VarintParsingEndOnEnd/1                         1.64 ns         1.64 ns    432610000 bytes_per_second=1.13844Gi/s items_per_second=611.197M/s
BM_VarintParsingEndOnEnd/2                         2.16 ns         2.16 ns    331480000 bytes_per_second=1.2962Gi/s items_per_second=463.928M/s
BM_VarintParsingEndOnEnd/3                         3.11 ns         3.11 ns    249780000 bytes_per_second=1.19976Gi/s items_per_second=322.058M/s
BM_VarintParsingEndOnEnd/4                         3.27 ns         3.27 ns    216500000 bytes_per_second=1.42589Gi/s items_per_second=306.208M/s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This approach lets us gauge how quickly we figure out the next place to
deserialize and there’s a dependency between the end of the previous iteration
and the start of the next. Still note, however, that since the varint sizes are
invariant, the processor can likely speculate on the next iteration due to
successful &lt;a href=&quot;https://en.wikipedia.org/wiki/Branch_predictor&quot;&gt;branch prediction&lt;/a&gt;,
so this is by no means perfect.&lt;/p&gt;

&lt;p&gt;This technique can also be employed for other algorithms, such as hashing,
hashtable lookups, and SIMD problems. It can also be helpful for understanding
when the processor’s execution
&lt;a href=&quot;https://llvm.org/docs/CommandGuide/llvm-mca.html&quot;&gt;backends are port-bound or otherwise lead to a long-critical path&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When applying this technique, we may need to look at the disassembly for our
benchmark to ensure that we carry a data dependency across loop iterations.
Control flow can be subject to speculation that defeats our attempt at
constructing a latency-focused benchmark. This can often arise when working with
booleans, for example, a benchmark that exercises &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;contains&lt;/code&gt; on a set should
have similar performance to one that does &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt;. While this can be sometimes
fixed through heavy application of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoNotOptimize&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClobberMemory&lt;/code&gt;, the cure
may be worse than the disease.&lt;/p&gt;

&lt;h2 id=&quot;understanding-the-speed-of-light&quot;&gt;Understanding the speed of light&lt;/h2&gt;

&lt;p&gt;Before embarking too far on optimizing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ParseVarint32&lt;/code&gt; routine, we might
want to identify the &lt;a href=&quot;/fast/72&quot;&gt;“speed of light”&lt;/a&gt; of the hardware. For varint
parsing, this is &lt;em&gt;approximately&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt;, since we are reading serialized bytes
and writing the (mostly expanded) bytes into the parsed data structure. While
this is not quite the operation we’re interested in, it’s readily available off
the shelf without much effort.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
void BM_Memcpy(benchmark::State&amp;amp; state) {
  const int shift = state.range(0);
  const int kNumVarints = 10000;
  // Simulate the skeleton of BM_VarintParsingEndOnEnd by memcpy&apos;ing, to
  // understand the approximate &quot;speed of light&quot; of the operation.
  std::vector&amp;lt;uint8_t&amp;gt; src(5 * kNumVarints, 0);
  std::vector&amp;lt;uint8_t&amp;gt; dst(5 * kNumVarints, 0);

  while (state.KeepRunningBatch(kNumVarints)) {
    memcpy(&amp;amp;dst[0], &amp;amp;src[0], (shift + 1) * kNumVarints);
    benchmark::DoNotOptimize(&amp;amp;src[0]);
    benchmark::DoNotOptimize(&amp;amp;dst[0]);
  }

  state.SetBytesProcessed(state.iterations() * (shift + 1));
}

BENCHMARK(BM_Memcpy)-&amp;gt;DenseRange(0, 4);
&lt;/pre&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BM_Memcpy/0                               0.027 ns        0.027 ns   1000000000 bytes_per_second=34.9201Gi/s
BM_Memcpy/1                               0.053 ns        0.053 ns   1000000000 bytes_per_second=35.3181Gi/s
BM_Memcpy/2                               0.080 ns        0.079 ns   1000000000 bytes_per_second=35.1449Gi/s
BM_Memcpy/3                               0.106 ns        0.106 ns   1000000000 bytes_per_second=35.308Gi/s
BM_Memcpy/4                               0.134 ns        0.133 ns   1000000000 bytes_per_second=34.9284Gi/s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s also important to do a rough double-check of these numbers. 0.027ns per
“operation” should normally seem implausibly fast and set off alarm bells, but
on a 2Ghz processor we might be issuing a 32-byte load and store every clock
cycle. Each “varint” here is a single byte in the fastest case and 0.027ns is
approximately ~36 bytes per nanosecond or ~18 bytes per clock, which aligns with
the processor’s abilities.&lt;/p&gt;

&lt;h2 id=&quot;increasing-representativeness&quot;&gt;Increasing representativeness&lt;/h2&gt;

&lt;p&gt;This particular benchmark works by parsing a single, varint width at a time.
Once we shifted to the end-on-end buffer style, we can actually choose a random
distribution of varint sizes. Varints shine when values are small and we can
roughly assume that the distribution is accordingly small-skewed. Production
profiles largely validate this assumption.&lt;/p&gt;

&lt;p&gt;Using a synthetic distribution (like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::LogUniform&lt;/code&gt;) can help us simulate
this. This helps fight one pitfall of microbenchmarks by using more realistic
data and avoiding “training” the branch-predictor too well.&lt;/p&gt;

&lt;p&gt;NOTE: We want to strike a balance between improving representativeness enough to
avoid chasing dead ends while simultaneously not adding so much complexity that
our time would be better spent using more accurate methods like loadtests or
production evaluation. Some of the &lt;a href=&quot;/fast/39&quot;&gt;pitfalls of microbenchmarks&lt;/a&gt; are
inescapable, so the solution is to recognize the benchmark’s limitations rather
than try to fully eliminate them.&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
void BM_VarintParsingSkewed(benchmark::State&amp;amp; state) {
  absl::BitGen rng;

  const int kNumVarints = 10000;
  std::vector&amp;lt;uint8_t&amp;gt; v(5 * kNumVarints, 0);
  uint8_t* buf = &amp;amp;v[0];
  for (int i = 0; i &amp;lt; kNumVarints; ++i) {
    // Initialize using a small-skewed value to create a synthetic distribution
    // of non-uniform varint sizes that roughly resemble real world ones.
    buf = WriteVarint32(
        buf, absl::LogUniform(rng, 0u, std::numeric_limits&amp;lt;uint32_t&amp;gt;::max()));
  }
  const uint8_t* const end_buf = buf;

  // Use KeepRunningBatch to get an accurate, per-item estimate of cost,
  // invariant from kNumVarints value.
  while (state.KeepRunningBatch(kNumVarints)) {
    // Start from the top every time, otherwise we run the loop once and stop,
    // so per-item speeds are infinitely fast.
    const uint8_t* read_buf = &amp;amp;v[0];
    while (read_buf &amp;lt; end_buf) {
      uint32_t read;
      read_buf = ParseVarint32(read_buf, &amp;amp;read);
      benchmark::DoNotOptimize(read);
    }
  }

  state.SetItemsProcessed(state.iterations());
  state.SetBytesProcessed(state.iterations() * (end_buf - &amp;amp;v[0]) / kNumVarints);
}
&lt;/pre&gt;

&lt;p&gt;We can use the benchmark library’s
&lt;a href=&quot;/fast/53&quot;&gt;built-in performance counter feature&lt;/a&gt; to capture per-benchmark
statistics around branch mispredictions
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--benchmark_perf_counters=BR_MISP_RETIRED:ALL_BRANCHES&lt;/code&gt;). This confirms that
we processed enough varints (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kNumVarints = 10000&lt;/code&gt;) to overwhelm the branch
predictor’s ability to memorize the input pattern.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BM_VarintParsingEndOnEnd/0                        0.933 ns        0.933 ns    749030000 BR_MISP_RETIRED:ALL_BRANCHES=100.032u bytes_per_second=1022.04Mi/s items_per_second=1.07169G/s
BM_VarintParsingEndOnEnd/1                         1.64 ns         1.64 ns    432610000 BR_MISP_RETIRED:ALL_BRANCHES=100.999u bytes_per_second=1.13844Gi/s items_per_second=611.197M/s
BM_VarintParsingEndOnEnd/2                         2.16 ns         2.16 ns    331480000 BR_MISP_RETIRED:ALL_BRANCHES=8.9521m bytes_per_second=1.2962Gi/s items_per_second=463.928M/s
BM_VarintParsingEndOnEnd/3                         3.11 ns         3.11 ns    249780000 BR_MISP_RETIRED:ALL_BRANCHES=328.881u bytes_per_second=1.19976Gi/s items_per_second=322.058M/s
BM_VarintParsingEndOnEnd/4                         3.27 ns         3.27 ns    216500000 BR_MISP_RETIRED:ALL_BRANCHES=112.993u bytes_per_second=1.42589Gi/s items_per_second=306.208M/s
BM_VarintParsingSkewed                             5.66 ns         5.66 ns    123440000 BR_MISP_RETIRED:ALL_BRANCHES=0.762816 bytes_per_second=465.11Mi/s items_per_second=176.563M/s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can back out the approximate item size from these throughputs as roughly
465/176, or ~2.6 bytes/varint on average. Because we incur more branch
mispredictions, performance is worse than any of the end-on-end inputs.&lt;/p&gt;

&lt;p&gt;For more complex benchmarks, using a randomly seeded benchmark can introduce
run-to-run instability. While this can be remedied by using fixed seeds and
deterministic distributions, this strategy risks using an aberrant input for our
benchmark. Deterministically generating a set of varied inputs and then randomly
shuffling them can help combat this.&lt;/p&gt;

&lt;h2 id=&quot;nonrepresentative&quot;&gt;Intentionally leaning into non-representativeness&lt;/h2&gt;

&lt;p&gt;With our current microbenchmark, we uniformly fit inside the processor’s L1
cache. When this tip was written, a processor with a 32KB L1 data cache was used
for the benchmark result examples. In comparison, we’re parsing a series of 1K
varints, whose length is at most 5 bytes each. This ensures that the data can
always fit into cache.&lt;/p&gt;

&lt;p&gt;The microbenchmark library framework includes helper methods (like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;benchmark::CPUInfo&lt;/code&gt;) to access information about the hardware we’re running on.
This allows us to sweep through the parameter space of cache sizes, from a
single varint (at most 5 bytes) to many multiples of the last cache’s size.
We’ll also evaluate an optimization using BMI2 (implementation omitted for
brevity).&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
template&amp;lt;bool DoBMI&amp;gt;
void BM_VarintParsingSkewedCaches(benchmark::State&amp;amp; state) {
  const int kNumVarints = state.range(0);
  absl::BitGen rng;

  // Pad input vector to permit an overread with the DoBMI implementation.
  std::vector&amp;lt;uint8_t&amp;gt; v(size_t{5} * kNumVarints + (DoBMI ? 8 : 0), 0);
  uint8_t* buf = &amp;amp;v[0];
  for (int i = 0; i &amp;lt; kNumVarints; ++i) {
    buf = WriteVarint32(buf, absl::LogUniform(rng, 1u, std::numeric_limits&amp;lt;uint32_t&amp;gt;::max()));
  }
  const uint8_t* const end_buf = buf;

  // Use KeepRunningBatch to get an accurate, per-item estimate of cost,
  // invariant from kNumVarints value.
  const uint8_t* read_buf;
  while (state.KeepRunningBatch(kNumVarints)) {
    // Start from the top every time, otherwise we run the loop once and stop,
    // so per-item speeds are infinitely fast.
    read_buf = &amp;amp;v[0];
    while (read_buf &amp;lt; end_buf) {
      uint32_t read;
      read_buf = ParseVarint32&amp;lt;DoBMI&amp;gt;(read_buf, &amp;amp;read);
      benchmark::DoNotOptimize(read);
    }
  }

  state.SetItemsProcessed(state.iterations());
  state.SetBytesProcessed(state.iterations() * (end_buf - &amp;amp;v[0]) / kNumVarints);
}

BENCHMARK_TEMPLATE(BM_VarintParsingSkewedCaches, false)
    -&amp;gt;Range(1, 4 * benchmark::CPUInfo::Get().caches.back().size);
BENCHMARK_TEMPLATE(BM_VarintParsingSkewedCaches, true)
    -&amp;gt;Range(1, 4 * benchmark::CPUInfo::Get().caches.back().size);
&lt;/pre&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/1               3.35 ns         3.34 ns    457036460 BR_MISP_RETIRED=6.03891u CYCLES=11.0191 INSTRUCTIONS=50 bytes_per_second=1.11618Gi/s items_per_second=299.622M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/8               2.13 ns         2.12 ns    268979016 BR_MISP_RETIRED=9.79259u CYCLES=7.01295 INSTRUCTIONS=31.75 bytes_per_second=1.20814Gi/s items_per_second=471.718M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/64              2.05 ns         2.05 ns    321649792 BR_MISP_RETIRED=22.9504u CYCLES=6.73112 INSTRUCTIONS=30.5938 bytes_per_second=1.23747Gi/s items_per_second=488.727M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/512             2.05 ns         2.05 ns    313550336 BR_MISP_RETIRED=1.31374m CYCLES=6.75802 INSTRUCTIONS=30.6074 bytes_per_second=1.24299Gi/s items_per_second=488.45M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/4096            6.37 ns         6.36 ns    106352640 BR_MISP_RETIRED=0.652793 CYCLES=20.8777 INSTRUCTIONS=31.0552 bytes_per_second=417.736Mi/s items_per_second=157.355M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/32768           7.97 ns         7.95 ns     89980928 BR_MISP_RETIRED=0.902907 CYCLES=26.1535 INSTRUCTIONS=30.8263 bytes_per_second=330.981Mi/s items_per_second=125.816M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/262144          8.66 ns         8.63 ns     83361792 BR_MISP_RETIRED=0.886097 CYCLES=25.8864 INSTRUCTIONS=30.7883 bytes_per_second=304.299Mi/s items_per_second=115.85M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/2097152         7.88 ns         7.86 ns     90177536 BR_MISP_RETIRED=0.886966 CYCLES=25.9592 INSTRUCTIONS=30.8173 bytes_per_second=334.775Mi/s items_per_second=127.303M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/16777216        7.91 ns         7.89 ns    100663296 BR_MISP_RETIRED=0.885126 CYCLES=26.0696 INSTRUCTIONS=30.8228 bytes_per_second=333.415Mi/s items_per_second=126.759M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/134217728       8.52 ns         8.50 ns    134217728 BR_MISP_RETIRED=0.884259 CYCLES=26.0602 INSTRUCTIONS=30.8234 bytes_per_second=309.466Mi/s items_per_second=117.651M/s
BM_VarintParsingSkewedCaches&amp;lt;false&amp;gt;/161480704       8.06 ns         8.04 ns    161480704 BR_MISP_RETIRED=0.885522 CYCLES=26.1663 INSTRUCTIONS=30.8221 bytes_per_second=327.339Mi/s items_per_second=124.452M/s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We see inflections in performance as the working set increases beyond each cache
tier. The benchmark framework can
&lt;a href=&quot;/fast/53&quot;&gt;concurrently collect performance counters&lt;/a&gt; and we also asymptote to
0.88 branch predictions per varint that we parse on average.&lt;/p&gt;

&lt;p&gt;Since our branches determine how quickly we move through the stream, we can see
an improvement by switching to a branchless implementation using BMI2. Our
performance is a bit worse for some of the small cases (where we’re already in
L1 and can memorize the branches) but asymptote to a faster per-varint speed
when working with large buffers. The PMU events show very few (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;5e-6&lt;/code&gt; per
varint) branch mispredictions.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/1                1.68 ns         1.68 ns    414588127 BR_MISP_RETIRED=31.3564n CYCLES=5.2722 INSTRUCTIONS=23 bytes_per_second=1.66702Gi/s items_per_second=596.649M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/8                2.32 ns         2.32 ns    301227112 BR_MISP_RETIRED=4.35884u CYCLES=7.43719 INSTRUCTIONS=16 bytes_per_second=1.30667Gi/s items_per_second=431.699M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/64               3.83 ns         3.82 ns    184510144 BR_MISP_RETIRED=11.3761u CYCLES=12.7085 INSTRUCTIONS=15.125 bytes_per_second=667.478Mi/s items_per_second=261.951M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/512              4.24 ns         4.23 ns    174177280 BR_MISP_RETIRED=1.954m CYCLES=13.4285 INSTRUCTIONS=15.0156 bytes_per_second=613.728Mi/s items_per_second=236.535M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/4096             4.04 ns         4.03 ns    173842432 BR_MISP_RETIRED=245.849u CYCLES=13.4066 INSTRUCTIONS=15.002 bytes_per_second=646.705Mi/s items_per_second=248.375M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/32768            4.06 ns         4.05 ns    173244416 BR_MISP_RETIRED=44.8961u CYCLES=13.4526 INSTRUCTIONS=15.0003 bytes_per_second=646.09Mi/s items_per_second=246.625M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/262144           4.40 ns         4.39 ns    173277184 BR_MISP_RETIRED=5.36135u CYCLES=13.4397 INSTRUCTIONS=15 bytes_per_second=598.464Mi/s items_per_second=227.561M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/2097152          4.07 ns         4.06 ns    142606336 BR_MISP_RETIRED=1.66192u CYCLES=13.4542 INSTRUCTIONS=15 bytes_per_second=647.626Mi/s items_per_second=246.183M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/16777216         4.07 ns         4.06 ns    184549376 BR_MISP_RETIRED=671.907n CYCLES=13.4525 INSTRUCTIONS=15 bytes_per_second=647.685Mi/s items_per_second=246.264M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/134217728        4.05 ns         4.04 ns    134217728 BR_MISP_RETIRED=1.09524u CYCLES=13.4582 INSTRUCTIONS=15 bytes_per_second=651.6Mi/s items_per_second=247.741M/s
BM_VarintParsingSkewedCaches&amp;lt;true&amp;gt;/161480704        4.01 ns         4.00 ns    161480704 BR_MISP_RETIRED=829.821n CYCLES=13.4539 INSTRUCTIONS=15 bytes_per_second=658.024Mi/s items_per_second=250.184M/s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This pattern is also used in
&lt;a href=&quot;https://github.com/google/fleetbench/blob/master/fleetbench&quot;&gt;fleetbench&lt;/a&gt;. For
example, it has a “hot” SwissMap benchmark that performs its operations
(lookups, etc.) against a single instance and a “cold” SwissMap benchmark where
we randomly pick a table on each iteration. The latter makes it more likely that
we’ll &lt;a href=&quot;/fast/62&quot;&gt;incur a cache miss&lt;/a&gt;. Hardware counters and the benchmark
framework’s &lt;a href=&quot;/fast/53&quot;&gt;support for collecting them&lt;/a&gt; can help diagnose and
explain performance differences.&lt;/p&gt;

&lt;p&gt;Even though the extremes are not representative, they can help us frame how to
tackle the problem. We might find an optimization for one extreme and then work
on it to hold performance for the other extremes constant.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;In conclusion, microbenchmarks can be a useful technique for quickly exploring
the performance landscape. Unlike macrobenchmarks which might take hours to
complete to get reliable signals, microbenchmarks can give us information in a
minute or two to make a better decision for what to try next while working on a
problem.&lt;/p&gt;

&lt;p&gt;While microbenchmarks are no substitute for using
&lt;a href=&quot;/fast/39&quot;&gt;progressively more realistic benchmarks and evaluating production&lt;/a&gt;,
imperfect information lets us iterate more quickly to achieve a better solution
to perform a final, production evaluation and landing.&lt;/p&gt;
</description>
          <pubDate>2023-11-10T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/75</link>
          <guid isPermaLink="true">https://abseil.io/fast/75</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #74: Avoid sweeping street lights under rugs</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #74 on September 29, 2023&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt; and &lt;a href=&quot;mailto:kfm@google.com&quot;&gt;Matt Kulukundis&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-10-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/74&quot;&gt;abseil.io/fast/74&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While their issues go by multiple names (i.e.
&lt;a href=&quot;https://en.wikipedia.org/wiki/Streetlight_effect&quot;&gt;the streetlight effect&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/McNamara_fallacy&quot;&gt;the McNamara fallacy&lt;/a&gt;), proxy
metrics present a seductive danger. Simply put, people often focus on improving
the things they can measure and neglecting the things they cannot even if those
other things are important. In this episode, we explore multiple stories of how
this can go wrong to help ground ourselves in the real world failure modes that
&lt;a href=&quot;/fast/70&quot;&gt;proxy metrics&lt;/a&gt; present.&lt;/p&gt;

&lt;p&gt;Most folks are familiar with the streetlight effect’s titular story:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A police officer sees a drunkard searching for something under a streetlight
and asks what the drunk has lost. They says they lost their keys and the two
look under the streetlight together. After a few minutes the policeman asks if
they is sure they lost them here, and the drunk replies, no, and that they
lost the keys in the park. The policeman asks why they are searching here, and
the drunk replies, “this is where the light is”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But there is an analog that is equally dangerous.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A trash collector assigned to keep the streets free of litter may simply sweep
the litter away from the street lights, thereby leaving the street visibly
clean.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;the-data-center-tax&quot;&gt;The “Data Center Tax”&lt;/h2&gt;

&lt;p&gt;In
&lt;a href=&quot;https://research.google/pubs/pub44271/&quot;&gt;“Profiling a Warehouse-Scale Computer”&lt;/a&gt;,
Svilen Kanev, et. al., coined the term, the “data center tax.” While a small
part of every single application, the commonly used libraries could add up at
scale when viewed horizontally. At the time in 2015, TCMalloc was as large as
the biggest single application. This view on the data helps make these
horizontal overheads
“&lt;a href=&quot;https://en.wikipedia.org/wiki/Seeing_Like_a_State&quot;&gt;legible&lt;/a&gt;,” bringing an
order to the chaos of understanding where fleet costs go. This analysis
motivated a strategy of reducing these overheads as a relative portion of the
fleet.&lt;/p&gt;

&lt;p&gt;Nevertheless, there are places where externalities, both positive and negative,
get overlooked. Focusing on the easily observed costs can cause us to miss
opportunities for greater impact. We’ll start with several examples of where
trying to reduce easily understood costs would have led to a worse outcome.&lt;/p&gt;

&lt;h3 id=&quot;artificial-costs-in-tcmalloc&quot;&gt;Artificial costs in TCMalloc&lt;/h3&gt;

&lt;p&gt;Starting from 2016, work commenced to reduce TCMalloc’s cost. Much of this early
work involved making things generally faster, by removing instructions,
&lt;a href=&quot;/fast/62&quot;&gt;avoiding cache misses&lt;/a&gt;, and shortening lock critical sections.&lt;/p&gt;

&lt;p&gt;During this process, a prefetch was added on its fast path. Our
&lt;a href=&quot;https://research.google/pubs/google-wide-profiling-a-continuous-profiling-infrastructure-for-data-centers/&quot;&gt;fleet-wide profiling&lt;/a&gt;
even indicates that 70%+ of cycles in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt; fastpath are
&lt;a href=&quot;/fast/39&quot;&gt;spent on that prefetch&lt;/a&gt;! Guided by the costs we could easily
understand, we might be tempted to remove it. TCMalloc’s fast path would appear
cheaper, but other code somewhere else would experience a cache miss and
&lt;a href=&quot;/fast/7&quot;&gt;application productivity&lt;/a&gt; would decline.&lt;/p&gt;

&lt;p&gt;To make matters worse, the cost is partly &lt;a href=&quot;/fast/94&quot;&gt;a profiling artifact&lt;/a&gt;. The
TLB miss blocks instruction retirement, but our processors are superscalar,
out-of-order behemoths. The processor can continue to execute further
instructions in the meantime, but this execution is not visible to a sampling
profiler like Google-Wide Profiling. IPC in the application may be improved, but
not in a way immediately associated with TCMalloc.&lt;/p&gt;

&lt;h3 id=&quot;hidden-context-switch-costs&quot;&gt;Hidden context switch costs&lt;/h3&gt;

&lt;p&gt;We can observe the apparent cost of context switches by running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;perf&lt;/code&gt; and
collecting PMU data from the processor. We end up running into two problems.&lt;/p&gt;

&lt;p&gt;Running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;perf&lt;/code&gt; to collect PMU events
&lt;a href=&quot;https://en.wikipedia.org/wiki/Heisenbug&quot;&gt;perturbs&lt;/a&gt; the system. Collecting PMU
events increases the overhead of context switches, to maintain the bookkeeping
required for it.&lt;/p&gt;

&lt;p&gt;The kernel cost is &lt;em&gt;legible&lt;/em&gt;, and has been subject to
&lt;a href=&quot;https://arxiv.org/pdf/1806.07480.pdf&quot;&gt;substantial optimization&lt;/a&gt;. Changing from
one process to another invalidates caches and
&lt;a href=&quot;https://en.wikipedia.org/wiki/Kernel_page-table_isolation&quot;&gt;the TLB&lt;/a&gt;. These will
manifest as misses and stalls for ordinary user code, completely disconnected
from the context switch itself.&lt;/p&gt;

&lt;p&gt;We see a similar effect from changing scheduling parameters. Preferring to keep
threads on the same core will improve cache locality, even though it may
increase apparent kernel scheduler latency.&lt;/p&gt;

&lt;h3 id=&quot;sweeping-away-protocol-buffers&quot;&gt;Sweeping away protocol buffers&lt;/h3&gt;

&lt;p&gt;Consider an extreme example. When &lt;a href=&quot;/fast/26&quot;&gt;our hashtable profiler&lt;/a&gt; for
Abseil’s hashtables indicates a problematic hashtable, a user could switch the
offending table from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt;. Since the
profiler doesn’t collect information about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std&lt;/code&gt; containers, the offending table
would no longer show up, although the fleet itself would be dramatically worse.&lt;/p&gt;

&lt;p&gt;While the above example may seem contrived, an almost entirely analogous
recommendation comes up with some regularity: migrate users from protos to
structs. Due to its ubiquity, Protobuf has a large cost across the fleet.&lt;/p&gt;

&lt;p&gt;It is true the structs have benefits in terms of simplicity. They have fewer
features, are generally lower cost to the compiler, and lack &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hasbit&lt;/code&gt;s. But they
also have drawbacks, they lack support for arena allocation strategies,
debugging affordances, and centralized optimizations.&lt;/p&gt;

&lt;p&gt;Rewriting protobufs to use hand-written &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;’s completely eliminates their
contribution to our horizontal data, but still shifts the costs elsewhere.
Migrations from internal protos to structs can produce very large performance
wins, but these usually come by simplifying the surrounding code and dropping
unused things. In other words, these migrations are usually catalysts for
identifying room-at-the-middle of the stack for changing &lt;em&gt;how&lt;/em&gt; APIs are used to
make code more efficient.&lt;/p&gt;

&lt;p&gt;Using protos alone or using structs alone will likely produce better wins than
mixing and matching as it exposes the code to fewer copies and a smaller set of
&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2125r0.pdf&quot;&gt;vocabulary types&lt;/a&gt;.
For example, converting back and forth between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Cord&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;
can prove to be costly. While hand-rolled data structures might afford better
optimizations upfront, these can often be brought back directly into the proto
implementation–or where that is not practical, suggests a copy might be needed
to interconvert.&lt;/p&gt;

&lt;h2 id=&quot;optimizing-for-externalities&quot;&gt;Optimizing for externalities&lt;/h2&gt;

&lt;p&gt;We can use the problems and pitfalls of legible indicators to find opportunities
to surface more data and uncover new optimizations. Thinking about the next
metric to improve can help us understand the full scope of a single optimization
and help us see the overall picture.&lt;/p&gt;

&lt;h3 id=&quot;seeing-through-reference-counting-and-allocations&quot;&gt;Seeing through reference counting and allocations&lt;/h3&gt;

&lt;p&gt;TCMalloc’s heap profiling feature tracks where memory is &lt;em&gt;allocated&lt;/em&gt;. For
long-lived, reference-counted objects, this view of the data is misleading. The
code responsible for holding the last reference to the object may be completely
unrelated to where it is allocated.&lt;/p&gt;

&lt;p&gt;For example, our RPC framework is one of the largest sources of memory
allocations in the fleet. It allocates memory that is held in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Cord&lt;/code&gt;.
Since the framework does the allocation it looks like it is to blame for the
memory usage. In reality, the application that holds onto the memory and
identifying why/how the application holds the memory is the key to reducing
memory footprint.&lt;/p&gt;

&lt;p&gt;This problem motivated building a profiler for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Cord&lt;/code&gt;s. Rather than solely
track where data is allocated, we track where references occur. This allows us
to ignore the false positive from Stubby and instead focus on code that holds
long-lived &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cord&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;Similarly, consider when we embed type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; as a data member in type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt;.
Changing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(A)&lt;/code&gt; indirectly changes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(B)&lt;/code&gt; and the memory we allocate
when we type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new B()&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;B&amp;gt;&lt;/code&gt;. Small types and memory paddings are
peanut-buttered across the codebase, but in aggregate can consume large amounts
of memory for commonly used types.&lt;/p&gt;

&lt;h3 id=&quot;improving-data-placement&quot;&gt;Improving data placement&lt;/h3&gt;

&lt;p&gt;The cost of memory allocation is not simply the cost of the memory allocator
itself, but also the TLB and cache misses that happen elsewhere in the program.
With nearly ~40% of cycles backend bound, waiting on caches or memory, the
apparent scope for allocator changes is much larger.&lt;/p&gt;

&lt;p&gt;With the &lt;a href=&quot;https://research.google/pubs/pub50370/&quot;&gt;Temeraire optimization&lt;/a&gt;,
TCMalloc changed how it placed allocations onto pages in memory. By reducing TLB
misses and stalls, this sped up the other parts of the application, leading to
application throughput, latency, and RAM usage broadly improved because of the
better placement decisions. Even though this is an across-the-board win,
applications tended to spend &lt;em&gt;more&lt;/em&gt; time in TCMalloc in relative terms, making
this an apparent regression.&lt;/p&gt;

&lt;h3 id=&quot;reducing-calling-convention-costs&quot;&gt;Reducing calling convention costs&lt;/h3&gt;

&lt;p&gt;libc functions like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memset&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcmp&lt;/code&gt; are frequently used. Every
core in Google’s fleet makes several calls to these functions every second.
During the development of
&lt;a href=&quot;https://research.google/pubs/pub50338/&quot;&gt;implementations&lt;/a&gt; now in llvm-libc, we
saw that implementations that were “slower” in microbenchmarks produced
&lt;a href=&quot;/fast/39&quot;&gt;better application performance&lt;/a&gt;. Smaller implementations have less
impact on instruction cache misses, both for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt; itself and for
evicting other useful code.&lt;/p&gt;

&lt;p&gt;With the advent of optimized instructions like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rep movsb&lt;/code&gt;, we can inline the
implementation to a single, two-byte instruction. This instruction uses 3
registers, containing source, destination, and size, akin to the arguments to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt;. X86_64 callers maintain the stack and preserve several registers over
calls. Even though &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rep movsb&lt;/code&gt; can be outperformed by hand-optimized
implementations in microbenchmarks, this strategy can reduce code cache pressure
and external overheads.&lt;/p&gt;

&lt;h3 id=&quot;making-effective-prefetches&quot;&gt;Making effective prefetches&lt;/h3&gt;

&lt;p&gt;During the A/B experiment evaluation of adaptive prefetching, we
&lt;a href=&quot;https://research.google/pubs/limoncello-prefetchers-for-scale/&quot;&gt;observed&lt;/a&gt; that
while topline, &lt;a href=&quot;/fast/7&quot;&gt;application-performance broadly improved&lt;/a&gt;, individual
functions sometimes regressed. If a function generally benefited from the HW
prefetcher, it often regressed. If a function were antagonized by memory
bandwidth saturation, it could improve.&lt;/p&gt;

&lt;p&gt;This data identified an opportunity to add software prefetches to functions with
simple access patterns. This allowed us to optimize for the best of both worlds:
keeping effective prefetches intact, while ablating often ineffective hardware
prefetchers under saturation.&lt;/p&gt;

&lt;h2 id=&quot;closing-thoughts&quot;&gt;Closing thoughts&lt;/h2&gt;

&lt;p&gt;When improving anything (performance, quality, even reliability) do not mistake
the measures you have for the actual thing you want to improve. All metrics are
&lt;a href=&quot;/fast/70&quot;&gt;proxy metrics&lt;/a&gt; for some deeper goal, and we as engineers must always
be careful to avoid externalizing costs into areas where we simply don’t measure
them. Metrics are not a replacement for good judgment–they are a tool to help
us sharpen our judgment.&lt;/p&gt;
</description>
          <pubDate>2023-11-10T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/74</link>
          <guid isPermaLink="true">https://abseil.io/fast/74</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #70: Defining and measuring optimization success</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #70 on June 26, 2023&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-10-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/70&quot;&gt;abseil.io/fast/70&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Engineers optimizing performance are ultimately trying to maximize the things
Google does (serve search queries, videos on YouTube, etc.) and minimize the
things Google buys (&lt;a href=&quot;/fast/7&quot;&gt;CPUs, RAM, disks, etc.&lt;/a&gt;). In this episode, we
discuss how to choose metrics that help us influence the optimizations we work
on, make effective decisions, and measure the outcome of projects.&lt;/p&gt;

&lt;h2 id=&quot;economic-value&quot;&gt;Economic value&lt;/h2&gt;

&lt;p&gt;Things like search queries and video playbacks on YouTube represent economic
value. Useful work is happening to deliver an experience to an end-user which
then translates into Google revenue.&lt;/p&gt;

&lt;p&gt;This isn’t simply a matter of adding up all of the requests that happen though:
Some requests are more important than others:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A search query from a human is valuable. A search query from a
&lt;a href=&quot;https://sre.google/sre-book/practical-alerting/#black-box-monitoring&quot;&gt;prober&lt;/a&gt;
used for monitoring is important insofar as it helps with monitoring the
service’s reliability, but search exists for humans, not for monitoring.&lt;/li&gt;
  &lt;li&gt;A YouTube session might continue to play for several minutes after someone
has left their computer. The automatic playback pause after inactivity cuts
off a flow of unimportant video plays.&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;strong&gt;Things we make&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Things we buy&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Searches&lt;/td&gt;
      &lt;td&gt;CPUs&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Driving directions&lt;/td&gt;
      &lt;td&gt;RAM&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Cat videos&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://dl.acm.org/doi/abs/10.1145/3079856.3080246&quot;&gt;TPUs&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Email messages&lt;/td&gt;
      &lt;td&gt;Disks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Cloud compute VM time&lt;/td&gt;
      &lt;td&gt;Electricity&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/AlphaStar_\(software\)&quot;&gt;Starcraft&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;em&gt;Maximizing value&lt;/em&gt; and &lt;em&gt;minimizing costs&lt;/em&gt; are the outcomes we are ultimately
after.&lt;/p&gt;

&lt;p&gt;In the course of handling requests across servers, there’s work that happens
independently from user requests:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Above, we touched on probing for monitoring.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://research.google/pubs/pub40801/&quot;&gt;Request hedging helps&lt;/a&gt; give users
consistent latency by sending duplicative requests: One of the requests and
the work done might prove to be unnecessary. Taken to an exaggerated
extreme, sending multiple hedged requests unconditionally is wasteful: Users
don’t get meaningfully better latency and production uses resources
profligately. Choosing the right time to hedge can let us strike a balance.&lt;/li&gt;
  &lt;li&gt;Deadline propagation allows child requests to backends to time out early,
rather than continue to perform work believing the requestor will still use
it. This is an important technique for minimizing unproductive work,
&lt;a href=&quot;https://sre.google/sre-book/addressing-cascading-failures/#xref_cascading-failure_latency-and-deadlines&quot;&gt;especially during overload&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Load testing a machine or cluster to the point of overload produces valuable
knowledge for capacity planning and validates that load shedding mechanisms
work. The requests do not directly answer user requests; but without this
knowledge, the user experience would eventually suffer as regressions go
unnoticed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many of these activities are effectively a cost of doing business. It’s hard to
run a reliable, low-latency service distributed across numerous servers without
them. Nonetheless, it’s important to not let the tail wag the dog here:
Monitoring or load testing are not an end unto themselves.&lt;/p&gt;

&lt;h2 id=&quot;selecting-good-proxies&quot;&gt;Selecting good proxies&lt;/h2&gt;

&lt;p&gt;Along the way, there are &lt;em&gt;proxy&lt;/em&gt; metrics that can help with telling us that our
optimization idea is on the right track, or help to explain the causal
connection to top-level metrics. We want to align with the business problem,
without boiling the ocean every time we make a small change and want to assess
it. Measurement has its own return on investment too and the benefits of
additional precision is quickly outweighed by the cost of obtaining it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Goodhart%27s_law&quot;&gt;Goodhart’s Law&lt;/a&gt; reminds us that
“when a measure becomes a target, it ceases to be a good measure.” Escaping this
completely is challenging, but analysis is easier the more closely aligned the
metric is with what we’re optimizing.&lt;/p&gt;

&lt;p&gt;One common leap that we might need to make is connecting an abstract or harder
to measure end goal such as business value or user satisfaction to more easily
measured metrics. Totals of RPC requests made or their latency are common
proxies for this.&lt;/p&gt;

&lt;p&gt;In working on optimizations, we also need to optimize our feedback loop for
developing optimizations. For example,&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/fast/75&quot;&gt;Microbenchmarks&lt;/a&gt; provide a much shorter feedback loop than
measuring application performance in macrobenchmarks or production. We can
build, run, and observe a microbenchmark in a manner of minutes. They have
&lt;a href=&quot;/fast/39&quot;&gt;limitations&lt;/a&gt;, but as long as we’re mindful of those pitfalls,
they can get us directional information much more quickly.&lt;/li&gt;
  &lt;li&gt;PMU counters can tell us rich details about &lt;a href=&quot;/fast/53&quot;&gt;bottlenecks in code&lt;/a&gt;
such as &lt;a href=&quot;/fast/62&quot;&gt;cache misses&lt;/a&gt; or branch mispredictions. Seeing changes in
these metrics can be a &lt;em&gt;proxy&lt;/em&gt; that helps us understand the effect. For
example, inserting software prefetches can reduce cache miss events, but in
a memory bandwidth-bound program, the prefetches can go no faster than the
“speed of light” of the memory bus. Similarly, eliminating a stall far off
the critical path might have little bearing on the application’s actual
performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we expect to improve an application’s performance, we might start by taking a
large function in the CPU profile and finding an optimization for it–say by
changing to a more cache-friendly data structure. The reduction in cache misses
and improvement in microbenchmark times help validate that the optimization is
working according to our mental model of the code being optimized. We avoid
false positives by doing so: Changing the
&lt;a href=&quot;https://xkcd.com/882/&quot;&gt;font color of a webpage to green&lt;/a&gt; and running a loadtest
&lt;em&gt;might&lt;/em&gt; give a &lt;a href=&quot;/fast/88&quot;&gt;positive result&lt;/a&gt;
&lt;a href=&quot;https://en.wikipedia.org/wiki/Bonferroni_correction&quot;&gt;purely by chance&lt;/a&gt;, not due
to a causal effect.&lt;/p&gt;

&lt;p&gt;These development-time proxies help us get an understanding of bottlenecks and
performance improvements. We still need to measure the impact on application and
service-level performance, but the proxies help us hone in on an optimization
that we want to deploy faster.&lt;/p&gt;

&lt;p&gt;When we are considering multiple options for a project, secondary metrics can
give us confirmation after the fact that our expectations were correct. For
example, suppose we chose option A over option B because both provided
comparable performance but A would not impact reliability. We should measure
both the performance and reliability outcomes to support our engineering
decision. This lets us close the loop between expectations and reality.&lt;/p&gt;

&lt;h2 id=&quot;aligning-with-success&quot;&gt;Aligning with success&lt;/h2&gt;

&lt;p&gt;The metrics we pick need to align with success. If a metric tells us to do the
opposite of a seemingly good thing, the metric is potentially flawed.&lt;/p&gt;

&lt;p&gt;For example, &lt;a href=&quot;https://research.google/pubs/pub35650/&quot;&gt;Flume&lt;/a&gt; tracks
&lt;a href=&quot;/fast/7&quot;&gt;useful work done by workers&lt;/a&gt; in terms of records processed. While no
default is ever perfect–this elides that records can be of varying workloads,
shapes, and sizes–it better aligns with other optimizations than bytes
processed. With static and dynamic field tracking, Flume can read a subset of
fields from every record. The total number of records is unchanged, but the
total number of bytes goes down and total pipeline costs fall as well. Comparing
the two possible metrics:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;With records as the denominator, we see a drop in resources required per
record processed with this optimization. ie the compute per record decreases
with optimization.&lt;/li&gt;
  &lt;li&gt;With bytes as the denominator, absolute resource usage does go down, but
fixed overheads stay the same. As a proportion of the total pipeline’s cost,
fixed costs grow and are amortized over fewer bytes. ie the compute per byte
may actually increase with optimization. This might make an
optimization–skipping unnecessary data–look like an apparent regression.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other cases, we want to normalize for the amount of work done. For example, a
service where the size of the response depends on the request will likely want
to track the number of returned bytes as its work done. A video transcoding
service similarly needs to count the number of pixels: Videos at higher
resolution require more processing time than lower resolution ones, and this
roughly normalizes the higher difficulty per frame.&lt;/p&gt;

&lt;h2 id=&quot;pitfalls&quot;&gt;Pitfalls&lt;/h2&gt;

&lt;p&gt;Instructions per clock (IPC) is a challenging metric to use as a proxy. While
executing more instructions in less time is generally good–for example, because
we reduced cache misses by optimizing things–there are other times where it is
worse. A thread spinning for a locked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SpinLock&lt;/code&gt; is not making forward progress,
despite having high IPC. Similarly, using vector instructions, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rep movsb&lt;/code&gt;, or
differences in microarchitecture allows us to accomplish more useful work in a
single instruction. Optimizing for IPC or instructions can lead us to prefer
behaviors that are worse for application performance.&lt;/p&gt;

&lt;p&gt;Similarly,
&lt;a href=&quot;https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/44271.pdf&quot;&gt;relative time in libraries&lt;/a&gt;
is a useful yardstick for finding places to optimize and tracking their costs.
In the long run, though, optimizations that
&lt;a href=&quot;https://research.google/pubs/pub50370.pdf&quot;&gt;speed up the whole program&lt;/a&gt; might
come at the “cost” of this proxy.&lt;/p&gt;

&lt;p&gt;Distributed systems complicate metrics as well. We still want to make sure the
high level goal–business value per TCO (total cost of ownership) is maximized,
but we may be able to put more precise calipers on subsystems to detect
improvements (or regressions). Task-level metrics such as throughput and latency
may not translate to the overall system’s performance: Optimizing the latency of
a task off the critical path may have little impact on the overall, user-facing
latency of a service. On the other hand, throughput improvements, allowing us to
do more work with less CPU time and memory per request, allow us to use fewer
resources to handle the same workload.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;The goal of optimization projects is to maximize
value–&lt;a href=&quot;/fast/7&quot;&gt;serving search queries, videos on YouTube, etc&lt;/a&gt;–and minimize
costs–CPUs, RAM, disks, etc. Similar to how we can carefully use
microbenchmarks to predict macrobenchmarks to &lt;a href=&quot;/fast/39&quot;&gt;predict production&lt;/a&gt;, we
can select proxy metrics to measure success. This lets us align with business
goals, especially harder to measure ones, while still having an effective
yardstick for day-to-day work.&lt;/p&gt;
</description>
          <pubDate>2023-10-20T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/70</link>
          <guid isPermaLink="true">https://abseil.io/fast/70</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #60: In-process profiling: lessons learned</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #60 on June 6, 2022&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-09-29&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/60&quot;&gt;abseil.io/fast/60&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://research.google/pubs/pub36575/&quot;&gt;Google-Wide Profiling&lt;/a&gt; collects data
not just from our hardware performance counters, but also from in-process
profilers. These have been covered in previous episodes covering
&lt;a href=&quot;/fast/26&quot;&gt;hashtables&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In-process profilers can give deeper insights about the state of the program
that are hard to observe from the outside, such as lock contention, where memory
was allocated, and the distribution of collisions on a hashtable. In this tip we
discuss how to determine that a new profiler is necessary, and the best
practices for producing one.&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;“The purpose of computing is insight, not numbers.” – Richard Hamming&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developing a new profiler and augmenting existing ones allows us to have more
information to make optimization decisions and aid debugging. The goal isn’t to
have perfect information and to make perfect decisions, but to make better
decisions faster, shortening our
&lt;a href=&quot;https://en.wikipedia.org/wiki/OODA_loop&quot;&gt;“OODA loop” (Observe Orient Decide Act)&lt;/a&gt;.
The value is in pulling in the area-under-curve and landing in a better spot. An
“imperfect” profiler that can help make a decision is better than a “perfect”
profiler that is unwieldy to collect for performance or privacy reasons. Extra
information or precision is only useful insofar as it helps us make a
&lt;a href=&quot;/fast/94&quot;&gt;&lt;em&gt;better&lt;/em&gt; decision or &lt;em&gt;changes&lt;/em&gt; the outcome&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, most new optimizations to
&lt;a href=&quot;https://github.com/google/tcmalloc/blob/master/tcmalloc&quot;&gt;TCMalloc&lt;/a&gt; start from
adding new data points to TCMalloc’s statistics that are collected by visiting
malloc profile handlers across the fleet. This information
&lt;a href=&quot;https://github.com/google/tcmalloc/blob/master/docs/stats.md&quot;&gt;helps with understanding&lt;/a&gt;
the scope of a particular phenomenon. After landing an optimization, these
metrics can help provide indicators that we changed what we set out to change,
even if the actual CPU and RAM savings might be measured by other means. These
steps didn’t directly save any CPU usage or bytes of RAM, but they enabled
better decisions. Capabilities are harder to directly quantify, but they are the
motor of progress.&lt;/p&gt;

&lt;h2 id=&quot;no-build&quot;&gt;Leveraging existing profilers: the “No build” option&lt;/h2&gt;

&lt;p&gt;Developing a new profiler takes considerable time, both in terms of
implementation and wallclock time to ready the fleet for collection at scale.
Before moving to implement one, it is valuable to consider whether we can derive
the necessary information from existing profilers and tools we already have.&lt;/p&gt;

&lt;p&gt;For example, if the case for hashtable profiling was just reporting the capacity
of hashtables, then we could also derive that information from heap profiles,
TCMalloc’s heap profiles of the fleet. Even where heap profiles might not be
able to provide precise insights–the actual “size” of the hashtable, rather
than its capacity–we can make an &lt;a href=&quot;/fast/90&quot;&gt;informed guess&lt;/a&gt; from the profile
combined with knowledge about the typical load factors due to SwissMap’s design.&lt;/p&gt;

&lt;p&gt;It is important to articulate the value of the new profiler over what is already
provided. A key driver for hashtable-specific profiling is that the CPU profiles
of a hashtable with a
&lt;a href=&quot;https://youtu.be/JZE3_0qvrMg?t=1864&quot;&gt;bad hash function look similar to those&lt;/a&gt;
with a good hash function. The &lt;a href=&quot;/fast/26&quot;&gt;added information collected&lt;/a&gt; for stuck
bits helps us drive optimization decisions we wouldn’t have been able to make.
The capacity information collected during hashtable-profiling is incidental to
the profiler’s richer, hashtable-specific details, but wouldn’t be a
particularly compelling reason to collect it on its own given the redundant
information available from ordinary heap profiles.&lt;/p&gt;

&lt;h2 id=&quot;sampling-strategies&quot;&gt;Sampling strategies&lt;/h2&gt;

&lt;p&gt;A key design aspect of a profiler is deciding when and how to collect
information. Most profilers do some kind of sampling to provide an estimate of
the total without the overhead of recording every event. Collecting some data,
even if heavily sampled, can be useful for gauging behaviors of a library at
scale. There are two aspects to a profiler that need to be decided up front:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Duration versus duration-less&lt;/strong&gt;: Several of our profilers track sampled
events over a period of time. Other profilers capture an instantaneous
snapshot of the program’s state.&lt;/p&gt;

    &lt;p&gt;Duration-less handlers are profiling during the entire program lifetime,
which imposes a higher bar on the stability and overhead that can be
required. In contrast, a profiler that is only active during collection can
be more expensive, as collecting itself is rare.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Sampling strategy&lt;/strong&gt;: The overheads of capturing data about every instance
of a class can be prohibitive, so it’s important to determine a strategy for
sampling - and figure out how that sampling strategy can be scaled to
provide information representative of the entire fleet.&lt;/p&gt;

    &lt;p&gt;Sampling operations can make-or-break the feasibility of a profiler: Our
compression profiler originally recorded statistics about &lt;em&gt;every&lt;/em&gt;
compression operation during its collection window, but the high overhead
caused major services to turn off the profiler altogether. It was fixed by
moving to a sampling strategy to only record statistics on a subset of
compression operations during the profiling window. This allowed the
profiler to be reenabled.&lt;/p&gt;

    &lt;p&gt;While &lt;a href=&quot;/fast/52&quot;&gt;knobs are often undesirable&lt;/a&gt;, allowing applications to tune
their sampling rate (or whether sampling occurs at all) can be helpful for
balancing the information gained against the overheads imposed.&lt;/p&gt;

    &lt;p&gt;Unless there is a justified exception, we require that the profiler applies
the sampling factor back to the data to “unsample” it before returning it.
This allows consumers to easily use the data without having to deal with the
sampling arithmetic themselves. This is especially important as sampling
rate can be variable–either automatically adjusted or tunable via a
configuration knob such as a flag. This step can also help with validation
via cross-checking with other profilers. For example, SwissMap’s total
memory allocations seen by TCMalloc’s heap profiles are consistent with the
total capacity seen by the hashtable profiler.&lt;/p&gt;

    &lt;p&gt;Choosing the right sampling approach (and the unsampling counterpart) needs
to carefully balance accuracy vs. overhead. For example, with the heap
profiler in TCMalloc one might decide to simply pick every Nth allocation.
But that would not work well: in a typical app memory profiles are dominated
by many small allocations and sampling those with reasonable overhead would
require high sampling factor. It is also likely to miss more rare large
allocations. Interestingly, the next obvious improvement of sampling an
allocation every N bytes would “almost work” but is subject to statistical
bias. This was fixed by introducing Poisson sampler which is used to date.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For libraries with significant global process state, the threads running in a
process or the state of malloc, we may use a more exhaustive strategy. For
example, a profiler could snapshot and summarize the state of the library
without further sampling.&lt;/p&gt;

&lt;h2 id=&quot;what-data-to-record&quot;&gt;What data to record&lt;/h2&gt;

&lt;p&gt;In addition to choosing a sampling strategy, we need to decide what data to
collect. We want to choose data that will influence an optimization decision.
Just as different optimization projects have varying returns on investment, we
want to strike a balance between the cost of implementing our profiler, of
running it, and implementing the optimizations it motivates.&lt;/p&gt;

&lt;p&gt;Mutation operations can be an excellent place to record additional statistics on
sampled instances. These are frequently heavyweight for unrelated reasons–they
trigger copies and reallocations–so checking whether to record statistics has
minimal added performance penalty. This is the strategy we use for many of our
existing profilers. In contrast, non-mutating operations, such as hashtable
lookups, can be prohibitively expensive as we use these operations frequently
and rely on them being fast.&lt;/p&gt;

&lt;p&gt;There is a cost-benefit tradeoff for having more information. Sampling more
frequently or collecting more data with each sample can paint a richer picture,
but this increases the runtime cost of profiling. TCMalloc’s heap profiling has
low, but non-zero costs, but it more than pays for itself by allowing us to look
at where much of our RAM usage goes. Increasing the sampling rate would give us
extra precision, but it wouldn’t materially affect the optimizations we can
uncover and deploy. The extra overheads would negatively impact performance.&lt;/p&gt;

&lt;p&gt;More practically, a minimal set of information can be a good starting point for
getting a new profiler up and running to start debugging it. While obvious in
hindsight, several new profilers have hit issues with their stack trace
collection and filtering. While collecting more data can give additional
insights, implementations that compute too many statistics or add contended
locks may simply be infeasible. A profiler that is too expensive to leave
enabled may be worse than no profiler at all: We spend time implementing it and
rolling it out, but we lose the visibility into the library usage that we were
after in the first place.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Profilers are a useful tool for probing the internal state of a program to
&lt;em&gt;answer questions&lt;/em&gt; during debugging and optimization. The types of questions
posed can greatly influence the design and architecture of a profiler.&lt;/p&gt;

&lt;p&gt;While a particular design may not be able to answer all questions, all at once,
the goal is ultimately to make &lt;em&gt;better decisions faster&lt;/em&gt;, shortening our
&lt;a href=&quot;https://en.wikipedia.org/wiki/OODA_loop&quot;&gt;“OODA loop” (Observe Orient Decide Act)&lt;/a&gt;.
Just as optimization projects are framed in terms of return-on-investment, we
can frame how additional information influences or changes course of a decision.&lt;/p&gt;
</description>
          <pubDate>2023-10-15T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/60</link>
          <guid isPermaLink="true">https://abseil.io/fast/60</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #64: More Moore with better API design</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #64 on October 21, 2022&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-09-29&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/64&quot;&gt;abseil.io/fast/64&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Optimizing library implementations only carries us so far in making software
more efficient. In this episode, we discuss the importance of good APIs and the
right abstractions for finding optimization opportunities. As we can make the
hardware–especially with the end of Moore’s Law–and software run only so fast,
the right abstractions give us continued optimization opportunities.&lt;/p&gt;

&lt;h2 id=&quot;correctness-is-paramount&quot;&gt;Correctness is paramount&lt;/h2&gt;

&lt;p&gt;We can simplify an implementation down to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return 42;&lt;/code&gt; regardless of the input
to see blazing fast results, but an API that doesn’t work correctly isn’t doing
its job.&lt;/p&gt;

&lt;p&gt;“Subtle” and “clever” code has costs for both maintainers and users alike.
Today’s tricky edge cases can be tomorrow’s headaches when we try to optimize an
implementation. Threading the needle of preserving explicitly (or
&lt;a href=&quot;https://hyrumslaw.com&quot;&gt;implicitly&lt;/a&gt;) promised quirks makes the optimization
process slower and more fragile over time. Being able to
&lt;a href=&quot;https://en.wikipedia.org/wiki/OODA_loop&quot;&gt;iterate&lt;/a&gt; &lt;a href=&quot;/fast/39&quot;&gt;faster&lt;/a&gt; helps with
exploring more of the design space to find the best minima.&lt;/p&gt;

&lt;p&gt;At times, we may need to break abstraction boundaries or have complex
preconditions to unlock the best possible performance. We need to document and
test these sharp edges. Future debugging has an opportunity cost: When we spend
time tracking down and fixing bugs, we are not developing new optimizations. We
can use assertions for preconditions, especially in debug/sanitizer builds, to
double-check contracts and &lt;em&gt;enforce&lt;/em&gt; them. Testing
&lt;a href=&quot;/fast/93&quot;&gt;robots never sleep&lt;/a&gt;, while humans are fallible. Randomized
implementation behaviors provide a useful bulwark against Hyrum’s Law from
creeping in to implicitly expand the contract of an interface.&lt;/p&gt;

&lt;h2 id=&quot;express-intents&quot;&gt;Express intents&lt;/h2&gt;

&lt;p&gt;Small, composable operations give users flexibility to express their intents
more clearly. We can find optimizations by combining high-level but related
concepts.&lt;/p&gt;

&lt;p&gt;Consider &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt; and a hypothetical &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy_but_faster&lt;/code&gt; API that we could
build. They both express the same intent, but presumably with
&lt;a href=&quot;/fast/52&quot;&gt;different tradeoffs around performance&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Users need to think about which one to call. This adds a cognitive cost to
every call site. They cannot quickly reach for precisely one to realize
their desired functionality. When in doubt, typing fewer characters is
faster. Over time, choices made will be incorrect, either because they were
suboptimal from the start or circumstances changed.&lt;/li&gt;
  &lt;li&gt;Bifurcating the API gives us two implementations, each with less usage. This
lowers the leverage from developing optimizations to one, unless its
maintainers can reliably cross-pollinate ideas from one to the other.
Actively maintaining &lt;em&gt;two&lt;/em&gt; implementations requires a larger investment,
reducing the RoI from having two in the first place. Engineers may give the
more commonly used implementation more care and attention, leading it to
eventually outstrip the “faster” implementation.&lt;/li&gt;
  &lt;li&gt;Data structures and types can be especially costly to duplicate, due to the
“&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2125r0.pdf&quot;&gt;impedance mismatch&lt;/a&gt;”
of having a library that works solely with one type (say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;) and
another that needs a different one (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::my_fast_string&lt;/code&gt;). In order for
the two to interoperate, the interfaces will require expensive copies–a
single type would not require such conversions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While this hypothetical might seem far-fetched, this is precisely what happened
with the &lt;a href=&quot;/fast/9&quot;&gt;predecessor implementation to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::popcount&lt;/code&gt;&lt;/a&gt;. We had two
implementations, but the “better” one was ultimately outstripped by the “worse”
one because engineers optimized the one with the wider usage instead.&lt;/p&gt;

&lt;p&gt;In terms of API design around intents, we can consider:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void* memcpy(void* dest, const void* src, size_t count);
crc32c_t absl::ComputeCrc32c(absl::string_view buf);
crc32c_t absl::MemcpyCrc32c(void* dest, const void* src, size_t count);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With the first two primitives, we can build a trivial, but non-optimal
implementation for the third. Combining the concepts makes sense when it is a
common operation where finer-grained operations might leave performance on the
table. Knowing we are going to both copy and checksum the bytes allows us to
read data once, rather than twice. We can decompose the implementation into its
components, as well, if that ever became more efficient.&lt;/p&gt;

&lt;p&gt;The extra output of the operation (the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crc32c_t&lt;/code&gt;) distinguishes it from just
being a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt; with different performance characteristics. We would recommend
using the combined operation when we need to both &lt;em&gt;copy&lt;/em&gt; data and &lt;em&gt;checksum&lt;/em&gt; it.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MemcpyCrc32c&lt;/code&gt; isn’t a suitable replacement for calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt; without a need
for a checksum, which removes the cognitive cost of considering it solely for
performance reasons.&lt;/p&gt;

&lt;p&gt;The explicit function calls can also help with understanding the purpose of the
code when we are looking at profiles later. For example, we can compare
protobufs for equality in two ways:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;By serializing and comparing the bytes, which is unfortunately both common
and
&lt;a href=&quot;https://protobuf.dev/programming-guides/encoding/#implications&quot;&gt;unsound&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/protocolbuffers/protobuf/tree/main/src/google/protobuf/util/message_differencer.h&quot;&gt;Field-by-field&lt;/a&gt;
directly, which is faster.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While reading a profile, we might see the individual calls to serialize and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcmp&lt;/code&gt;, but it is harder to ascertain the intended semantics later. We may be
tempted to optimize the discrete functions–the process of serializing and
subsequent the process of comparing the resulting string. Understanding the
high-level intent and data flow gives us opportunities to optimize further up
the stack to find the “Room at the Middle”, optimizing the direct comparison. At
a minimum, an optimized version could avoid holding the serialized versions in
memory.&lt;/p&gt;

&lt;h2 id=&quot;avoid-unnecessarily-strong-guarantees&quot;&gt;Avoid unnecessarily strong guarantees&lt;/h2&gt;

&lt;p&gt;There are situations where the benefits of duplicate APIs outweigh the costs.&lt;/p&gt;

&lt;p&gt;The Abseil hash containers
(&lt;a href=&quot;https://abseil.io/about/design/swisstables&quot;&gt;SwissMap&lt;/a&gt;) added new hashtable
implementations to the codebase, which at first glance, appear redundant with
the ones in the C++ standard library. This apparent duplication allowed us to
have a more efficient set of containers which match the standard library API,
but adhere to a weaker set of constraints.&lt;/p&gt;

&lt;p&gt;The Abseil hash containers provided weaker guarantees for iterator and pointer
stability, allowing them to improve performance by reducing data indirections.
It is difficult to implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt;’s guarantees without resorting
to a node-based implementation that requires data indirections and constrains
performance. Given &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt;’s widespread usage, it was not feasible
to relax these guarantees all at once.&lt;/p&gt;

&lt;p&gt;Node-based containers necessitate implementation overheads, but they come with a
direct benefit: They actively facilitate migration while allowing weaker
containers to be available. Making a guarantee stronger without an accompanying
benefit is undesirable.&lt;/p&gt;

&lt;p&gt;The migration was a replacement path for the legacy containers, not an
alternative. The superior performance characteristics meant that users could
“just use SwissMap” without tedious benchmarking on a case-by-case basis.
There’s little need for a user to revisit their decision to migrate to SwissMap
with the passage of time. This meant that usage could be actively driven towards
SwissMap: Two types would be a temporary (albeit long) state, rather than one
where every individual usage had to be carefully selected.&lt;/p&gt;

&lt;p&gt;Years after SwissMap’s development, there are far fewer–but non-zero–uses of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt;. Blocking the improvement on the complete cleanup means no
benefit would have accrued. We were able to migrate instance-by-instance,
realizing incremental benefits over time.&lt;/p&gt;

&lt;p&gt;It’s important to avoid ascribing intent–even with expressive APIs–to use of a
previously predominant one. A use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::map&lt;/code&gt; might require keys to be
ordered, but the more likely explanation might be that it is older code in need
of updating.&lt;/p&gt;

&lt;h2 id=&quot;avoid-leaking-implementation-details&quot;&gt;Avoid leaking implementation details&lt;/h2&gt;

&lt;p&gt;Hyrum’s Law reminds us that observable behaviors will be relied upon, but
sometimes our API design choices constrain our implementation details. These
often arise from returning references to data or giving fine-grained control in
APIs. This can help performance in the short-term, but care is required to make
sure it allows long-term evolution to continue to improve performance over time.&lt;/p&gt;

&lt;p&gt;Consider protocol buffers for a simple message.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;message MyMessage {
  optional string foo = 1;
  repeated string bar = 2;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As of October 2023, the accessor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.foo()&lt;/code&gt; returns a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::string&amp;amp;&lt;/code&gt;. This
&lt;em&gt;requires&lt;/em&gt; that we have an in-memory representation of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; instance
that can be returned. This approach has two problems:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; encodes a specific allocation strategy (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::allocator&lt;/code&gt;). If
we change the allocation strategy, for example wrapping &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Arena&lt;/code&gt;, we change
the type.&lt;/li&gt;
  &lt;li&gt;Individual fields can have a wide range of sizes (or likelihoods of
presence) that we can determine from profiling, which could benefit from
variable small string object buffer sizes. Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::string&amp;amp;&lt;/code&gt;
constrains the implementation to that particular size of buffer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In contrast, by returning &lt;a href=&quot;/tips/1&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string_view&lt;/code&gt;&lt;/a&gt; (or our
&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html&quot;&gt;internal predecessor&lt;/a&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StringPiece&lt;/code&gt;), we decouple callers from the internal representation. The API is
the same, independent of whether the string is constant data (backed by the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.rodata&lt;/code&gt; section), allocated on the heap by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; instance, or
allocated by an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Arena&lt;/code&gt;. We’ve abstracted away the implementation detail from
our user, giving us more optimization freedom.&lt;/p&gt;

&lt;p&gt;Similarly, consider the allocation-aware APIs in protobuf, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_allocated_...&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;release_...&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unsafe_arena_...&lt;/code&gt;. Fine-grained control over when and where
allocations occur can offer significant performance benefits, but they also
constrain future implementations by creating sharp performance edges.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;release_...&lt;/code&gt; allows us to remove a submessage and return ownership to the
caller. Subobjects were heap allocated and the operation was fast–it’s hard
to beat swapping two pointers. When Protobuf Arenas became available,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;release_...&lt;/code&gt; created a new copy of the underlying message on the heap, so
it could release that. The API couldn’t convey that the returned pointer was
owned by the Arena, not caller, so making a full copy was required to keep
code working. As a result, code that calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;release_...&lt;/code&gt; may be O(1) or O(n)
based on non-local information (whether the source object was constructed on
an arena)!&lt;/li&gt;
  &lt;li&gt;With Arenas, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unsafe_arena_...&lt;/code&gt; gives us the raw hooks we need to add or
remove fields from a message without making the copy mentioned above , with
“unsafe” in the name conveying the subtlety and gravitas of what we’re
doing. These APIs are tricky to use correctly, though, as today’s tested
combination of arena and heap ownership may change over time and assumptions
break. The APIs are also extremely fine-grained, but do not convey the
higher-level intent–transferring pointer ownership, “lending” a submessage
to another one, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;concluding-remarks&quot;&gt;Concluding remarks&lt;/h2&gt;

&lt;p&gt;Good performance should be available by default, not an optional feature. While
&lt;a href=&quot;/fast/52&quot;&gt;feature flags and knobs can be useful for testing and initial rollout&lt;/a&gt;,
we should strive to make the right choices for users, rather than requiring
users adopt the improvement on a case-by-case basis.&lt;/p&gt;

&lt;p&gt;Developing an optimization for an existing implementation can provide a larger
return-on-investment by targeting widespread, current usage upfront. Adding a
new API or optimization knob can be expedient, but without widespread usage and
adoption, the benefit is far more limited.&lt;/p&gt;

&lt;p&gt;Optimization of existing code can hit stumbling blocks around unnecessarily
strong guarantees or APIs that constrain the implementation–and thus the
optimization search space–too much to find improvements.&lt;/p&gt;
</description>
          <pubDate>2023-10-10T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/64</link>
          <guid isPermaLink="true">https://abseil.io/fast/64</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #52: Configuration knobs considered harmful</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #52 on September 30, 2021&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-10-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/52&quot;&gt;abseil.io/fast/52&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flags, options, and other mechanisms to override default behaviors are useful
during a migration or as a short-term mechanism to address an unusual need. In
the long term they go stale (not providing real benefit to users), are almost
always haunted (in the
&lt;a href=&quot;https://www.usenix.org/sites/default/files/conference/protected-files/srecon17americas_slides_reese.pdf&quot;&gt;haunted graveyard&lt;/a&gt;
sense), and prevent centralized consistency/optimization efforts. In this
episode, we discuss the tradeoffs in technical debt and optimization velocity
for adding configurability.&lt;/p&gt;

&lt;h2 id=&quot;the-ideal-flag-lifecycle&quot;&gt;The ideal flag lifecycle&lt;/h2&gt;

&lt;p&gt;When developing a new feature, it’s straightforward and often recommended to
guard it behind a flag. This approach of using
&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#continuous_delivery-id00035&quot;&gt;feature flags&lt;/a&gt;
makes it possible to decouple pushing the code changes to production from
turning on a new feature, which might have undiscovered correctness bugs or
different resource requirements.&lt;/p&gt;

&lt;p&gt;For a commonly-used library, flags also allow early opt-ins from users. When the
default is changed, the flag also provides an escape hatch to revert to the old
behavior.&lt;/p&gt;

&lt;p&gt;For example, this was employed successfully for the rollout of
&lt;a href=&quot;https://github.com/google/tcmalloc/blob/master/tcmalloc&quot;&gt;TCMalloc&lt;/a&gt;’s
&lt;a href=&quot;https://research.google/pubs/pub50370.pdf&quot;&gt;Huge Page Aware Allocator optimization&lt;/a&gt;:
many applications opted-in early, but even with extensive testing, a few
applications saw changes in their resource requirements. These could be
opted-out while deeper investigation occurred without rolling back the
efficiency gains seen by most other users of TCMalloc.&lt;/p&gt;

&lt;p&gt;These experiences suggest flags are an unalloyed good in theory, but practice is
wholly different. Whether flags are considered good or not is dependent on what
percentage of users will use the feature:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If the number of users of a flag is always expected to be small, its
existence hampers future evolution.&lt;/li&gt;
  &lt;li&gt;If that number is mid-ranged, this can be a well-justified level of
complexity but it can be challenging to set the flags optimally. Some teams
have observed that, often, only the authors of features have the necessary
context to set the flag appropriately - either to know when to set it at all
or to which value it should actually be set.&lt;/li&gt;
  &lt;li&gt;If that number is near 100% – then probably we’re transitioning to a new
default and the flag exists to provide an opt-out - this can be a good use
of the flag. Nonetheless, it is important to clean that flag up after the
rollout is complete so it doesn’t linger indefinitely. Without the cleanup,
this becomes technical debt that hinders future changes or becomes a
“standard knob with a weird name.”&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;flags-failing-to-convey-intent&quot;&gt;Flags failing to convey intent&lt;/h2&gt;

&lt;p&gt;The units for many flags are entirely opaque and often have second or third
order effects that may not be immediately intuitive.&lt;/p&gt;

&lt;p&gt;In his &lt;a href=&quot;https://www.youtube.com/watch?v=J6SNO5o9ADg&quot;&gt;2021 CppCon talk&lt;/a&gt;, Titus
Winters makes a real-world note of this phenomenon: The “popcorn button” of
microwaves should not be used for microwave popcorn, as the button does not
align with the settings required.&lt;/p&gt;

&lt;p&gt;Moving to Google’s C++ codebase, SwissMap, Abseil’s high performance hashtables,
does not provide an implementation of the flag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_load_factor&lt;/code&gt;. The low
utility of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_load_factor&lt;/code&gt; was uncovered during the migration to SwissMap.
Even worse, in many of the situations where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_load_factor&lt;/code&gt; was set, it was
set incorrectly.&lt;/p&gt;

&lt;p&gt;Even when the role of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_load_factor&lt;/code&gt; was correctly understood, its value was
often misconfigured to achieve a desired goal. While &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_load_factor(0.25)&lt;/code&gt;
might convey an intent to “trade RAM for speed,” such a setting can make CPU
performance worse while simultaneously using more RAM, defeating the intent of
its user.&lt;/p&gt;

&lt;p&gt;In other situations, different implementations can be API-compatible, but their
behaviors do not transfer effectively between implementations. Open addressing
hashtables have typical load factors &amp;lt;1, while chained hashtables have load
factors typically ≥1. Changing between these implementations would cause the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_load_factor&lt;/code&gt; to have a surprisingly different effect.&lt;/p&gt;

&lt;p&gt;This experience led the SwissMap authors to make &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_load_factor&lt;/code&gt; a no-op,
providing it only for API compatibility.&lt;/p&gt;

&lt;h2 id=&quot;stale-configuration-parameters&quot;&gt;Stale configuration parameters&lt;/h2&gt;

&lt;p&gt;Tuning a configuration is another optimization that
&lt;a href=&quot;/fast/9&quot;&gt;does not age well&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For flags defined in commonly used libraries, the defaults themselves have
probably evolved: a feature was launched or an optimization landed. The nature
of Google’s production configuration languages often means that once a service
has hard-coded a flag’s value, it takes precedence over the default. This was
the whole reason for choosing a non-default value in the first place; but with
the codebase evolving at a high rate, it’s easy to overlook that the underlying
infrastructure has improved and that overriding value now is &lt;em&gt;worse&lt;/em&gt; than the
default.&lt;/p&gt;

&lt;p&gt;The key action here is to use customized flags lightly and regularly reconsider
their use. When designing new options, prefer good defaults or make parameters
self-tune if possible. Self-tuning may come in the form of adapting
automatically to workloads, rather than requiring careful tuning through flags.&lt;/p&gt;

&lt;h2 id=&quot;reduced-long-term-velocity&quot;&gt;Reduced long-term velocity&lt;/h2&gt;

&lt;p&gt;Titus Winters notes that “If 99% of your users understand an API’s behavior
through the lens of the default setting, the 1% of users that change that
setting are at risk: APIs built at a higher level have a good chance of assuming
the default behavior, leaving your 1% semi-supported.”&lt;/p&gt;

&lt;p&gt;Configurability can be a great short-term boon; but long-term, configurability
is a double edged sword. Options increase the state-space that has to be
considered with every future change, making it more difficult to reason about,
test, and successfully land new features in production. Beyond just optimizing
&lt;em&gt;costs&lt;/em&gt;, this complexity also hampers achieving better business objectives:
Extra complexity that delays an improvement to product experiences is a
non-obvious externality.&lt;/p&gt;

&lt;p&gt;For example, TCMalloc has a number of
&lt;a href=&quot;https://github.com/google/tcmalloc/blob/master/docs/tuning.md&quot;&gt;tuning options&lt;/a&gt;
and customization points, but ultimately, several optimizations came from
sanding away extra configuration complexity. The rarely used malloc hooks API
required careful structuring of TCMalloc’s fast path to allow users who didn’t
use hooks–most users–to not pay for their possible presence. In another case,
removing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sbrk&lt;/code&gt; allocator allowed TCMalloc to structure its virtual address
space carefully, enabling several enhancements.&lt;/p&gt;

&lt;h2 id=&quot;beyond-knobs&quot;&gt;Beyond knobs&lt;/h2&gt;

&lt;p&gt;While this discussion has largely focused on knobs and tunables, APIs and
libraries have the same challenges.&lt;/p&gt;

&lt;p&gt;An existing library, &lt;em&gt;X&lt;/em&gt;, might be inadequate or insufficiently expressive,
which can motivate building a “better” alternative, &lt;em&gt;Y&lt;/em&gt;, along some dimensions.
Realizing the benefit of using &lt;em&gt;Y&lt;/em&gt; is dependent on users both discovering &lt;em&gt;Y&lt;/em&gt;
and picking between &lt;em&gt;X&lt;/em&gt; and &lt;em&gt;Y&lt;/em&gt; &lt;em&gt;correctly&lt;/em&gt;–and in the case of a long-lived
codebase, keeping that choice optimal over time.&lt;/p&gt;

&lt;p&gt;For some uses, this strategy is infeasible. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my::super_fast_string&lt;/code&gt; will
probably never replace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; because the latter is so entrenched and the
impedance mismatch of living in an independent string ecosystem exceeds the
benefits. Multiple
&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2125r0.pdf&quot;&gt;vocabulary types&lt;/a&gt;
suffer from impedance mismatch–costly interconversions can overwhelm the
overall benefits. The costs of migrating the world also need to be considered
upfront. Without active migration, we end up with two things.&lt;/p&gt;

&lt;p&gt;There are times where a new library or API is truly needed –
&lt;a href=&quot;https://abseil.io/about/design/swisstables&quot;&gt;SwissMap&lt;/a&gt; needed to break stability
guarantees provided by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt; on an instance-by-instance basis to
avoid waiting for every problematic usage to be fixed. In that case, however,
the performance benefits it provided were only realized by active migration.
Being able to aim for a complete migration eases maintenance and educational
burdens as well. A compelling performance case simplified to “just use SwissMap”
avoids the need for painstaking benchmarking with every use where the optimal
choice could get out of date.&lt;/p&gt;

&lt;h2 id=&quot;best-practices&quot;&gt;Best practices&lt;/h2&gt;

&lt;p&gt;When adding new customization points, consider how they’ll evolve over the
long-term.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;When using flags to gate new features that will be enabled by default, make
a plan for removing any opt-outs so the flag itself can be removed, rather
than end up as technical debt.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Flags are a powerful tool for tuning and optimization, but the author of a
customization point has the most context for how to use it effectively.
Choosing good defaults or making features self-tune is often better for the
codebase as a whole.&lt;/p&gt;

    &lt;p&gt;Discoverability, let alone optimal selection, is challenging.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2023-09-30T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/52</link>
          <guid isPermaLink="true">https://abseil.io/fast/52</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #7: Optimizing for application productivity</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #7 on June 6, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-10-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/7&quot;&gt;abseil.io/fast/7&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;p&gt;Google manages a vast fleet of servers to handle search queries, process
records, and transcode cat videos. We don’t buy those servers to allocate memory
in TCMalloc, put protocol buffers into other protocol buffers, or to handle
branch mispredictions by our processors.&lt;/p&gt;

&lt;p&gt;To make our fleet more efficient, we want to optimize for how productive our
servers are, that is, how much useful work they accomplish per CPU-second,
byte-second of RAM, disk operation, or by using hardware accelerators. While
measuring a job’s resource consumption is easy, it’s harder to tell just how
much useful work it’s accomplishing without help.&lt;/p&gt;

&lt;p&gt;A task’s CPU usage going up could mean the task has suffered a performance
regression or that it’s simply busier. Consider a plot of a service’s CPU usage
against time, breaking down the total CPU usage of two versions of the binary.
We cannot determine from casual inspection what caused the increase in CPU
usage, whether this is from an increase in workload (serving more videos per
unit time) or a decrease in efficiency (some added, needless protocol conversion
per video).&lt;/p&gt;

&lt;p&gt;To determine what is really happening, we need a productivity metric which
captures the amount of real work completed. If we know the number of cat videos
processed, we can easily determine whether we are getting more, or less, real
work done per CPU-second (or byte-second of RAM, disk operation, or hardware
accelerator time). These metrics are referred to as &lt;em&gt;application productivity
metrics&lt;/em&gt;, or &lt;em&gt;APMs&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If we do not have productivity metrics, we are faced with &lt;em&gt;entire classes of
optimizations&lt;/em&gt; that are not well-represented by existing metrics:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Application speedups through core infrastructure changes&lt;/strong&gt;:&lt;/p&gt;

    &lt;p&gt;As seen in our &lt;a href=&quot;https://research.google/pubs/pub50370/&quot;&gt;2021 OSDI paper&lt;/a&gt;,
“one classical approach is to increase the efficiency of an allocator to
minimize the cycles spent in the allocator code. However, memory allocation
decisions also impact overall application performance via data placement,
offering opportunities to improve fleetwide productivity by completing more
units of application work using fewer hardware resources.”&lt;/p&gt;

    &lt;p&gt;Experiments with TCMalloc’s hugepage-aware allocator, also known as
Temeraire, have shown considerable speedups by improving application
performance, not time spent in TCMalloc.&lt;/p&gt;

    &lt;p&gt;We spend more &lt;em&gt;relative&lt;/em&gt; time in TCMalloc but greatly improve application
performance. Focusing just on relative time in TCMalloc would produce an
error in sign: We’d deprioritize (or even rollback) a strongly positive
optimization.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Allocating more protocol buffer messages on
&lt;a href=&quot;https://protobuf.dev/reference/cpp/arenas/&quot;&gt;Arenas&lt;/a&gt; speeds up not just the
protocol buffer code itself (like message destructors), but also in the
business logic that uses them. Enabling Arenas in major frameworks allowed
them to process 15-30% more work per CPU, but protobuf destructor costs were
a small fraction of this cost. The improvements in data locality could
produce outsized benefits for the entire application.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;New instruction sets&lt;/strong&gt;: With successive hardware generations, vendors have
added new instructions to their ISAs.&lt;/p&gt;

    &lt;p&gt;In future hardware generations, we expect to replace calls to memcpy with
microcode-optimized &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rep movsb&lt;/code&gt; instructions that are faster than any
handwritten assembly sequence we can come up with. We expect &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rep movsb&lt;/code&gt; to
have low IPC (instructions per cycle): It’s a single instruction that
replaces an entire copy loop of instructions!&lt;/p&gt;

    &lt;p&gt;Using these new instructions can be triggered by optimizing the source code
or through compiler enhancements that improve vectorization.&lt;/p&gt;

    &lt;p&gt;Focusing on MIPS (millions of instructions per second) or IPC would cause us
to prefer any implementation that executes a large number of instructions,
even if those instructions take longer to execute to copy &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt; bytes.&lt;/p&gt;

    &lt;p&gt;In fact, enabling the AVX, FMA, and BMI instruction sets by compiling with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--march=haswell&lt;/code&gt; shows a MIPS regression while simultaneously &lt;em&gt;improving
application productivity&lt;/em&gt;. These instructions can do more work per
instruction, however, replacing several low latency instructions may mean
that &lt;em&gt;average&lt;/em&gt; instruction latency increases. If we had 10 million
instructions and 10 ms per query, we may now have 8 million instructions
taking only 9 ms per query. QPS is up and MIPS would go down.&lt;/p&gt;

    &lt;p&gt;Since Google’s fleet runs on a wide variety of architectures, we cannot
easily compare instructions across platforms and need to instead compare
useful work accomplished by an application.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Compiler optimizations&lt;/strong&gt;: Compiler optimizations can significantly affect
the number of dynamically executed instructions. Techniques such as inlining
reduce function preambles and enable further simplifying optimizations.
Thus, &lt;em&gt;fewer&lt;/em&gt; instructions translate to &lt;em&gt;faster&lt;/em&gt;, &lt;em&gt;more productive&lt;/em&gt; code.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Kernel optimizations&lt;/strong&gt;: The kernel has many policies around hugepages,
thread scheduling, and other system parameters. While changing these
policies may make the kernel nominally more costly, for example, if we did
more work to compact memory, the application benefits can easily outweigh
them.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Availability of these metrics help infrastructure and efficiency teams guide
their work more effectively.&lt;/p&gt;
</description>
          <pubDate>2023-09-14T00:00:00-04:00</pubDate>
          <link>https://abseil.io/fast/7</link>
          <guid isPermaLink="true">https://abseil.io/fast/7</guid>
        </item>
      
    
      
        <item>
          <title>Abseil Breaking Change Policy Update</title>
          <description>&lt;h3 id=&quot;abseil-breaking-change-policy-update&quot;&gt;Abseil Breaking Change Policy Update&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:dmauro@google.com&quot;&gt;Derek Mauro&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today we are announcing that Abseil is adopting the Google
&lt;a href=&quot;https://opensource.google/documentation/policies/library-breaking-change&quot;&gt;OSS Library Breaking Change Policy&lt;/a&gt;.
What does this mean for Abseil users? Let’s take a look.&lt;/p&gt;

&lt;p&gt;Abseil’s original compatibility policy made this statement:&lt;/p&gt;

&lt;p&gt;&lt;i&gt;We will always strive to not break API compatibility. If we feel that we
must, we will provide a compiler-based refactoring tool to assist in the upgrade
… any time we are making a change publicly we’re also doing the work to update
the 250MLoC+ internal Google codebase — we very rarely do such refactoring that
cannot be automated.&lt;/i&gt;&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;In the 6 years since Abseil has been available to the open source community, we
have released only one tool, and we believe that there is a good chance that no
one ever needed to use that tool.&lt;/p&gt;

&lt;p&gt;There are a few reasons why we never really needed to make use of our policy of
providing an automated update tool.&lt;/p&gt;

&lt;p&gt;First, Abseil only ships production-ready APIs. While these APIs did evolve in
their early life, APIs must be considered stable and have thousands of usages in
Google’s internal codebase before they are eligible for inclusion in Abseil.&lt;/p&gt;

&lt;p&gt;Second, as stated in the original policy, when we do change an API, we also have
to update Google’s internal code base. While we do use automated tooling to do
this, the fact that Google’s internal code base is so large constrains the types
of changes that we can make.&lt;/p&gt;

&lt;p&gt;The policy of releasing a tool for automated upgrades has not worked out in
practice. Not only have we not made changes that would have made upgrading
difficult without the use of a tool, but the policy of requiring releasing a
tool has also made it harder for us to release fixes that are technically API
breaks but that impact very few callsites.&lt;/p&gt;

&lt;p&gt;Under the new policy, despite claiming the right to make breaking changes
without shipping an automated upgrade tool, we still commit to making upgrading
as easy as possible, and only making breaking changes when we believe they will
provide benefit to our users. We will announce these changes prominently in our
commit messages as well as in the release notes for
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/releases&quot;&gt;LTS releases&lt;/a&gt;, and will provide
guidance on how to resolve issues.&lt;/p&gt;

&lt;p&gt;Please read our updated
&lt;a href=&quot;https://abseil.io/about/compatibility&quot;&gt;compatibility guidelines&lt;/a&gt; for more
information about what users must (and must not) do to successfully update to
newer versions of Abseil.&lt;/p&gt;
</description>
          <pubDate>2023-08-28T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20230828-breaking-change-policy</link>
          <guid isPermaLink="true">https://abseil.io/blog/20230828-breaking-change-policy</guid>
        </item>
      
    
      
        <item>
          <title>Perf Tips</title>
          <description>&lt;h3 id=&quot;performance-tips-of-the-week&quot;&gt;Performance Tips of the Week&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:aalexand@google.com&quot;&gt;Alexey Alexandrov&lt;/a&gt;, Google Engineer&lt;/p&gt;

&lt;p&gt;We are pleased to announce that we’ve started publishing some of Google’s
internal &lt;a href=&quot;/fast&quot;&gt;“Performance Tips of the Week”&lt;/a&gt; externally on abseil.io!&lt;/p&gt;

&lt;p&gt;These tips form a sort of “Effective analysis and optimization of
production performance and resource usage”: a gallery of “do”s and “don’t”s
gathered from the hard-learned lessons of optimizing performance of
production systems running on machines in Google data centers.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;This set of tips started as an internal series at Google and it has been
hugely popular, with thousands of monthly readers and dozens of episodes
published. We are making some of these episodes available to a wider
external audience as they discuss topics that are common to the industry. 
We hope you find these tips valuable and welcome your feedback!&lt;/p&gt;

&lt;p&gt;–Alexey&lt;/p&gt;

</description>
          <pubDate>2023-03-02T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/03022023-perf-tips</link>
          <guid isPermaLink="true">https://abseil.io/blog/03022023-perf-tips</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #9: Optimizations past their prime</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #9 on June 24, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-10-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/9&quot;&gt;abseil.io/fast/9&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;p&gt;Optimizations don’t always age gracefully. Faster yesterday might mean slower
today.&lt;/p&gt;

&lt;p&gt;Benchmarks citing performance on Intel Pentium 3’s or AMD Opterons may have been
meaningful several years ago, but optimization equilibria, originally chosen for
long-unplugged platforms, may have changed since. Let’s look at a couple
examples where well-intended optimizations ultimately hurt performance in the
long run.&lt;/p&gt;

&lt;h2 id=&quot;popcount&quot;&gt;Popcount&lt;/h2&gt;

&lt;p&gt;In 2008, Intel introduced the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;popcnt&lt;/code&gt; instruction to determine the number of
set bits in a 32- or 64-bit integer. This is of interest for computing hamming
distances and a bunch of other things. Without the instruction, we can use a
slightly
&lt;a href=&quot;https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation&quot;&gt;more complex, longer sequence&lt;/a&gt;
of shifts, bitwise ands, and adds to achieve the same.&lt;/p&gt;

&lt;p&gt;Google’s predecessor library to C++20’s
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/bits.h&quot;&gt;bit manipulation functions&lt;/a&gt;
offered two population count routines. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CountOnes64&lt;/code&gt; uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;popcnt&lt;/code&gt; if the
compiler knows it’s going to be available and a fallback otherwise.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CountOnes64withPopcount&lt;/code&gt; unconditionally uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;popcnt&lt;/code&gt; on x86_64 machines.&lt;/p&gt;

&lt;p&gt;When this instruction first started rolling out, it made sense to test for the
availability of the instruction at runtime before choosing which one to call.
This would be faster for crunching data on the machines with the instruction and
we’d avoid &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIGILL&lt;/code&gt;‘ing on machines without it.&lt;/p&gt;

&lt;p&gt;Years later, every &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt; machine in the fleet supported this instruction, so
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CountOnes64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CountOnes64withPopcount&lt;/code&gt; should be the same, right?&lt;/p&gt;

&lt;p&gt;Unfortunately, we’re still paying for all of the runtime dispatch machinery to
check availability of the instruction, even though the answer is always “yes.”
We could make this a compile time constant, but this is akin to picking up rocks
faster when we should have instead just left them on the ground. The branch cost
might seem trivial, but there’s actually more to be concerned about here.&lt;/p&gt;

&lt;p&gt;Prior to cleanups, the implementations weren’t the same.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CountOnes64withPopcount&lt;/code&gt; used inline assembly to unconditionally emit the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;popcnt&lt;/code&gt; instruction. The inline assembly prevented the compiler from
working around a
&lt;a href=&quot;https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62011&quot;&gt;false dependency bug&lt;/a&gt;
in some processors.&lt;/li&gt;
  &lt;li&gt;When the compiler built-in is used (the “slow” version), we actually end up
with a better sequence of machine code and can perform stronger
optimizations at compile-time around constant folding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the compiler began emitting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;popcnt&lt;/code&gt; instruction for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__builtin_popcount&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CountOnes64&lt;/code&gt; was the unconditionally better
implementation.&lt;/p&gt;

&lt;p&gt;Ironically, code using runtime dispatch to select a “fast” implementation is
(unintentionally) preferring an actually slower implementation
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CountOnes64withPopcount&lt;/code&gt;) and paying for the privilege.&lt;/p&gt;

&lt;h2 id=&quot;check_eq&quot;&gt;&lt;code&gt;CHECK_EQ&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;In 2005, Google implemented its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CHECK&lt;/code&gt; logging macros in terms of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CheckOpString&lt;/code&gt;, a thin wrapper around a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string*&lt;/code&gt;. This later underwent
further optimizations, adding hints to the compiler optimizer that the
comparison would likely be true.&lt;/p&gt;

&lt;p&gt;As of early 2019, a simplified implementation for optimized builds for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CHECK_EQ(a, b)&lt;/code&gt;, after preprocessing looked like:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
template&amp;lt;typename T1, typename T2&amp;gt;
std::string* MakeCheckOpString(const T1&amp;amp; a, const T2&amp;amp; b, const char*);

std::string* Check_EQ_Impl(const T1&amp;amp; a, const T2&amp;amp; b, const char* error) {
  if (ABSL_PREDICT_TRUE(a == b))
    return nullptr;
  else
    return MakeCheckOpString(a, b, error);
}

struct CheckOpString {
  CheckOpString(std::string* str) : str_(str) {}
  operator bool() const { return ABSL_PREDICT_FALSE(str_ != nullptr); }
  std::string* str_;
};

#define CHECK_EQ(a, b)                                                \
  while (CheckOpString _result = Check_EQ_Impl(a, b, &quot;...error...&quot;))  \
    ...log failure...
&lt;/pre&gt;

&lt;p&gt;When LLVM generated assembly for this code, it made two checks:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a == b&lt;/code&gt;: We predict that this is typically true.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_ != nullptr&lt;/code&gt;: We predict that this is typically false.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…but the second check is redundant. Once we’ve determined that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a == b&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_&lt;/code&gt; is &lt;em&gt;always&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nullptr&lt;/code&gt;. This is a missed compiler optimization, but the
optimizer faces the challenge of layers of complexity and hand-tuning added to
this code over a decade.&lt;/p&gt;

&lt;p&gt;Removing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CheckOpString&lt;/code&gt; completely removes the extra branch: We compare &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b&lt;/code&gt;, but the optimizer does not need to reason about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CheckOpString&lt;/code&gt;. Working
directly with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string*&lt;/code&gt; for the comparison leads to better code.
Ironically, this optimization had already been applied to &lt;em&gt;debug&lt;/em&gt; builds, added
in 2008.&lt;/p&gt;

&lt;h2 id=&quot;best-practices&quot;&gt;Best practices&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Prefer writing clear, idiomatic code whenever possible. It is not only
easier to read and debug, but in the long run, also easier for the compiler
to optimize.&lt;/li&gt;
  &lt;li&gt;Whenever you find a low-level performance optimization that requires fancy
bit-twiddling, intrinsics code, or inline assembly, consider first whether
this is something the compiler could do.&lt;/li&gt;
  &lt;li&gt;If the code is hot, and the optimization is not something the compiler can
be taught to perform, then: prefer portable code, possibly using
&lt;a href=&quot;https://github.com/google/highway/blob/master/hwy&quot;&gt;hwy&lt;/a&gt; to generate
efficient and portable vector code, failing that use intrinsics, failing
that use inline asm (this should be extremely rare). Avoiding inline
assembly makes the code more portable across microarchitectures.&lt;/li&gt;
  &lt;li&gt;Keep the “naive” code you are replacing. If you are optimizing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ComputeFoo&lt;/code&gt;,
consider keeping the simple implementation in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;REFERENCE_ComputeFoo&lt;/code&gt;
function. This makes it easy to write a unit-test for the new implementation
that ensures the two functions are equivalent; it makes it easier to write a
microbenchmark; and it makes it easier to revert to the reference code when
(not if) the machine-dependent implementation outlives its usefulness.&lt;/li&gt;
  &lt;li&gt;Include a microbenchmark with your change.&lt;/li&gt;
  &lt;li&gt;When &lt;a href=&quot;/fast/52&quot;&gt;designing or changing configuration knobs&lt;/a&gt;, ensure that the
choices stay optimal over time. Frequently, overriding the default can lead
to suboptimal behavior when the &lt;em&gt;default changes&lt;/em&gt; by pinning things in a
worse-than-out-of-the-box state. Designing the knobs
&lt;a href=&quot;https://youtu.be/J6SNO5o9ADg?t=1521&quot;&gt;in terms of the outcome&lt;/a&gt; rather than
specific behavior aspects can make such overrides easier (or even possible)
to evolve.&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2023-03-02T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/9</link>
          <guid isPermaLink="true">https://abseil.io/fast/9</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #53: Precise C++ benchmark measurements with Hardware Performance Counters</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #53 on October 14, 2021&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:mtrofin@google.com&quot;&gt;Mircea Trofin&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-09-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/53&quot;&gt;abseil.io/fast/53&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use performance benchmarks as the first line of defense in detecting costly
regressions, and as a way to guide performance improvement work. Getting to the
root cause of a change in performance can be time consuming and full of “false
leads”, because on modern architectures program execution is influenced by many
factors.&lt;/p&gt;

&lt;p&gt;In this episode, we present a productivity tool that helps lower the cost of
performance investigations by leveraging
&lt;a href=&quot;https://en.wikipedia.org/wiki/Hardware_performance_counter&quot;&gt;Hardware Performance Counters&lt;/a&gt;
to surface low-level architectural metrics. The tool is available for C++
benchmarks running on Linux, on &lt;a href=&quot;https://github.com/google/benchmark&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-are-hardware-performance-counters&quot;&gt;What are Hardware Performance Counters?&lt;/h2&gt;

&lt;p&gt;Hardware Performance Counters are a hardware feature where you can request
precise counts of events such as: instructions retired, load or store
instructions retired, clock cycles, cache misses, branches taken or
mispredicted, etc. See https://perf.wiki.kernel.org/index.php/Tutorial for more
information.&lt;/p&gt;

&lt;p&gt;With performance counters you get less noisy measurements when compared to
time-based ones. CPU timer-based measurements are noisier, even on isolated
machines, because:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;performance counter measurements can be isolated to the benchmark process,
and, thus, not account context switching time when the process is
preempted - which is otherwise measured by the CPU timer,&lt;/li&gt;
  &lt;li&gt;we can further isolate counter increments to user mode executed instructions
only, which further reduces noise due to context switching&lt;/li&gt;
  &lt;li&gt;specific counters (e.g. instruction-counting ones) inherently produce
measurements that are almost noise-free (variations under 0.01%). This is
because the value of such counters is independent of systemic sources of
noise like frequency throttling.&lt;/li&gt;
  &lt;li&gt;finally, depending on the setup of the benchmarking machine, time-based
measurements suffer from noise introduced by thermal effects,
hyperthreading, or shared resource (like memory bus) access. Some counters
will also suffer from noise due to these, but others - like instructions
retired counters - won’t.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By selecting appropriate performance counters you can get nuanced insight into
the execution of a benchmark. For instance, a measurement using CPU time that
points to a regression may be caused by subtle changes in executable layout,
which increases branch mispredictions. This is generally not actionable and
considered acceptable. Identifying this is the case, when only looking at time
measurements, is not very productive and not scalable over a large benchmark
suite corpus. With performance counter-based measurements, it is immediately
apparent by observing branch mispredict variations and instruction count
variations, and the detection is easily scriptable.&lt;/p&gt;

&lt;h2 id=&quot;how-to-gather-performance-counter-data&quot;&gt;How-to gather performance counter data&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/google/benchmark&quot;&gt;Google Benchmark&lt;/a&gt; project simplifies
the process of writing a benchmark. An example of its use may be seen
&lt;a href=&quot;https://github.com/llvm/llvm-test-suite/tree/main/MicroBenchmarks/LoopVectorization&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The benchmark harness support for performance counters consists of allowing the
user to specify counters in a comma-separated list, via the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--benchmark_perf_counters&lt;/code&gt; flag, to be measured alongside the time measurement.
Just like time measurement, each counter value is captured right before the
benchmarked code is run, and right after. The difference is reported to the user
as per-iteration values (similar to the time measurement).&lt;/p&gt;

&lt;h3 id=&quot;basic-usage&quot;&gt;Basic usage&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: counter names are hardware vendor and version specific. The example
here assumes Intel Skylake. Check how this maps to other versions of Intel CPUs,
other vendors (e.g. AMD), or other architectures (e.g. ARM); also refer to
&lt;a href=&quot;https://perfmon2.sourceforge.net/&quot;&gt;perfmon2&lt;/a&gt; which we use for counter name
resolution, and/or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;perf list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Build a benchmark executable - for example, let’s use “swissmap” from
&lt;a href=&quot;https://github.com/google/fleetbench&quot;&gt;fleetbench&lt;/a&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
bazel build -c opt //fleetbench/swissmap:swissmap_benchmark
&lt;/pre&gt;

&lt;p&gt;Run the benchmark; let’s ask for instructions, cycles, and loads:&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
bazel-bin/fleetbench/swissmap/swissmap_benchmark \
  --benchmark_filter=&apos;.*Cold.*::absl::flat_hash_set.*64.*set_size:64.*density:0&apos; \
  --benchmark_perf_counters=INSTRUCTIONS,CYCLES,MEM_UOPS_RETIRED:ALL_LOADS
&lt;/pre&gt;

&lt;p&gt;The output looks like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Running ./swissmap_benchmark
Run on (8 X 4667.91 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x4)
  L1 Instruction 32 KiB (x4)
  L2 Unified 256 KiB (x4)
  L3 Unified 8192 KiB (x1)
Load Average: 2.31, 2.08, 1.95
---------------------------------------------------------------------------------------------------------------------------------------
Benchmark                                                                             Time             CPU   Iterations UserCounters...
---------------------------------------------------------------------------------------------------------------------------------------
BM_FindMiss_Cold&amp;lt;::absl::flat_hash_set, 64&amp;gt;/set_size:64/density:0                  18.4 ns         18.4 ns     39048136 CYCLES=82.9019 INSTRUCTIONS=35.7284 MEM_UOPS_RETIRED:ALL_LOADS=6.05507
BM_FindHit_Cold&amp;lt;::absl::flat_hash_set, 64&amp;gt;/set_size:64/density:0                   33.3 ns         33.3 ns     20600490 CYCLES=152.156 INSTRUCTIONS=55.0354 MEM_UOPS_RETIRED:ALL_LOADS=15.0034
BM_InsertHit_Cold&amp;lt;::absl::flat_hash_set, 64&amp;gt;/set_size:64/density:0                 34.8 ns         34.8 ns     19004416 CYCLES=157.956 INSTRUCTIONS=59.0354 MEM_UOPS_RETIRED:ALL_LOADS=16.0013
BM_Iterate_Cold&amp;lt;::absl::flat_hash_set, 64&amp;gt;/set_size:64/density:0                   33.5 ns         33.5 ns     25444389 CYCLES=152.431 INSTRUCTIONS=57.9225 MEM_UOPS_RETIRED:ALL_LOADS=13.3892
BM_InsertManyOrdered_Cold&amp;lt;::absl::flat_hash_set, 64&amp;gt;/set_size:64/density:0         54.9 ns         54.8 ns     14141958 CYCLES=242.373 INSTRUCTIONS=111.455 MEM_UOPS_RETIRED:ALL_LOADS=33.1838
BM_InsertManyUnordered_Cold&amp;lt;::absl::flat_hash_set, 64&amp;gt;/set_size:64/density:0       50.0 ns         50.0 ns     14234753 CYCLES=227.516 INSTRUCTIONS=111.415 MEM_UOPS_RETIRED:ALL_LOADS=33.1781
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So we can see that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BM_FindMiss_Cold&lt;/code&gt; took approximately 83 cycles, 36
instructions, and 6 memory ops per iteration.&lt;/p&gt;

&lt;h2 id=&quot;limitations&quot;&gt;Limitations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;Number of counters&lt;/em&gt;: At most 32 events may be requested for simultaneous
collection. Note however, that the number of hardware counters available is
much lower (usually 4-8 on modern CPUs, see
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PerfCounterValues::kMaxCounters&lt;/code&gt;) – requesting more events than the
hardware counters will cause
&lt;a href=&quot;https://perf.wiki.kernel.org/index.php/Tutorial#multiplexing_and_scaling_events&quot;&gt;multiplexing&lt;/a&gt;
and decreased accuracy.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;Visualization&lt;/em&gt;: There is no dedicated visualization UI available, so for
complex analysis, users may need to collect JSON result files and summarize
the results.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;Counting vs. Sampling&lt;/em&gt;: The framework only collects counters in “counting”
mode – it answers how many cycles/cache misses/etc. happened, but not does
not associate them to the code location causing the events. For that, you’d
need a sampling profiler like
&lt;a href=&quot;https://perf.wiki.kernel.org/index.php/Tutorial#Sampling_with_perf_record&quot;&gt;Linux perf&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--benchmark_perf_counters&lt;/code&gt; flag in https://github.com/google/benchmark
benchmarks to quickly drill into the root cause of a performance regression, or
to guide performance optimization work.&lt;/p&gt;
</description>
          <pubDate>2023-03-02T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/53</link>
          <guid isPermaLink="true">https://abseil.io/fast/53</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #39: Beware microbenchmarks bearing gifts</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #39 on January 22, 2021&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt; and &lt;a href=&quot;mailto:alkis@evlogimenos.com&quot;&gt;Alkis Evlogimenos&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-09-29&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/39&quot;&gt;abseil.io/fast/39&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Benchmarks are only a tool for debugging efficiency: Production is ultimately
what matters. Benchmarks analyze the performance of code under the specific
circumstances created and maintained by the benchmark. They cannot perfectly
predict the performance of code in the real world. In this episode, we discuss
some of the pitfalls of microbenchmarks and mitigation strategies.&lt;/p&gt;

&lt;p&gt;For example, we can use the following series of benchmarks for evaluating
changes to search query performance:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Inverted_index&quot;&gt;Posting List&lt;/a&gt; iteration
benchmarks&lt;/li&gt;
  &lt;li&gt;Single task loadtests&lt;/li&gt;
  &lt;li&gt;Cluster loadtests of many tasks&lt;/li&gt;
  &lt;li&gt;Production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each benchmark is increasingly more complicated and increasingly more accurate
but takes more time to run. It is not uncommon for the first and last to
disagree. It is less common for single task loadtests to disagree with cluster
loadtests but it happens. The reason to have the hierarchy of benchmarks is to
&lt;em&gt;optimize the iterative process&lt;/em&gt; of developing performance optimizations
themselves. If we are able to observe and iterate faster (a shorter
“&lt;a href=&quot;https://en.wikipedia.org/wiki/OODA_loop&quot;&gt;OODA loop&lt;/a&gt;”), we explore more ideas
more quickly.&lt;/p&gt;

&lt;p&gt;There is a parallel here to testing, starting from narrow scope (unit tests) to
increasing scope (integration and system tests) to production itself. Like
correctness testing, performance testing is complicated. Unfortunately,
performance testing is less predictive than correctness testing, especially at
the micro scale. Surrounding code or competing processes might interfere with
network resource, memory bandwidth, CPU instruction decoding, branch predictor,
processor cache utilization, flash i/o, mutexes. If, for example, we have medium
confidence that a passing unittest suggests correctness in prod, then we should
have relatively low confidence in benchmark results materializing the same way
in prod.&lt;/p&gt;

&lt;h2 id=&quot;where-benchmarks-mislead&quot;&gt;Where benchmarks mislead&lt;/h2&gt;

&lt;p&gt;There are situations where the results from benchmarks can be misleading when
applied to full applications. The following are some examples of situations
where the results from benchmarks are not applicable at application scale.&lt;/p&gt;

&lt;h3 id=&quot;memcmp-bloat&quot;&gt;&lt;code&gt;memcmp&lt;/code&gt; bloat&lt;/h3&gt;

&lt;p&gt;Google’s software tends to be instruction footprint-heavy, challenging our
ability to effectively cache it, which leads to
&lt;a href=&quot;https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/44271.pdf&quot;&gt;frontend stalls on our processors&lt;/a&gt;.
The functions provided by libc are no exception.&lt;/p&gt;

&lt;p&gt;In
“&lt;a href=&quot;https://storage.googleapis.com/pub-tools-public-publication-data/pdf/e52f61fd2c51e8962305120548581efacbc06ffc.pdf&quot;&gt;AsmDb: Front-End Stalls in WSC&lt;/a&gt;”
(Figure 13 / Section 4.4), the glibc implementation for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcmp&lt;/code&gt; was ~6KB,
leading to icache misses of its own and evictions of other functions. The
implementation for glibc is in hand-written assembly, using a variety of
techniques based on comparison size to obtain “good” performance. 99% of cycles
in the function span 41 cache lines, or about 2.6KB of cache capacity.&lt;/p&gt;

&lt;p&gt;Individually, these small micro-optimizations were entirely justifiable with
microbenchmarks. We saw this in greater detail while developing a
&lt;a href=&quot;https://research.google/pubs/pub50338/&quot;&gt;Google workload-tuned &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt; implementation&lt;/a&gt;:
“Faster” implementations on microbenchmarks had larger code footprints and
produced &lt;em&gt;worse&lt;/em&gt; macrobenchmark results than seemingly slower implementations
that had smaller code footprints.&lt;/p&gt;

&lt;p&gt;This is undoubtedly a place where hardware acceleration can shine to deliver its
best possible performance consistently, rather than having programmers optimize
their implementations for each generation (only to make things worse in real
workloads).&lt;/p&gt;

&lt;h3 id=&quot;arithmetic-versus-load&quot;&gt;Arithmetic versus load&lt;/h3&gt;

&lt;p&gt;Consider a simple masking function, to get the lower bits of a value:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
uint32_t getLowerBits(uint32_t value, int bits) {
  return value &amp;amp; ((uint64_t{1} &amp;lt;&amp;lt; bits) - 1);
}
&lt;/pre&gt;

&lt;p&gt;This requires several instructions and processor uops to shift, subtract, and
finally mask. This might motivate loading a precomputed array of masks.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
constexpr uint32_t kMasks[] = {0x1, 0x3, 0x7, 0xf, ...};

uint32_t getLowerBits(uint32_t value, int bits) {
  return value &amp;amp; kMasks[bits];
}
&lt;/pre&gt;

&lt;p&gt;This might appear to be a profitable optimization in microbenchmarks. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kMasks&lt;/code&gt;
can be consistently cached in L1. Modeling cache behavior in microbenchmarks is
challenging: Microbenchmarks tend to have small working sets that tend to be
cache resident. Real code, particularly Google C++, is not.&lt;/p&gt;

&lt;p&gt;In production, the cacheline holding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kMasks&lt;/code&gt; might be evicted, leading to much
worse stalls
(&lt;a href=&quot;https://sre.google/static/pdf/rule-of-thumb-latency-numbers-letter.pdf&quot;&gt;hundreds of cycles to access main memory&lt;/a&gt;).
Additionally, on x86 processors since Haswell, this
&lt;a href=&quot;/fast/9&quot;&gt;optimization can be past its prime&lt;/a&gt;: BMI2’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bzhi&lt;/code&gt; instruction is both
faster than loading and masking &lt;em&gt;and&lt;/em&gt; delivers more consistent performance.&lt;/p&gt;

&lt;p&gt;When developing benchmarks for
&lt;a href=&quot;https://abseil.io/blog/20180927-swisstables&quot;&gt;SwissMap&lt;/a&gt;, individual operations
were benchmarked in two ways: always triggering a cache hit and always
triggering a cache miss. The latter can be achieved by having enough hashtables
that their working set will not fit in cache, then picking a hashtable to lookup
at random on every iteration of the benchmark.&lt;/p&gt;

&lt;p&gt;Having explicit benchmarks for the boundary conditions - always-cache-hit and
always-cache-miss gives more insight on how changes to the code affect its
operations under different conditions and help develop intuition on which
operations are important to optimize to reach our goal: improve production
performance.&lt;/p&gt;

&lt;h3 id=&quot;tcmallocs-suspicious-prefetch&quot;&gt;TCMalloc’s suspicious prefetch&lt;/h3&gt;

&lt;p&gt;TCMalloc has a suspicious prefetch on its allocation path. By the time we’ve
computed which object to return, prefetching would be too late: User code could
begin using the object within a few cycles. Instead, it prefetches the &lt;em&gt;next&lt;/em&gt;
object of the same size class that would be returned. This object will not be
used by the application until the next time we allocate another object of the
same size.&lt;/p&gt;

&lt;p&gt;This prefetch appears to be extraordinarily costly: Microbenchmarks measuring
allocation performance show potential savings if it were removed and Google-Wide
Profiling shows 70%+ of cycles in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt;’s fastpath on the prefetch. Removing it
would “reduce” the
&lt;a href=&quot;https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/44271.pdf&quot;&gt;data center tax&lt;/a&gt;,
but we would actually hurt &lt;a href=&quot;/fast/7&quot;&gt;application productivity&lt;/a&gt;-per-CPU. Time we
spend in malloc is
&lt;a href=&quot;https://storage.googleapis.com/gweb-research2023-media/pubtools/6170.pdf&quot;&gt;less important than application performance&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Trace-driven simulations with hardware-validated architectural simulators showed
the prefetched data was frequently used. Additionally, it is better to stall on
a TLB miss at the prefetch site–which has no dependencies, than to stall at the
point of use.&lt;/p&gt;

&lt;h2 id=&quot;pitfalls&quot;&gt;Pitfalls&lt;/h2&gt;

&lt;p&gt;There are a number of things that commonly go wrong when writing benchmarks. The
following is a non-exhaustive list:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Data being resident. Workloads have large footprints, a small footprint may
be instruction bound, whereas the true workload could be
&lt;a href=&quot;/fast/62&quot;&gt;memory bound&lt;/a&gt;. There’s a trade-off between adding instructions to
save some memory costs vs placing data in memory to save instructions.&lt;/li&gt;
  &lt;li&gt;Small instruction cache footprint. Google codes typically have large
instruction footprints. Benchmarks are often cache resident. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcmp&lt;/code&gt;
and TCMalloc examples go directly to this.&lt;/li&gt;
  &lt;li&gt;Sensitivity to function and branch alignment. Small changes to code layout
and branch alignment can have large effects on microbenchmark performance.
Code being changed can also affect neighboring code that is actually
benchmarked, leading to paradoxical speedups and slowdowns. For example,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy&lt;/code&gt; has 20% swings from this effect. For several years,
&lt;a href=&quot;https://github.com/google/snappy&quot;&gt;snappy&lt;/a&gt; had “load bearing nops” to
perturb branch alignment of an inner loop to an optimal state.
&lt;a href=&quot;https://people.cs.umass.edu/~emery/pubs/stabilizer-asplos13.pdf&quot;&gt;Stabilizer (by Berger, et. al.)&lt;/a&gt;
deliberately perturb these parameters to improve benchmarking statistical
quality.&lt;/li&gt;
  &lt;li&gt;Sensitivity to stack alignment. Changes anywhere in the stack–added/removed
variables, better (or worse) spilling due to compiler optimizations,
etc.–can affect the alignment at the start of the function-under-test. This
has been seen to produce 20% performance swings.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Representative data. The data in the benchmark needs to be “similar” to the
data in production - for example, imagine having short strings in the
benchmark, and long strings in the fleet. This also extends to the code
paths in the benchmarks being similar to the code paths that the application
exercises. This is a common pain point for macrobenchmarks too. A loadtest
may cover certain request types, rather than all of those seen by production
servers.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Benchmarking the right code. It’s very easy to introduce code into the
benchmark that’s not present in the real workload. For example, using a
random number generator’s cost for a benchmark could exceed the cost of the
work being benchmarked.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Being aware of steady state vs dynamic behaviour. For more complex
benchmarks it’s easy to produce something that converges to a steady state -
for example if it has a constant arrival rate and service time. Production
workloads may demonstrate more variability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;leveraging-benchmarks-fully&quot;&gt;Leveraging benchmarks fully&lt;/h2&gt;

&lt;p&gt;Focus on &lt;a href=&quot;/fast/75&quot;&gt;writing microbenchmarks&lt;/a&gt; that test individual properties of
the component under test. Using Search as an example, consider the compute
kernel of search intersects posting lists (PLs). A posting list is a sorted
sequence of hits, where a hit is an occurrence of a term in a document. When a
query like “dog AND cat” is executed, the PLs for terms “dog” and “cat” are
intersected to find the documents that contain both “dog” and “cat”.&lt;/p&gt;

&lt;p&gt;For PLs we benchmark the basic operations of a PL:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PL iterator creation/destruction&lt;/li&gt;
  &lt;li&gt;PL iterator iteration&lt;/li&gt;
  &lt;li&gt;PL iterator advance (jump forward)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observe production behaviour to determine the appropriate code and functionality
to optimize:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Profile production jobs to identify which operation is critical to
performance.&lt;/p&gt;

    &lt;p&gt;In some cases, PL iterator advance is where the majority of CPU cycles are
spent. In others, PL iterator creation is as critical as PL iterator
advance.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;After identification of the above, one can start looking for opportunities
to:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;improve PL iterator creation/destruction &lt;strong&gt;without&lt;/strong&gt; pessimizing PL
iterator advance&lt;/li&gt;
      &lt;li&gt;improve PL iterator advance &lt;strong&gt;without&lt;/strong&gt; pessimizing PL iterator
creation/destruction&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Note: PL iterator iteration is largely irrelevant - at this particular time
and shape of the system&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After coming up with a strategy and prototype to improve the two microbenchmarks
in isolation, run a more accurate test (single task) to validate that this
results in meaningful improvements. The next steps depend on whether this, more
accurate, benchmark also produces favorable results:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If not, it is very important to understand why and fix the microbenchmark:
it is likely not measuring what is intended!&lt;/li&gt;
  &lt;li&gt;If yes, then proceed with higher accuracy tests (full cluster/prod) and
gather artifacts measuring the impact of the change.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One might wonder why writing the PL iterator iteration benchmark is useful if it
does not show up in production profiles. One useful piece of information we can
extract from this benchmark is the relative performance of iteration vs advance.
With such knowledge at hand, one can look into opportunities to use iteration
more prominently in the intersection kernel code. For example, it may be more
efficient to replace the advance operation with multiple iteration actions.
Pragmatically, even though iteration contributes few cycles, we don’t want its
performance to regress to the point where it does take significant time.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Benchmarks are a useful way to prototype the impact of code changes on
production systems. However, writing benchmarks that accurately reflect
production performance is hard. There are multiple pitfalls where the size of
the benchmark, or other of its characteristics, may lead to incorrect estimates
of production impact. One approach to solving this is to have multiple
benchmarks, with increasing fidelity and complexity. Understanding why a
particular benchmark does not produce representative results is a critical step
in improving benchmark fidelity, and can even produce insights into production
behavior.&lt;/p&gt;
</description>
          <pubDate>2023-03-02T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/39</link>
          <guid isPermaLink="true">https://abseil.io/fast/39</guid>
        </item>
      
    
      
        <item>
          <title>Performance Tip of the Week #21: Improving the efficiency of your regular expressions</title>
          <description>&lt;p&gt;Originally posted as Fast TotW #21 on January 16, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:junyer@google.com&quot;&gt;Paul Wankadia&lt;/a&gt; and &lt;a href=&quot;mailto:djgove@google.com&quot;&gt;Darryl Gove&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2025-09-03&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/fast/21&quot;&gt;abseil.io/fast/21&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Regular expressions are used, misused and abused nearly everywhere. Google is no
exception, alas, and at our scale, even a simple change can save hundreds or
thousands of cores. In this tip, we describe ways to use RE2 more efficiently.&lt;/p&gt;

&lt;p&gt;NOTE: This tip is specifically about RE2 and C++. A number of the ideas below
are universally applicable, but discussion of other libraries and other
languages is out of scope.&lt;/p&gt;

&lt;h2 id=&quot;using-regular-expressions-a-representative-sample&quot;&gt;Using regular expressions: a representative sample&lt;/h2&gt;

&lt;p&gt;As a prelude, let’s consider an example of how regular expressions are often
used. This snippet looks for a zone ID at the end of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zone_name&lt;/code&gt; string and
extracts its value into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zone_id&lt;/code&gt; integer:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
int zone_id;
if (RE2::FullMatch(zone_name, R&quot;(.*\.zone(\d+))&quot;, &amp;amp;zone_id)) {
&lt;/pre&gt;

&lt;p&gt;This tip describes several techniques for improving efficiency in situations
such as this. These fall into two broad categories: improving the code that uses
regular expressions; and improving the regular expressions themselves.&lt;/p&gt;

&lt;h2 id=&quot;writing-more-efficient-code&quot;&gt;Writing more efficient code&lt;/h2&gt;

&lt;h3 id=&quot;a-few-words-about-re2-objects&quot;&gt;A few words about &lt;code&gt;RE2&lt;/code&gt; objects&lt;/h3&gt;

&lt;p&gt;In order to understand why the following techniques matter, we need to talk
briefly about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2&lt;/code&gt; objects. In the initial example, we passed a pattern string
to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2::FullMatch()&lt;/code&gt;. Passing a pattern string instead of an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2&lt;/code&gt; object
implicitly constructs a temporary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2&lt;/code&gt; object. During construction, RE2 parses
the pattern string to a syntax tree and compiles the syntax tree to an
automaton. Depending on the complexity of the regular expression, construction
can require a lot of CPU time and can build an automaton that will have a large
memory footprint.&lt;/p&gt;

&lt;h3 id=&quot;use-abseil-functions-for-literal-strings&quot;&gt;Use Abseil functions for literal strings&lt;/h3&gt;

&lt;p&gt;In many situations, regular expressions are unnecessary because simple string
operations will suffice. For exact matching, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; defines
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator==()&lt;/code&gt;. For substring, prefix and suffix matching, Abseil provides
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrContains()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StartsWith()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::EndsWith()&lt;/code&gt;,
respectively, in
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/strings/match.h&quot;&gt;absl/strings/match.h&lt;/a&gt;.
These are much faster than regular expressions and more readable, so using them
where possible is recommended.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
const RE2 re(absl::StrCat(row_key, &quot;:.*&quot;));
for (const auto&amp;amp; row : rows) {
  if (RE2::FullMatch(row, re)) {
&lt;/pre&gt;

&lt;p&gt;could be rewritten as:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
const std::string prefix = absl::StrCat(row_key, &quot;:&quot;);
for (const auto&amp;amp; row : rows) {
  if (absl::StartsWith(row, prefix)) {
&lt;/pre&gt;

&lt;h3 id=&quot;minimise-re2-object-churn&quot;&gt;Minimise &lt;code&gt;RE2&lt;/code&gt; object churn&lt;/h3&gt;

&lt;p&gt;As discussed above, constructing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2&lt;/code&gt; objects can be expensive, so as a rule of
thumb, they should be long-lived. Precompiling or caching them where possible is
recommended.&lt;/p&gt;

&lt;h3 id=&quot;use-lazyre2-for-static-or-global-regular-expressions&quot;&gt;Use &lt;code&gt;LazyRE2&lt;/code&gt; for static or global regular expressions&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2&lt;/code&gt; class is unsafe for direct use with static or global regular
expressions. Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyRE2&lt;/code&gt; instead because it lazily constructs the underlying
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2&lt;/code&gt; object and never destructs it.&lt;/p&gt;

&lt;p&gt;The initial example could be rewritten as:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
static constexpr LazyRE2 kZoneRe = {R&quot;(.*\.zone(\d+))&quot;};
int zone_id;
if (RE2::FullMatch(zone_name, *kZoneRe, &amp;amp;zone_id)) {
&lt;/pre&gt;

&lt;h2 id=&quot;writing-more-efficient-regular-expressions&quot;&gt;Writing more efficient regular expressions&lt;/h2&gt;

&lt;h3 id=&quot;use-re2partialmatch-to-avoid-leading-or-trailing-&quot;&gt;Use &lt;code&gt;RE2::PartialMatch()&lt;/code&gt; to avoid leading or trailing &lt;code&gt;.*&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2::FullMatch()&lt;/code&gt; with leading or trailing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; is an antipattern.
Instead, change it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2::PartialMatch()&lt;/code&gt; and remove the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt;.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2::PartialMatch()&lt;/code&gt; performs an unanchored search, so it is also necessary to
anchor the regular expression (i.e. with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;^&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&lt;/code&gt;) to indicate that it must
match at the start or end of the string. Let’s look at some examples.&lt;/p&gt;

&lt;h4 id=&quot;replacing-leading-&quot;&gt;Replacing leading &lt;code&gt;.*&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;For a regular expression with a leading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt;, the leading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; should be removed
and the regular expression should be anchored at the end with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&lt;/code&gt;. For example,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*-(?:bar|qux)-foo&lt;/code&gt; should become &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-(?:bar|qux)-foo$&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The leading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; prevents RE2 from terminating reverse execution (i.e. backwards
from the end of the input string) after matching the last byte of interest. When
the remainder of the input string is relatively large, RE2 has to do a lot more
work for no benefit. More about that shortly…&lt;/p&gt;

&lt;p&gt;The initial example could be rewritten further as:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
static constexpr LazyRE2 kZoneRe = {R&quot;(\.zone(\d+)$)&quot;};
int zone_id;
if (RE2::PartialMatch(zone_name, *kZoneRe, &amp;amp;zone_id)) {
&lt;/pre&gt;

&lt;h4 id=&quot;replacing-trailing-&quot;&gt;Replacing trailing &lt;code&gt;.*&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;For a regular expression with a trailing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt;, the trailing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; should be
removed and the regular expression should be anchored at the start with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;^&lt;/code&gt;. For
example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo-(?:bar|qux)-.*&lt;/code&gt; should become &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;^foo-(?:bar|qux)-&lt;/code&gt;. RE2 will detach
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;^foo-&lt;/code&gt; prefix and match it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcmp(3)&lt;/code&gt;. (Note that this optimisation
applies when the regular expression has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;^&lt;/code&gt; plus some literal string as its
prefix–even when using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2::FullMatch()&lt;/code&gt;!)&lt;/p&gt;

&lt;p&gt;The trailing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; prevents RE2 from terminating execution after matching the
last byte of interest. When the remainder of the input string is relatively
large, RE2 has to do a lot more work for no benefit. More about that very
shortly…&lt;/p&gt;

&lt;h4 id=&quot;replacing-leading-and-trailing-&quot;&gt;Replacing leading and trailing &lt;code&gt;.*&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;For a regular expression with both a leading and trailing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt;, both the leading
and trailing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; should be removed. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*-(?:bar|qux)-.*&lt;/code&gt; should
become &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-(?:bar|qux)-&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The leading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; prevents RE2 from using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memchr(3)&lt;/code&gt; to find the first byte of
interest. (Note that this optimisation applies when the regular expression has
one distinct first byte such as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo\d+&lt;/code&gt;, but not when there are two
or more possible first bytes such as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\d&lt;/code&gt; ≡ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0-9]&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\d+bar&lt;/code&gt;.)&lt;/p&gt;

&lt;h4 id=&quot;what--really-means&quot;&gt;What &lt;code&gt;.*&lt;/code&gt; really means&lt;/h4&gt;

&lt;p&gt;The problem with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; is that it doesn’t mean “match anything” by default. In
fact, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt; ≡ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[^\n]&lt;/code&gt; by default, so it matches any character that isn’t newline.
RE2 defaults to UTF-8 encoding, so it builds an automaton that handles multibyte
characters. Consequently, the default meaning of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; is “match zero or more
multibyte characters that aren’t newline”. An automaton steps over the input
string one byte at a time, so executing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*&lt;/code&gt; is much slower than using
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memchr(3)&lt;/code&gt; (which is typically implemented using SIMD) and it is infinitely
slower than terminating execution as soon as the regular expression has been
matched.&lt;/p&gt;

&lt;h3 id=&quot;minimise-capturing-groups-and-submatches&quot;&gt;Minimise capturing groups and submatches&lt;/h3&gt;

&lt;p&gt;In situations where parentheses are necessary for grouping, use a non-capturing
group (i.e. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(?:&lt;/code&gt; … &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;)&lt;/code&gt;) unless a submatch is being extracted. Moreover,
extract as few submatches as possible because execution engine selection depends
in part on how many submatches the caller wants.&lt;/p&gt;

&lt;p&gt;Passing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nullptr&lt;/code&gt; for a no-op submatch is an antipattern. Instead, change the
capturing group to a non-capturing group.&lt;/p&gt;

&lt;h3 id=&quot;use-abslstring_view-for-submatches&quot;&gt;Use &lt;code&gt;absl::string_view&lt;/code&gt; for submatches&lt;/h3&gt;

&lt;p&gt;When extracting a submatch, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;. Extracting to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;
necessarily involves a string copy.&lt;/p&gt;

&lt;p&gt;The same advice applies even when extracting a submatch with numeric conversion.
Extracting to a numeric type also involves a string copy because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strtol(3)&lt;/code&gt; et
al. require NUL-terminated strings. Extracting to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; and
calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::SimpleAtoi()&lt;/code&gt; et al. avoids the string copy.&lt;/p&gt;

&lt;p&gt;The initial example could be rewritten even further as:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
static constexpr LazyRE2 kZoneRe = {R&quot;(\.zone(\d+)$)&quot;};
absl::string_view zone_id_str;
int zone_id;
if (RE2::PartialMatch(zone_name, *kZoneRe, &amp;amp;zone_id_str) &amp;amp;&amp;amp;
    absl::SimpleAtoi(zone_id_str, &amp;amp;zone_id)) {
&lt;/pre&gt;

&lt;h3 id=&quot;minimise-ambiguity&quot;&gt;Minimise ambiguity&lt;/h3&gt;

&lt;p&gt;The “cost” of executing a regular expression depends greatly on ambiguity. See
the comments in
&lt;a href=&quot;https://github.com/google/re2/blob/main/re2/onepass.cc&quot;&gt;re2/onepass.cc&lt;/a&gt; for
details, but the rules can be summarised as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;it must be immediately obvious which branch of an alternation to take; and&lt;/li&gt;
  &lt;li&gt;it must be immediately obvious when a repetition ends.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(.+)/&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(.+?)/&lt;/code&gt; are ambiguous because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt; aren’t
disjoint–a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;/&apos;&lt;/code&gt; byte could be consumed by either. In contrast, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;([^/]+)/&lt;/code&gt; is
unambiguous because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[^/]&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt; are disjoint. It isn’t always possible to
eliminate ambiguity, but it is often possible to reduce it.&lt;/p&gt;

&lt;h4 id=&quot;exception-common-prefixes-of-alternations&quot;&gt;Exception: common prefixes of alternations&lt;/h4&gt;

&lt;p&gt;RE2 will factor common prefixes of alternations. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;abacus|abalone&lt;/code&gt;
parses as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aba(?:cus|lone)&lt;/code&gt;. This optimisation permits the regular expression to
be written in a more readable manner. Note that it applies to contiguous runs,
so lexicographically sorting the subexpressions is recommended.&lt;/p&gt;

&lt;h3 id=&quot;avoid-counted-repetition&quot;&gt;Avoid counted repetition&lt;/h3&gt;

&lt;p&gt;A subexpression of the form &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x{n}&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x{n,}&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x{n,m}&lt;/code&gt; results in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; being
duplicated at least &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m&lt;/code&gt; times in the automaton. It’s bad enough
(particularly when using Unicode character classes) for anchored matching, but
it’s dangerous for unanchored matching because it’s easy to blow up the number
of DFA states and their sizes. Each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2&lt;/code&gt; object has a memory budget (8 MiB by
default) mostly for caching DFA states; exhausting the memory budget incurs a
considerable performance hit.&lt;/p&gt;

&lt;p&gt;For example, constructing the entire DFA needs 22 KiB for the anchored
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;^[a-q][^u-z]{13}x&lt;/code&gt; versus 6 MiB for the unanchored &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[a-q][^u-z]{13}x&lt;/code&gt;. The
former isn’t useful for searching due to being anchored, but the latter isn’t
efficient due to the exponential blowup in DFA states from being unanchored.
Matching &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[a-q][^u-z]+x&lt;/code&gt; instead (i.e. using uncounted repetition) may be
possible, but checking the length of the match in a subsequent step might not be
acceptable.&lt;/p&gt;

&lt;h2 id=&quot;bonus-matching-multiple-regular-expressions&quot;&gt;Bonus: Matching multiple regular expressions&lt;/h2&gt;

&lt;p&gt;To finish, let’s touch on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2::Set&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FilteredRE2&lt;/code&gt;. These are two very
different approaches to matching multiple regular expressions, which is useful
in situations where performing multiple passes over the input string would be
prohibitively expensive. Such situations include keyword matching and logs
processing.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2::Set&lt;/code&gt; combines the regular expressions into one “many match” automaton. It
has strengths and weaknesses similar to those of normal DFA execution and is
suited to shorter, less complex regular expressions.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FilteredRE2&lt;/code&gt; identifies the literal string “atoms” within the regular
expressions; given which of those “atoms” occur within the input string, it
determines which regular expressions potentially match. It requires an initial
pass over the input string with something like Aho-Corasick or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE2::Set&lt;/code&gt; and is
suited to longer, more complex regular expressions.&lt;/p&gt;

&lt;p&gt;You might also like to read about
&lt;a href=&quot;https://doi.org/10.1007/978-3-642-24212-0_4&quot;&gt;lightgrep&lt;/a&gt;,
&lt;a href=&quot;https://dl.acm.org/doi/10.5555/3323234.3323286&quot;&gt;Hyperscan&lt;/a&gt; and
&lt;a href=&quot;https://dl.acm.org/doi/10.1007/s00778-003-0094-0&quot;&gt;RE-tree&lt;/a&gt;, which were designed
specifically for matching multiple regular expressions.&lt;/p&gt;
</description>
          <pubDate>2023-03-02T00:00:00-05:00</pubDate>
          <link>https://abseil.io/fast/21</link>
          <guid isPermaLink="true">https://abseil.io/fast/21</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #198: Tag Types</title>
          <description>&lt;p&gt;Originally posted as TotW #198 on August 12, 2021&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:akonradi@google.com&quot;&gt;Alex Konradi&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2022-01-24&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/198&quot;&gt;abseil.io/tips/198&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Suppose we have a class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Foo {
 public:
  explicit Foo(int x, int y);
  Foo&amp;amp; operator=(const Foo&amp;amp;) = delete;
  Foo(const Foo&amp;amp;) = delete;
};
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; is neither movable nor copyable, but it is constructible, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo f(1,
2);&lt;/code&gt;. Since it has a public constructor, we can easily make an instance wrapped
in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::optional&amp;lt;Foo&amp;gt; maybe_foo;
maybe_foo.emplace(5, 10);
&lt;/pre&gt;

&lt;p&gt;That’s great, but what if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; is declared &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;, so we can’t
call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace()&lt;/code&gt;? Luckily for us, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; has a constructor for this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Pass std::in_place as the first argument, followed by the arguments for Foo&apos;s
// constructor.
const std::optional&amp;lt;Foo&amp;gt; maybe_foo(std::in_place, 5, 10);
&lt;/pre&gt;

&lt;p&gt;Wait, what’s going on with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place&lt;/code&gt;? If we look at
&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/optional/optional&quot;&gt;the documentation&lt;/a&gt;
for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; construction, we can see that one of the overloads takes a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_t&lt;/code&gt; as the first argument, along with a list of additional
arguments. Since
&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/in_place&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place&lt;/code&gt;&lt;/a&gt; is an
instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_t&lt;/code&gt;, the compiler chooses the &lt;em&gt;emplacing constructor&lt;/em&gt;,
which instantiates &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; within the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; by forwarding the rest of
the arguments to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;’s constructor.&lt;/p&gt;

&lt;p&gt;If we look a little closer at the documentation for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_t&lt;/code&gt;, we see
that it’s… an empty struct. No special qualifiers or magic declarations. The
only thing even mildly special about it is that the standard library includes a
named instance of it, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;overload-resolution-via-tag-types&quot;&gt;Overload Resolution Via Tag Types&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_t&lt;/code&gt; is a member of a loose category of classes sometimes referred
to as “tag types”. The function of these classes is to pass information to the
compiler by “tagging” specific overloads in an overload set. By providing an
instance of an appropriate tag class to an overloaded function (often a
constructor), we can use the compiler’s ordinary resolution rules to make it
select the desired overload. In the case of our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; construction,
the compiler sees that the first argument is of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_t&lt;/code&gt; and so
chooses the matching emplacing constructor.&lt;/p&gt;

&lt;p&gt;Though &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_t&lt;/code&gt; was introduced in C++17, the use of empty classes for
tagging overloads in the standard library has been prevalent since
&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/piecewise_construct_t&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::piecewise_construct_t&lt;/code&gt;&lt;/a&gt;,
was introduced in C++11 to select the emplacing constructor for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair&lt;/code&gt;.
C++17 significantly expanded the set of tag types in the standard library.&lt;/p&gt;

&lt;h2 id=&quot;templates-of-course&quot;&gt;Templates, of Course&lt;/h2&gt;

&lt;p&gt;Besides disambiguating overloads, another common use case for tag types is to
pass type information to templated constructors. Consider these two structs:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct A { A(); /* internal members */ };
struct B { B(); /* internal members */ };
&lt;/pre&gt;

&lt;p&gt;Let’s try to construct an instance of
&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/variant&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&amp;lt;A, B&amp;gt;&lt;/code&gt;&lt;/a&gt; with
each:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// These work if A and B are copy- or move-constructible, but incur the
// performance cost of an extra copy or move construction.
std::variant&amp;lt;A, B&amp;gt; with_a{A()};
std::variant&amp;lt;A, B&amp;gt; with_b{B()};

// These aren&apos;t valid C++; the language doesn&apos;t support providing constructor
// template parameters explicitly.
std::variant&amp;lt;A, B&amp;gt; try_templating_a&amp;lt;A&amp;gt;{};
std::variant&amp;lt;A, B&amp;gt;&amp;lt;B&amp;gt; try_templating_b{};
&lt;/pre&gt;

&lt;p&gt;What we need is a way to tell the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&lt;/code&gt; constructor that we want to
instantiate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; without actually providing an instance of either. For
that, we can use
&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/in_place&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_type&lt;/code&gt;&lt;/a&gt;!&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::variant&amp;lt;A, B&amp;gt; with_a{std::in_place_type&amp;lt;A&amp;gt;};
std::variant&amp;lt;A, B&amp;gt; with_b{std::in_place_type&amp;lt;B&amp;gt;};
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_type&amp;lt;T&amp;gt;&lt;/code&gt; is an instance of the class template
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_type_t&amp;lt;T&amp;gt;&lt;/code&gt;, which is (unsurprisingly, at this point) empty. By
passing a value of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place_type_t&amp;lt;A&amp;gt;&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&lt;/code&gt;’s
constructor, the compiler can deduce that the constructor template parameter is
our class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;

&lt;p&gt;Tag types show up occasionally when interacting with generic class templates,
especially ones from the standard library. One of the shortcomings of tag types
is that other techniques, such as factory functions, often result in more
readable code. Take the following example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// This tag spelling requires the reader to know how std::optional interacts
// with std::in_place.
std::optional&amp;lt;Foo&amp;gt; with_tag(std::in_place, 5, 10);

// Here the intent is clearer: make an optional Foo by providing these arguments.
std::optional&amp;lt;Foo&amp;gt; with_factory = std::make_optional&amp;lt;Foo&amp;gt;(5, 10);
&lt;/pre&gt;

&lt;p&gt;These two &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;Foo&amp;gt;&lt;/code&gt; objects are guaranteed to be constructed
identically thanks to C++17’s &lt;a href=&quot;/tips/166&quot;&gt;mandatory copy elision&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So why use tags? Because factory functions don’t always work:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// This doesn&apos;t work because Foo isn&apos;t move-constructible.
std::optional&amp;lt;std::optional&amp;lt;Foo&amp;gt;&amp;gt; foo(std::make_optional&amp;lt;Foo&amp;gt;(5, 10));
&lt;/pre&gt;

&lt;p&gt;The above example doesn’t compile because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;’s move constructor is deleted.
To make this work, we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place&lt;/code&gt; to select the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt;
constructor that forwards the remaining arguments.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// This constructs everything in place, resulting in a single call to Foo&apos;s
// constructor.
std::optional&amp;lt;std::optional&amp;lt;Foo&amp;gt;&amp;gt; foo(std::in_place, std::in_place, 5, 10);
&lt;/pre&gt;

&lt;p&gt;In addition to working in places where factory functions don’t, tag types have
some other nice properties:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;they are
&lt;a href=&quot;https://en.cppreference.com/w/cpp/named_req/LiteralType&quot;&gt;literal types&lt;/a&gt;
which means we can declare &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; instances, even in header files, like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::in_place&lt;/code&gt;;&lt;/li&gt;
  &lt;li&gt;because they are empty, the compiler can optimize them out, resulting in
zero runtime overhead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Though they’re used in the standard library, encountering empty tag types in the
wild is relatively uncommon. If you find yourself using one, consider adding a
comment to help your readers:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::unordered_map&amp;lt;int, Foo&amp;gt; int_to_foo;
// std::piecewise_construct is a tag for overload resolution of std::pair&apos;s
// constructor. Emplaces 100 -&amp;gt; Foo(5, 10) in the map.
int_to_foo.emplace(std::piecewise_construct,
                   std::forward_as_tuple(100),
                   std::forward_as_tuple(5, 10));
&lt;/pre&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Tag types are a powerful way to give additional information to the compiler.
While at first glance they might seem magical, they use the same overload
resolution and template type deduction rules as the rest of C++. The standard
library uses class tags for disambiguating constructor calls, and you can use
the same mechanisms to define tags for your own needs.&lt;/p&gt;

&lt;h2 id=&quot;see-also&quot;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/integer_sequence&quot;&gt;std::integer_sequence&lt;/a&gt;
for compile-time indexing of tuples&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/134#what-about-stdshared-ptr&quot;&gt;passkey for std::make_shared&lt;/a&gt; uses tags
to control access&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2023-02-15T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/198</link>
          <guid isPermaLink="true">https://abseil.io/tips/198</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #218: Designing Extension Points With FTADLE</title>
          <description>&lt;p&gt;Originally posted as TotW #218 on January 19, 2023&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:asoffer@google.com&quot;&gt;Andy Soffer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2023-01-19&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/218&quot;&gt;abseil.io/tips/218&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ftadle. It’s a perfectly cromulent word. ~ Unknown&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;designing-extension-points&quot;&gt;Designing Extension Points&lt;/h2&gt;

&lt;p&gt;Suppose you work on a library called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sketchy&lt;/code&gt;, that draws on a canvas. You
already provide ways to draw some common things like points, lines, and text,
but you want to provide a mechanism where users can specify how to draw their
own types. You’re designing an &lt;strong&gt;extension point&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;design-goals-for-extension-points&quot;&gt;Design Goals For Extension Points&lt;/h3&gt;

&lt;p&gt;C++ provides many mechanisms for defining extension points, each with their own
benefits and drawbacks. When defining an extension point in C++ there are
several considerations worth weighing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Readability – How easy is it for an engineer to understand the relationship
between your library and the extension?&lt;/li&gt;
  &lt;li&gt;Maintainability – How easy will it be to change the extension point as the
needs of your library and your library’s users change?&lt;/li&gt;
  &lt;li&gt;Dependency Hygiene – Does your extension point require your library to be
linked in to a user’s binary? We want to make sure extension points play
nicely with
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Include_What_You_Use&quot;&gt;IWYU&lt;/a&gt;,
so if a header needs to be included for the extension mechanism to work, the
extended types should actually use something from that header.&lt;/li&gt;
  &lt;li&gt;Lack of &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/definition&quot;&gt;ODR violations&lt;/a&gt; – Some mechanisms make it easy to
have different portions of your program have contradictory views about what
a program means. ODR violations are always a bug.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;ftadle-a-good-pattern-with-a-great-name&quot;&gt;FTADLE: A Good Pattern With A Great Name&lt;/h3&gt;

&lt;p&gt;When defining an extension point, we recommend following a pattern that we
lovingly call &lt;em&gt;FTADLE&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; (Friend Template
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/adl&quot;&gt;ADL&lt;/a&gt; Extension)&lt;/em&gt;. FTADLE does
well on each of the considerations listed above. It relies heavily on a language
feature known as ADL, or Argument Dependent Lookup; the process by which the
compiler determines what function is intended when a function call appears
without namespace qualification (i.e., no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::&lt;/code&gt;s). ADL is explained in detail in
&lt;a href=&quot;/tips/49&quot;&gt;Tip #49&lt;/a&gt;, To write an extension using the FTADLE pattern:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Pick a name for your extension point and prefix it with your project’s
namespace. Our extension is for drawing, and our project lives in the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sketchy&lt;/code&gt; namespace, so we’ll call our extension &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SketchyDraw&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Design a type to be passed in to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SketchyDraw&lt;/code&gt; that has all the behavior
your users will need. In our case, this is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sketchy::Canvas&lt;/code&gt; on which
users can draw their types.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Implement your functionality as an overload set. One member of that overload
set will be a template and will call your extension point. The non-template
functions in the overload set should be the basic building blocks; the
primitive types that your API supports. In our running example, that means
functions that accept the types &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sketchy::Point&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sketchy::Line&lt;/code&gt;.&lt;/p&gt;

    &lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
namespace sketchy {
// Draws the point `p` on the canvas `c`.
void Draw(Canvas&amp;amp; c, const Point&amp;amp; p);

// Draws the line segment `l` on the canvas `c`.
void Draw(Canvas&amp;amp; c, const Line&amp;amp; l);

// For any user-defined type `T` which implements `SketchyDraw` (see
// documentation that I&apos;ve definitely written), draws `value` on the canvas
// `c`.
template &amp;lt;typename T&amp;gt;
void Draw(Canvas&amp;amp; c, const T&amp;amp; value) {
  // Called without namespace qualifiers. We rely on ADL to find the correct
  // overload. See [Tip #49](/tips/49) for details on ADL.
  SketchyDraw(c, value);
}

}  // namespace sketchy
&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this extension-point designed, users will now be able to make their types
drawable. How can an unrelated type add this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Draw&lt;/code&gt; functionality without adding
an explicit dependency? We can make use of a friend function to do so. By adding
a friend function template in their type named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SketchyDraw&lt;/code&gt; with the
appropriate signature. the template overload above will use ADL to find the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SketchyDraw&lt;/code&gt; function. For example,&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Triangle {
 public:
  explicit Triangle(Point a, Point b, Point c) : a_(a), b_(b), c_(c) {}

  template &amp;lt;typename SC&amp;gt;
  friend void SketchyDraw(SC&amp;amp; canvas, const Triangle&amp;amp; triangle) {
    // Note: This is a template, even though the only type we ever expect to be
    // passed in for `SC` is `sketchy::Canvas`. Using `sketchy::Canvas` directly
    // works, but pulls in an extra dependency that may not be used by all users
    // of `Triangle`.
    sketchy::Draw(canvas, sketchy::Line(triangle.a_, triangle.b_));
    sketchy::Draw(canvas, sketchy::Line(triangle.b_, triangle.c_));
    sketchy::Draw(canvas, sketchy::Line(triangle.c_, triangle.a_));
  }

 private:
  Point a_, b_, c_;
};

// Usage:
void DrawTriangles(sketchy::Canvas&amp;amp; canvas, absl::Span&amp;lt;const Triangle&amp;gt; triangles) {
  for (const Triangle&amp;amp; triangle : triangles) {
    sketchy::Draw(canvas, triangle);
  }
}
&lt;/pre&gt;

&lt;p&gt;NOTE: Users of the library never call the ADL extension point &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SketchyDraw&lt;/code&gt;
directly. Rather, the library should provide a function like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sketchy::Draw&lt;/code&gt;
which invokes the extension point on the user’s behalf.&lt;/p&gt;

&lt;h2 id=&quot;other-examples&quot;&gt;Other Examples&lt;/h2&gt;

&lt;p&gt;The FTADLE pattern has been used with several other common libraries.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslHashValue&lt;/code&gt; extension point allows you to make your type hashable by
any of Abseil’s hash containers. See &lt;a href=&quot;/tips/152&quot;&gt;Tip #152&lt;/a&gt; for details.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify&lt;/code&gt; extension point allows you to print your type with many
many Abseil libraries, including logging, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat&lt;/code&gt;,
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Substitute&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-to-avoid&quot;&gt;What To Avoid&lt;/h2&gt;

&lt;p&gt;Some common extension point mechanisms fall short of our design goals. Virtual
functions, checking at compile-time for member functions, and template
specialization are each brittle in their own way, as discussed below.&lt;/p&gt;

&lt;h3 id=&quot;virtual-functions&quot;&gt;Virtual Functions&lt;/h3&gt;

&lt;p&gt;Though perhaps the most familiar, virtual functions and class hierarchies are
often overly rigid. They are nearly impossible to refactor, because the base
class and all derived classes need to be updated in lock-step. We rarely get
designs right on the first try, so it’s prudent to have a design that we can
change later.&lt;/p&gt;

&lt;p&gt;Beyond the rigidity, class hierarchies &lt;em&gt;force&lt;/em&gt; a dependency on your users. In
the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sketchy&lt;/code&gt;, users are required to depend on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sketchy&lt;/code&gt; code, even when
only some of their binaries want to use the dependency. FTADLE ensures that only
binaries that need to do something &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sketchy&lt;/code&gt; pay that cost.&lt;/p&gt;

&lt;p&gt;The same is true for non-template friend extension points as well (for example
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::ostream&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt;). Each class that wishes to implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt;
must include one of the standard library headers defining &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::ostream&lt;/code&gt; (e.g.,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;ostream&amp;gt;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/code&gt;). This means that (barring optimizations) the code for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::ostream&lt;/code&gt; will be compiled and linked into the binary whether or not
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt; is used, a potential extra cost to compile-times and binary size.&lt;/p&gt;

&lt;h3 id=&quot;member-functions&quot;&gt;Member Functions&lt;/h3&gt;

&lt;p&gt;With some template trickery, you could check to see if a class has a particular
method by name (or even signature). However, names can be misleading.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// Requires that the image have a `draw()` member function.
template &amp;lt;typename Image&amp;gt;
void DisplayImage(const Image&amp;amp; image) {
  image.draw();
}

class Cowboy {
 public:
  // Draws the gun from the holster.
  void draw();
};

int main() {
  Cowboy c;
  DisplayImage(c);  // Oops, not the &quot;draw&quot; we meant.
}
&lt;/pre&gt;

&lt;p&gt;With the FTADLE pattern, the extension point is prefixed with the project’s
namespace, mitigating accidental conformance.&lt;/p&gt;

&lt;h3 id=&quot;template-specializations&quot;&gt;Template Specializations&lt;/h3&gt;

&lt;p&gt;Another common but dangerous technique is to use template specializations. This
is how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::hash&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::less&lt;/code&gt; are specialized.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
namespace std {

template&amp;lt;&amp;gt;
struct hash&amp;lt;MyType&amp;gt; {
  size_t operator()(const MyType&amp;amp; m) const {
    return HashCombine(std::hash&amp;lt;&amp;gt;()(m.foo()), std::hash&amp;lt;&amp;gt;()(m.bar()));
  }
};

}  // namespace std
&lt;/pre&gt;

&lt;p&gt;Aside from requiring more boilerplate, this technique is ripe for
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/definition&quot;&gt;ODR violations&lt;/a&gt;. While not terribly common, providing different
specializations for this type in different translation units, or even the same
definition twice is an ODR violation. More commonly, if such a specialization is
available only in some translation units but not others, metaprogramming
techniques will produce different answers to the question “is there a hash
function available?” which is also an ODR-violation.&lt;/p&gt;

&lt;p&gt;Beyond that, it is generally bad practice to open up a namespace you do not own
(amongst other reasons, because it leads to ODR violations). We should design
our APIs to avoid bad practices so as not to accidentally encourage dangerous
practices.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The FTADLE extension point pattern is readable, maintainable, mitigates against
ODR violations, and avoids adding dependencies. If your library needs an
extension point, FTADLE comes highly recommended.&lt;/p&gt;

&lt;!-- note: footnotes need to be after any end-of-document links --&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;C++ has a rich tradition of almost-pronounceable
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/acronyms&quot;&gt;acronyms&lt;/a&gt;, including
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/raii&quot;&gt;RAII&lt;/a&gt;,
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/ndr&quot;&gt;IFNDR&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern&quot;&gt;CRTP&lt;/a&gt;,
and &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/sfinae&quot;&gt;SFINAE&lt;/a&gt;. We have
been pronouncing FTADLE as “fftah-dill” (similar to “paddle” but with the
‘p’ replaced by the sound at the end of “raft”), but we encourage you to
pronounce it in whichever way brings you the most joy. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
          <pubDate>2023-01-19T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/218</link>
          <guid isPermaLink="true">https://abseil.io/tips/218</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #3: String Concatenation and &lt;code&gt;operator+&lt;/code&gt; vs. &lt;code&gt;StrCat()&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #3 on May 11, 2012&lt;/p&gt;

&lt;p&gt;Updated 2022-11-16&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/3&quot;&gt;abseil.io/tips/3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Users are often surprised when a reviewer says, “Don’t use the string
concatenation operator, it’s not that efficient.” How can it be that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string::operator+&lt;/code&gt; is inefficient? Isn’t it hard to get that wrong?&lt;/p&gt;

&lt;p&gt;It turns out, such inefficiency isn’t clear cut. These two snippets have close
to the same execution time, in practice:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string foo = LongString1();
std::string bar = LongString2();
std::string foobar = foo + bar;

std::string foo = LongString1();
std::string bar = LongString2();
std::string foobar = absl::StrCat(foo, bar);
&lt;/pre&gt;

&lt;p&gt;However, the same is not true for these two snippets:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string foo = LongString1();
std::string bar = LongString2();
std::string baz = LongString3();
std::string foobarbaz = foo + bar + baz;

std::string foo = LongString1();
std::string bar = LongString2();
std::string baz = LongString3();
std::string foobarbaz = absl::StrCat(foo, bar, baz);
&lt;/pre&gt;

&lt;p&gt;The reason these two cases differ can be understood when we pick apart what is
happening in the expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo + bar + baz&lt;/code&gt;. Since there are no overloads for
three-argument operators in C++, this operation is necessarily going to make two
calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string::operator+&lt;/code&gt;. And between those two calls, the operation will
construct (and store) a temporary string. So `std::string foobarbaz = foo + bar&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;baz` is really equivalent to:&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string temp = foo + bar;
std::string foobarbaz = std::move(temp) + baz;
&lt;/pre&gt;

&lt;p&gt;Specifically, note that the contents of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar&lt;/code&gt; must be copied to a
temporary location before they are placed within &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foobarbaz&lt;/code&gt;. (For more on
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move&lt;/code&gt;, see &lt;a href=&quot;/tips/77&quot;&gt;Tip #77&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;C++11 at least allows the second concatenation to happen without creating a new
string object: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move(temp) + baz&lt;/code&gt; is equivalent to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move(temp.append(baz))&lt;/code&gt;. However, it’s possible that the buffer initially
allocated for the temporary won’t be large enough to hold the final string, in
which case a reallocation (and another copy) will be required. As a result, in
the worst case, chains of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt; string concatenations require O(n) reallocations.&lt;/p&gt;

&lt;p&gt;It is better instead to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt;, a nice helper function from
google3/third_party/absl/strings/str_cat.h that calculates the necessary string
length, reserves that size, and concatenates all of the input data into the
output - a well-optimized O(n). Similarly, for cases like:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
foobar += foo + bar + baz;
&lt;/pre&gt;

&lt;p&gt;use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrAppend()&lt;/code&gt;, which performs similar optimizations:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
absl::StrAppend(&amp;amp;foobar, foo, bar, baz);
&lt;/pre&gt;

&lt;p&gt;In addition, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrAppend()&lt;/code&gt; operate on types other
than just string types: you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrAppend&lt;/code&gt; to convert
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int32_t&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint32_t&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64_t&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint64_t&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;float&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;double&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt;,
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;, like this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string foo = absl::StrCat(&quot;The year is &quot;, year);
&lt;/pre&gt;

&lt;p&gt;For additional information, see
&lt;a href=&quot;https://abseil.io/docs/cpp/guides/strings#abslstrcat-and-abslstrappend-for-string-concatenation&quot;&gt;absl::StrCat() and absl::StrAppend() for String Concatenation&lt;/a&gt;.&lt;/p&gt;
</description>
          <pubDate>2022-11-16T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/3</link>
          <guid isPermaLink="true">https://abseil.io/tips/3</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #215: Stringifying Custom Types with &lt;code&gt;AbslStringify()&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #215 on November 2, 2022&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:phoebeliang@google.com&quot;&gt;Phoebe Liang&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2022-11-16&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/215&quot;&gt;abseil.io/tips/215&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Abseil now contains a new lightweight mechanism, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt;, that allows
users to format user-defined types as strings. User-defined types that are
extended using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; work out of the box with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Substitute&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As with most type extensions, you should own the type you wish to extend.&lt;/p&gt;

&lt;p&gt;Let’s say that we have a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Point&lt;/code&gt; struct:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Point {
  int x;
  int y;
};
&lt;/pre&gt;

&lt;p&gt;If we want a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Point&lt;/code&gt; to be formattable with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Substitute()&lt;/code&gt;, we add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;friend&lt;/code&gt; function template
named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Point {
  template &amp;lt;typename Sink&amp;gt;
  friend void AbslStringify(Sink&amp;amp; sink, const Point&amp;amp; p) {
    absl::Format(&amp;amp;sink, &quot;(%d, %d)&quot;, p.x, p.y);
  }

  int x;
  int y;
};
&lt;/pre&gt;

&lt;p&gt;Note: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; utilizes a generic “sink” buffer to construct its
string. This sink has an interface similar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::FormatSink&lt;/code&gt;, but does not
support &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PutPaddedString()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat(&quot;The point is &quot;, p)&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Substitute(&quot;The point is $0&quot;,
p)&lt;/code&gt; will just work.&lt;/p&gt;

&lt;p&gt;Note: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt; also provides
&lt;a href=&quot;https://abseil.io/docs/cpp/guides/format#user-defined-formats&quot;&gt;a more customizable extension point&lt;/a&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslFormatConvert()&lt;/code&gt; that is not supported by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;type-deduction-with-the-v-specifier&quot;&gt;Type Deduction with the &lt;code&gt;%v&lt;/code&gt; Specifier&lt;/h2&gt;

&lt;p&gt;But what if we want to format our type using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt;?
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt;’s existing type specifiers don’t support user-defined types
extended with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt;, so we would have to do something like this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
absl::StrFormat(&quot;The point is (%d, %d)&quot;, p.x, p.y)
&lt;/pre&gt;

&lt;p&gt;This is obviously not ideal. It doesn’t make use of the extension at all and it
duplicates the format string used in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; definition. Instead,
we can use the new type specifier &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
absl::StrFormat(&quot;The point is %v&quot;, p)
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt; uses type deduction to format an argument. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt; supports the formatting of
most primitive types, as well as any types extended using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt;. You
can think of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt; as a generic way to format a “value” of any type that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt; can deduce. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt; can also be used directly within
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; definitions.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt; specifier deduces the following types:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d&lt;/code&gt; for signed integral values&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;u&lt;/code&gt; for unsigned integral values&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g&lt;/code&gt; for floating point values
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;double&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;float&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;long double&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; for string values
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string_view&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Cord&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOTE: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; is &lt;strong&gt;not&lt;/strong&gt; supported. See below for more information.&lt;/p&gt;

&lt;p&gt;Some examples:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
absl::StrFormat(&quot;%v&quot;, std::string{&quot;hello&quot;})    -&amp;gt; &quot;hello&quot;
absl::StrFormat(&quot;%v&quot;, 42)    -&amp;gt; &quot;42&quot;
absl::StrFormat(&quot;%v&quot;, uint64_t{16})    -&amp;gt; &quot;16&quot;
absl::StrFormat(&quot;%v&quot;, 1.6)  -&amp;gt; &quot;1.6&quot;
absl::StrFormat(&quot;%v&quot;, true) -&amp;gt; &quot;true&quot;
&lt;/pre&gt;

&lt;h3 id=&quot;types-with-special-handling&quot;&gt;Types With Special Handling&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt; intentionally does not support &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;char&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; due to ambiguity in
the desired output format. Boolean values are printed as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;true&quot;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;false&quot;&lt;/code&gt;
rather than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;1&quot;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;0&quot;&lt;/code&gt;, which is how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt; print booleans otherwise.&lt;/p&gt;

&lt;h2 id=&quot;integration-with-other-libraries&quot;&gt;Integration With Other Libraries&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; has additional support throughout other Abseil libraries.&lt;/p&gt;

&lt;h3 id=&quot;logging&quot;&gt;Logging&lt;/h3&gt;

&lt;p&gt;Types that define &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; are directly loggable:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Point {
  template &amp;lt;typename Sink&amp;gt;
  friend void AbslStringify(Sink&amp;amp; sink, const Point&amp;amp; p) {
    absl::Format(&amp;amp;sink, &quot;(%v, %v)&quot;, p.x, p.y);
  }

  int x = 10;
  int y = 20;
};

Point p;

LOG(INFO) &amp;lt;&amp;lt; p;
&lt;/pre&gt;

&lt;p&gt;This code will produce a message in the logs like:&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
I0926 09:00:00.000000   12345 main.cc:10] (10, 20)
&lt;/pre&gt;

&lt;p&gt;It is recommended that custom types be made loggable by implementing
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; rather than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt; as it is a universal stringification
extension that also enables &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Substitute&lt;/code&gt; support.&lt;/p&gt;

&lt;h3 id=&quot;protocol-buffer-types&quot;&gt;Protocol Buffer Types&lt;/h3&gt;

&lt;p&gt;Protocol buffers are formattable using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt;. Since
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; provides an overall smoother user experience over
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DebugString()&lt;/code&gt;, it is recommended that users use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; when
formatting protos as strings.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
message MyProto {
  optional string my_string = 1
}

MyProto my_proto;
my_proto.set_my_string(&quot;hello world&quot;);

absl::StrCat(&quot;My proto is: &quot;, my_proto);
absl::StrFormat(&quot;My proto is: %v&quot;, my_proto);
LOG(INFO) &amp;lt;&amp;lt; my_proto;
&lt;/pre&gt;

&lt;h2 id=&quot;closing-words&quot;&gt;Closing Words&lt;/h2&gt;

&lt;p&gt;Aside from user-defined types where its use is required, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt; type specifier
is intended for use in cases where the precise formatting is not important. It
is essentially a catch-all “just print it in a human readable manner” specifier.
If you require any other guarantees beyond that, please use one of the more
specific type specifiers.&lt;/p&gt;
</description>
          <pubDate>2022-11-16T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/215</link>
          <guid isPermaLink="true">https://abseil.io/tips/215</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #18: String Formatting with Substitute</title>
          <description>&lt;p&gt;Originally posted as TotW #18 on October 4, 2012&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:titus@cs.ucr.edu&quot;&gt;Titus Winters&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2022-11-16&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/18&quot;&gt;abseil.io/tips/18&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It happens all the time: you’re writing code and suddenly you need to assemble a
new string from a template and some run-time values. Maybe it’s an error message
from a failed Stubby call, maybe it’s the body of an email being sent from an
internal process. Probably the most common mechanism for string formatting
outside of google3 is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sprintf/snprintf&lt;/code&gt;. But as we wander through the codebase,
we see many things that people have done, and many places where C++ engineers
are spending too much of their time, too many cycles, and too many lines of code
to accomplish this task. In this week’s tip, we will walk through some common
options and point out their various drawbacks.&lt;/p&gt;

&lt;h2 id=&quot;option-1-string-concatenation-built-in&quot;&gt;Option 1: String Concatenation (built-in)&lt;/h2&gt;

&lt;p&gt;Some people still just reach for basic string concatenation:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string GetErrorMessage(const std::string&amp;amp; op, const std::string&amp;amp; user,
                            int id) {
  return &quot;Error in &quot; + op + &quot; for user &quot; + user + &quot;(&quot; + std::to_string(id) +
         &quot;)&quot;;
}
&lt;/pre&gt;

&lt;p&gt;As we saw back in &lt;a href=&quot;/tips/3&quot;&gt;Tip #3&lt;/a&gt;, there are problems with this approach:
chains of calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator+()&lt;/code&gt; wind up making (and wasting) temporaries, and
cause needless copies of your data.&lt;/p&gt;

&lt;h2 id=&quot;option-2-abslstrcat-google3third_partyabslstringsstr_cath&quot;&gt;Option 2: absl::StrCat() (google3/third_party/absl/strings/str_cat.h)&lt;/h2&gt;

&lt;p&gt;Just like in Tip #3, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt; avoids those copies, handles the numeric
conversion for us (go/willitstrcat), and even allows us to operate on
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; efficiently (which is better in cases when we are called with a
C-style string):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string GetErrorMessage(absl::string_view op, absl::string_view user,
                            int id) {
  return absl::StrCat(&quot;Error in &quot;, op, &quot; for user &quot;, user, &quot;(&quot;, id, &quot;)&quot;);
}
&lt;/pre&gt;

&lt;p&gt;However, it’s still a little difficult to see at a glance what the string
actually will look like: Where are the spaces? Do the parentheses in the string
match up properly?&lt;/p&gt;

&lt;h2 id=&quot;option-3-abslsubstitute-google3third_partyabslstringssubstituteh&quot;&gt;Option 3: absl::Substitute (google3/third_party/absl/strings/substitute.h)&lt;/h2&gt;

&lt;p&gt;However, an even better option exists: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Substitute()&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Substitute()&lt;/code&gt; uses
the same techniques as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrCat()&lt;/code&gt; to allow you to pass numeric values,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;s, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;char*&lt;/code&gt;s, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;s. It doesn’t require you to remember
arcane format strings for numeric types (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Even though everyone can more-or-less understand printf-style format strings,
Substitute format strings are just as hard to misinterpret:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string GetErrorMessage(absl::string_view op, absl::string_view user,
                            int id) {
  return absl::Substitute(&quot;Error in $0 for user $1 ($2)&quot;, op, user, id);
}
&lt;/pre&gt;

&lt;p&gt;Good readability, and better performance? LGTM.&lt;/p&gt;
</description>
          <pubDate>2022-11-16T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/18</link>
          <guid isPermaLink="true">https://abseil.io/tips/18</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #124: &lt;code&gt;absl::StrFormat()&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #124 on October 11, 2016&lt;/p&gt;

&lt;p&gt;Updated 2022-11-16&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/124&quot;&gt;abseil.io/tips/124&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-str_format-library-and-abslstrformat&quot;&gt;The &lt;code&gt;str_format&lt;/code&gt; Library and &lt;code&gt;absl::StrFormat()&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;After a long testing and development period, we’re pleased to announce that the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_format&lt;/code&gt; library is now generally available. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_format&lt;/code&gt; library is a
very efficient, typesafe, and extensible library that implements all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf&lt;/code&gt;
formatting syntax. Nearly all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf&lt;/code&gt;-style conversions can be trivially
upgraded to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt;. For more detailed documentation, see
https://abseil.io/docs/cpp/guides/format. It’s the best option for printf-style
formatting, but no position is taken here on where printf-style is or isn’t
appropriate.&lt;/p&gt;

&lt;p&gt;Usage is simple. Add a BUILD dependency on
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;//third_party/absl/strings:str_format&lt;/code&gt;, and include the header:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
#include &quot;absl/strings/str_format.h&quot;
&lt;/pre&gt;

&lt;p&gt;Most users will interact with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_format&lt;/code&gt; library simply by calling
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt; just as they’d call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StringPrintf()&lt;/code&gt; or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;util::format::StringF()&lt;/code&gt; in the past. There are also &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrAppendFormat()&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StreamFormat()&lt;/code&gt; variants.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string s = absl::StrFormat(&quot;%d %s\n&quot;, 123, &quot;hello&quot;);
&lt;/pre&gt;

&lt;p&gt;Unlike the C library’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf()&lt;/code&gt;, the correctness of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt;
conversions doesn’t rely on callers encoding the exact types of arguments into
the format string. With &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf()&lt;/code&gt; this must be carefully done with length
modifiers and conversion specifiers, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%llu&lt;/code&gt; encoding the type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unsigned
long long&lt;/code&gt;. But &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt; is written in C++, so it uses templates and
overloading to safely work directly with types in the caller’s argument list. In
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt;, a format conversion specifies a broader C++ conceptual
category instead of an exact type. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%s&lt;/code&gt; binds to any string-like
argument, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cord&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; are
all accepted. Likewise, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%d&lt;/code&gt; accepts an integer-like argument, etc. It can be
further extended for basic user-defined types (though we’d like to manage the
extensions for now). It ignores length modifiers like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ll&lt;/code&gt; and formats any
usable value. For example, clients do not have to unnecessarily hardcode the
types of the data members of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; here:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
  X x = project_x::GetStats();
  LOG(INFO) &amp;lt;&amp;lt; absl::StreamFormat(&quot;%s:%08x&quot;, x.name, x.size);
&lt;/pre&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; can be anything string-like, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size&lt;/code&gt; can be any integer-like type.
This decoupling is great for the maintainers of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project_x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can also control the destination much more smoothly with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_format&lt;/code&gt;
library. In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf()&lt;/code&gt; family, there was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fprintf()&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FILE*&lt;/code&gt; output,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sprintf()&lt;/code&gt; for writing to a buffer, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asprintf()&lt;/code&gt; for writing to allocated
memory, or the (now deprecated) usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StringPrintf()&lt;/code&gt; (with wasteful
multiple calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vsnprintf()&lt;/code&gt;). The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_format&lt;/code&gt; library uses an abstract
sink, so the destination can be customized without loss of efficiency. As
built-ins, we have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt; to produce a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrAppendFormat()&lt;/code&gt; to append to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;, and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StreamFormat()&lt;/code&gt; to write to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::ostream&lt;/code&gt; (such as for logging).&lt;/p&gt;

&lt;p&gt;Under the clang compiler, compile-time checking is performed on literal format
strings. In the uncommon case of format strings determined at runtime, the
format string must be parsed and checked against an argument list specification
for compatibility before it can be used. This eliminates a danger of traditional
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf()&lt;/code&gt; when using runtime formats. This ability to produce parsed format
specifiers (similar to how regular expressions can be compiled into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RE&lt;/code&gt;
objects) can yield a performance boost, so in performance-sensitive code it may
be used even with statically-determined format strings.&lt;/p&gt;

&lt;p&gt;There are a few notable differences from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf()&lt;/code&gt; (see
https://abseil.io/docs/cpp/guides/format). We try in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_format&lt;/code&gt; library to
be flexible without information loss. If a signed argument is formatted with an
unsigned conversion like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%u&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%x&lt;/code&gt;, we convert the argument to the
corresponding unsigned integer type before formatting, so printing negatives
with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%u&lt;/code&gt; may work differently from one’s expectations on this previously
undefined behavior.&lt;/p&gt;

&lt;p&gt;Best of all, it is highly optimized and much faster than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sprintf()&lt;/code&gt; or the
deprecated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StringPrintf()&lt;/code&gt; (see &lt;a href=&quot;https://docs.google.com/a/google.com/spreadsheets/d/1-pEDOge3DzXiyEoO9xC2JJxL4Ybf-XdPu1nXzBiUsAM&quot; title=&quot;Format shootout results&quot;&gt;format-shootout&lt;/a&gt;). Please give this library a
try anywhere you’d use printf-style formatting.&lt;/p&gt;

&lt;h3 id=&quot;examples&quot;&gt;Examples&lt;/h3&gt;

&lt;p&gt;I’ll close with a few examples.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
#include &quot;absl/strings/str_format.h&quot;

absl::StrAppendFormat(&amp;amp;s, &quot;Also, %s\n&quot;, epilogue);

// Logs something like: &quot;billydonahue         12345.67&quot;
// When formatting streamed output, prefer `absl::StreamFormat()` instead of
// stream I/O manipulators like `std::setw`.
// See https://google.github.io/styleguide/cppguide.html#Streams for more information.
for (const auto&amp;amp; g : hard_workers)
  LOG(INFO) &amp;lt;&amp;lt; absl::StreamFormat(&quot;%-20s %8.2f&quot;, g.username, g.bonus);

// POSIX positional specifiers (yields &quot;veni, vidi, vici!&quot;).
summary = absl::StrFormat(&quot;%2$s, %3$s, %1$s!&quot;, &quot;vici&quot;, &quot;veni&quot;, &quot;vidi&quot;);

std::string letter = response.format_string();  // known only at runtime
// Reject unacceptable form letters.
auto format = absl::ParsedFormat&amp;lt;&apos;d&apos;, &apos;s&apos;, &apos;s&apos;&amp;gt;::New(letter);
if (!format) {
  // ... error case ...
  return;
}
letter = StringF(*format, vacation_days, from, to);

// Precompile for performance. Yields, e.g., rows like:
//   &quot;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;alice&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;00000123&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;\n&quot;
//   &quot;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;bob&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;00004567&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;\n&quot;
static const auto* const pfmt = new absl::ParsedFormat&amp;lt;&apos;s&apos;,&apos;d&apos;&amp;gt;(
    &quot;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;%s&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;%08d&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;\n&quot;);
for (const auto&amp;amp; joe : folks) {
  absl::StrAppendFormat(&amp;amp;output, *pfmt, joe.name, joe.id);
}
// The &apos;FormatStreamed&apos; adaptor can be used to format any ostream-formattable
// &apos;x&apos;.
s = absl::StrFormat(&quot;[%-12s]&quot;, absl::FormatStreamed(x));

&lt;/pre&gt;

</description>
          <pubDate>2022-11-16T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/124</link>
          <guid isPermaLink="true">https://abseil.io/tips/124</guid>
        </item>
      
    
      
        <item>
          <title>Abseil Stringify</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:phoebeliang@google.com&quot;&gt;Phoebe Liang&lt;/a&gt;, Abseil Engineer&lt;/p&gt;

&lt;p&gt;We are pleased to introduce an easier way to format user-defined types as strings in
Abseil: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt;. This API allows user-defined types to be printed more
easily using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To “stringify” a custom type, define a friend function template named
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify(&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; 
  &lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Sink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;friend&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AbslStringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sink&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;(%d, %d)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt; will work right out of the box like so:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrCat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;The point is &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To print custom types with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt;, use the new type specifier &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrFormat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;The point is %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt; uses type deduction to print an argument and supports any user-defined type
that provides an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbslStringify()&lt;/code&gt; definition. Most types that are supported
natively by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrFormat()&lt;/code&gt; are also supported by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%v&lt;/code&gt;. For a full list of
supported types, see the &lt;a href=&quot;https://abseil.io/docs/cpp/guides/format&quot;&gt;StrFormat Guide&lt;/a&gt;.&lt;/p&gt;
</description>
          <pubDate>2022-11-15T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/11152022-stringify</link>
          <guid isPermaLink="true">https://abseil.io/blog/11152022-stringify</guid>
        </item>
      
    
      
        <item>
          <title>Abseil Logging</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:durandal@google.com&quot;&gt;Andy Getzendanner&lt;/a&gt;, Abseil Engineer&lt;/p&gt;

&lt;p&gt;We are pleased to announce, at long last, the initial availability of the Abseil
Logging library.  This library provides facilities for writing short text
messages about the status of a program to stderr, disk files, or other sinks
(via an extension API).&lt;/p&gt;

&lt;p&gt;The core interface is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LOG&lt;/code&gt; macro, which has a streaming interface like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::ostream&lt;/code&gt;’s:&lt;/p&gt;
&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StatusOr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Duration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetUserAge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetUserId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;LOG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ERROR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;No user found named &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NotFoundError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrCat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;No user found named &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age_map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The library also supports terminating the process via a severity level named
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FATAL&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Duration&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetUserAge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;LOG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FATAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;No user named &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; found&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// No need for a return statement; this line is unreachable.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age_map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CHECK&lt;/code&gt; macro family provides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assert()&lt;/code&gt;-like precondition checking and
process termination &lt;strong&gt;in all compilation modes&lt;/strong&gt; with better error messages:&lt;/p&gt;
&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Duration&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetUserAge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;CHECK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;No user named &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; found&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age_map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--break--&gt;

&lt;p&gt;If you are familiar with the
&lt;a href=&quot;https://github.com/google/glog&quot;&gt;Google Logging (glog)&lt;/a&gt; library, these examples
will look very familiar; that project and this one share a common ancestor.  The
core macro APIs are essentially unchanged, however other interfaces like the
extension points have changed quite a bit.  While those changes aim to improve
interfaces, performance, extensibility, etc., the main reason to choose Abseil
Logging over glog is for its compatibility and integration with Abseil and with
Google’s internal code now and in the future.&lt;/p&gt;

&lt;p&gt;For more information, consult the
&lt;a href=&quot;/docs/cpp/guides/logging&quot;&gt;Abseil Logging library documentation&lt;/a&gt;.&lt;/p&gt;

</description>
          <pubDate>2022-09-08T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/09082022-logging</link>
          <guid isPermaLink="true">https://abseil.io/blog/09082022-logging</guid>
        </item>
      
    
      
        <item>
          <title>The Danger of Atomic Operations</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:ahedberg@google.com&quot;&gt;Ashley Hedberg&lt;/a&gt;, Software Engineer&lt;/p&gt;

&lt;p&gt;The C++ Standard provides a library for performing fine-grained atomic
operations (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::atomic&lt;/code&gt;). Engineers sometimes reach for these
atomic operations in the hope to introduce some lock-free mechanism,
or to introduce clever tricks to improve performance. At Google, we’ve
found – more often than not – that such attempts lead to code that
is difficult to get right, hard to understand, and can often introduce
subtle and sometimes dangerous bugs.&lt;/p&gt;

&lt;p&gt;We’ve now published a guide on the danger of these atomic operations,
and are publishing it to Abseil as a general programming guide. Atomic
operations should be used only in a handful of low-level data
structures which are written by a few experts and then reviewed and
tested thoroughly. Most programmers make mistakes when they attempt
direct use of atomic operations. Even when they don’t, the resulting
code is hard for others to maintain.&lt;/p&gt;

&lt;p&gt;For more information, check out
&lt;a href=&quot;https://abseil.io/docs/cpp/atomic_danger&quot;&gt;The Danger of Atomic Operations&lt;/a&gt;.&lt;/p&gt;

</description>
          <pubDate>2022-01-18T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/01222022-atomic-operations</link>
          <guid isPermaLink="true">https://abseil.io/blog/01222022-atomic-operations</guid>
        </item>
      
    
      
        <item>
          <title>SWE Book Freely Available</title>
          <description>&lt;h3 id=&quot;software-engineering-at-google-book-availability&quot;&gt;Software Engineering at Google Book Availability&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:titus@google.com&quot;&gt;Titus Winters&lt;/a&gt;, &lt;a href=&quot;mailto:shreck@google.com&quot;&gt;Tom
Manshreck&lt;/a&gt;, and &lt;a href=&quot;mailto:hwright@google.com&quot;&gt;Hyrum
Wright&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re very pleased to announce that the “Software Engineering at Google”
book (the Flamingo Book) is now freely available electronically under a
Creative Commons license. You can get a PDF at &lt;a href=&quot;/resources/swe-book&quot;&gt;SWE Book&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From the very beginning of this project, about three years ago, our intent has been to describe how Google thinks about Software Engineering, and to get people thinking about the same kinds of big interesting problems. We think that the best way to do that is to make sure that the content is available for everyone, so we’re providing it now, free of charge. We’re very grateful for our partners at O’Reilly for helping to make this possible (and of course we encourage you to support them and buy a physical copy if you can, etc).&lt;/p&gt;

&lt;p&gt;Some of you may be aiming to land a job at Google in the future: we’ve heard from dozens of Nooglers that this is the handbook they needed to understand the unique and complex machine that is Google. We hope this book is useful for you.&lt;/p&gt;

&lt;p&gt;Some of you may be running your own software companies. You’ll have different scales and problems, but hopefully you can learn from how we think about problems arising from Time and Scale, and how we evaluate the relevant Tradeoffs (these are the main themes threaded through every chapter of the book). You may want to lean on our thinking, or blaze your own trails. We hope the insights we’ve earned the hard way can make your path easier.&lt;/p&gt;

&lt;p&gt;Some of you may know more than us. There are several topics in the book where we are still trying to find a good answer. We’re making our thinking public - why not show us where we’re wrong?&lt;/p&gt;

&lt;p&gt;Over the past year we’ve heard from hundreds of you, all over the world, with stories about how this material has affected your practice and thinking. We’re also seeing this picked up by colleges and universities looking to modernize their discussion of software engineering topics. We’re thrilled at this reception, and very excited that we can take this next step in sharing this material.&lt;/p&gt;

&lt;p&gt;As Nicole Forsgren told us once, “Accountants still have meetings to discuss their practices, and accountancy goes back thousands of years. Software Engineering is barely 50 years old. Give us a minute.” As an industry, and as a discipline, we’re still figuring things out. We hope that this book, in some small way, can help with that.&lt;/p&gt;

&lt;p&gt;-Titus, Tom, and Hyrum&lt;/p&gt;

</description>
          <pubDate>2021-04-22T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/04222021-swe-book</link>
          <guid isPermaLink="true">https://abseil.io/blog/04222021-swe-book</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #188: Be Careful With Smart-Pointer Function Parameters</title>
          <description>&lt;p&gt;Originally posted as TotW #188 on December 10, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:krzysio@google.com&quot;&gt;Krzysztof Kosiński&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-12-10&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/188&quot;&gt;abseil.io/tips/188&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is wrong with this code?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
bool CanYouPetTheDog(const std::shared_ptr&amp;lt;Dog&amp;gt;&amp;amp; dog,
                     absl::Duration min_delay) {
  return dog-&amp;gt;GetLastPetTime() + min_delay &amp;lt; absl::Now();
}
&lt;/pre&gt;

&lt;p&gt;The function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CanYouPetTheDog&lt;/code&gt; does not affect the ownership of its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dog&lt;/code&gt;
argument, yet its signature demands that it should be stored in a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::shared_ptr&lt;/code&gt;. This creates an unnecessary dependency on a specific
ownership model, even though nothing in the function requires it. This
dependency prevents callers from using other models, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;
or constructing objects on the stack.&lt;/p&gt;

&lt;h2 id=&quot;use-references-or-pointers-when-ownership-is-unaffected&quot;&gt;Use References or Pointers When Ownership is Unaffected&lt;/h2&gt;

&lt;p&gt;By using a reference, we can remove the dependency on a specific ownership
model, and allow our function to work with any object of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dog&lt;/code&gt;.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
bool CanYouPetTheDog(const Dog&amp;amp; dog, absl::Duration min_delay) {
  return dog.GetLastPetTime() + min_delay &amp;lt; absl::Now();
}
&lt;/pre&gt;

&lt;p&gt;With the above definition, the function can be called regardless of the caller’s
ownership model:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
Dog stack_dog;
if (CanYouPetTheDog(stack_dog, delay)) { ... }

auto heap_dog = std::make_unique&amp;lt;Dog&amp;gt;();
if (CanYouPetTheDog(*heap_dog, delay)) { ... }

CustomPetPtr&amp;lt;Dog&amp;gt; custom_dog = CreateDog();
if (CanYouPetTheDog(*custom_dog, delay)) { ... }
&lt;/pre&gt;

&lt;p&gt;If the function modifies the passed value, pass a mutable reference or a raw
pointer, and use the same idioms as shown above.&lt;/p&gt;

&lt;h2 id=&quot;use-smart-pointers-when-the-function-modifies-ownership&quot;&gt;Use Smart Pointers When the Function Modifies Ownership&lt;/h2&gt;

&lt;p&gt;The following code provides several overloads for different smart pointer
parameters. The first overload assumes ownership of the passed object and the
second one adds a shared reference to the passed object. Both of these
operations depend on how the caller handles ownership of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dog&lt;/code&gt;. Adopting a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dog&lt;/code&gt; that lives on the stack isn’t possible, as ownership can’t be taken away
from the stack.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Human {
 public:
  ...
  // Transfers ownership of `dog` to this Human.
  // See Tip #117 for the rationale for accepting std::unique_ptr by value.
  void Adopt(std::unique_ptr&amp;lt;Dog&amp;gt; dog) {
    pets_.push_back(std::move(dog));
  }
  // Adds a shared reference to `cat`.
  void Adopt(std::shared_ptr&amp;lt;Cat&amp;gt; cat) {
    pets_.push_back(std::move(cat));
  }

 private:
  std::vector&amp;lt;std::shared_ptr&amp;lt;Pet&amp;gt;&amp;gt; pets_;
  ...
};
&lt;/pre&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;If ownership is not being transferred or modified, avoid having smart pointers
as function parameters.&lt;/p&gt;

&lt;h2 id=&quot;see-also&quot;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/117&quot;&gt;Tip #117&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f7-for-general-use-take-t-or-t-arguments-rather-than-smart-pointers&quot;&gt;C++ Core Guideline F.7&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r30-take-smart-pointers-as-parameters-only-to-explicitly-express-lifetime-semantics&quot;&gt;C++ Core Guideline R.30&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/&quot;&gt;Herb Sutter’s Guru of the Week #91&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2020-12-10T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/188</link>
          <guid isPermaLink="true">https://abseil.io/tips/188</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #187: &lt;code&gt;std::unique_ptr&lt;/code&gt; Must Be Moved</title>
          <description>&lt;p&gt;Originally posted as TotW #187 on November 5, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:asoffer@google.com&quot;&gt;Andy Soffer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-11-05&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/187&quot;&gt;abseil.io/tips/187&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you say in the first chapter that there is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; on the wall,
in the second or third chapter it absolutely must be moved. If it’s not going to
be moved, it shouldn’t be hanging there. ~ With apologies to Anton Chekhov&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; is for expressing transfer of ownership. If you never pass
ownership from one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; to another, the abstraction is rarely
necessary or appropriate.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-stdunique_ptr&quot;&gt;What is a &lt;code&gt;std::unique_ptr&lt;/code&gt;?&lt;/h2&gt;

&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; is a pointer that automatically destroys whatever it is
pointing at when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; itself is destroyed. It exists to convey
ownership (the responsibility to destroy resources) as part of the type system
and is one of C++11’s more valuable additions&lt;sup id=&quot;fnref:unique&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:unique&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. However,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; is commonly overused. A good litmus test is this: &lt;strong&gt;If it is
never &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move&lt;/code&gt;d to or from another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;, it likely should not be
a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;.&lt;/strong&gt; If we do not transfer ownership then there is almost
always a better way to express our intent than by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-costs-of-stdunique_ptr&quot;&gt;The Costs of &lt;code&gt;std::unique_ptr&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;There are several reasons for avoiding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; when ownership is not
being transferred.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; conveys transferrable ownership which is unhelpful if
ownership isn’t being transferred. We should aim to use the type that most
accurately conveys the required semantics.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; can be in a null state, which gives extra cognitive
overhead for readers if the null state is not actually used.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;T&amp;gt;&lt;/code&gt; manages a heap-allocated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;, which comes with
performance implications both due to the heap allocation itself, and the
fact that the data is spread out across the heap and less likely to be in
CPU cache.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;common-anti-pattern-avoiding-&quot;&gt;Common Anti-Pattern: Avoiding &lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;It is not uncommon to see examples like the following.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
int ComputeValue() {
  auto data = std::make_unique&amp;lt;Data&amp;gt;();
  ModifiesData(data.get());
  return data-&amp;gt;GetValue();
}
&lt;/pre&gt;

&lt;p&gt;In this example &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; does not need to be a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;, because
ownership is never transferred. The data will be constructed and destroyed
exactly at the same instances as if a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Data&lt;/code&gt; object were declared on the stack.
Therefore, as is also discussed in &lt;a href=&quot;/tips/123&quot;&gt;Tip #123&lt;/a&gt;, a better option would
be:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
int ComputeValue() {
  Data data;
  ModifiesData(&amp;amp;data);
  return data.GetValue();
}
&lt;/pre&gt;

&lt;h2 id=&quot;common-anti-pattern-delayed-initialization&quot;&gt;Common Anti-Pattern: Delayed Initialization&lt;/h2&gt;

&lt;p&gt;Because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; is null when default constructed, and can be assigned
a new value from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&lt;/code&gt;, it’s common to see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; used
as a delayed initialization mechanism. There is a particularly common pattern
with GoogleTest, in which test fixtures can initialize objects in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetUp&lt;/code&gt;.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
class MyTest : public testing::Test {
 public:
  void SetUp() override {
    thing_ = std::make_unique&amp;lt;Thing&amp;gt;(data_);
  }

 protected:
  Data data_;
  // Initialized in `SetUp()`, so we&apos;re using `std::unique_ptr` as a
  // delayed-initialization mechanism.
  std::unique_ptr&amp;lt;Thing&amp;gt; thing_;
};
&lt;/pre&gt;

&lt;p&gt;Once again, we see that ownership of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thing_&lt;/code&gt; is never transferred elsewhere, so
there is no need to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;. The example above could have done all
of the initialization in the default constructor for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyTest&lt;/code&gt;. See the
&lt;a href=&quot;https://github.com/google/googletest/blob/master/docs/faq.md#CtorVsSetUp&quot;&gt;GoogleTest FAQ&lt;/a&gt;
for details on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetUp&lt;/code&gt; versus construction.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class MyTest : public testing::Test {
 public:
  MyTest() : thing_(data_) {}

 private:
  Data data_;
  Thing thing_;
};
&lt;/pre&gt;

&lt;p&gt;In this example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data_&lt;/code&gt; is default constructed as it was before. Afterwards,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Thing&lt;/code&gt; is constructed with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data_&lt;/code&gt;. Remember that a class’s constructor
initializes fields in the order they are declared, so this approach initializes
objects in the same order as they were before, but without the use of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If delayed initialization is really important and unavoidable, consider using
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; with its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace()&lt;/code&gt; method. &lt;a href=&quot;/tips/123&quot;&gt;Tip #123&lt;/a&gt; discusses
delayed initialization in much greater depth.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class MyTest : public testing::Test {
 public:
  MyTest() {
    Initialize(&amp;amp;data_);
    thing_.emplace(data_);
  }

 private:
  Data data_;
  std::optional&amp;lt;Thing&amp;gt; thing_;
};
&lt;/pre&gt;

&lt;h2 id=&quot;caveats&quot;&gt;Caveats&lt;/h2&gt;

&lt;p&gt;This being C++, there are of course cases where a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; makes sense
even if it is never moved. However these situations are uncommon, and any code
handling such situations should come with comments explaining the subtleties.
Here are two such examples.&lt;/p&gt;

&lt;h3 id=&quot;large-rarely-used-objects&quot;&gt;Large, rarely used objects.&lt;/h3&gt;

&lt;p&gt;If an object is only sometimes needed, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; is a good default choice.
However, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; reserves space regardless of whether the object is
actually constructed. If this space is important, it may make sense to hold a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; and only allocate it if it is needed.&lt;/p&gt;

&lt;h3 id=&quot;legacy-apis&quot;&gt;Legacy APIs&lt;/h3&gt;

&lt;p&gt;Many legacy APIs return raw pointers to owned data. These APIs often predate the
addition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; to the C++ standard library, and this pattern
should not be copied in new code. However, even if the resulting object is never
moved, such legacy API calls should be wrapped in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; to ensure
that the memory is not leaked.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
Widget *CreateLegacyWidget() { return new Widget; }

int func() {
  Widget *w = CreateLegacyWidget();
  return w-&amp;gt;num_gadgets();
}  // Memory leak!
&lt;/pre&gt;

&lt;p&gt;Wrapping the object in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; solves both of these issues:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
int func() {
  std::unique_ptr&amp;lt;Widget&amp;gt; w = absl::WrapUnique(CreateLegacyWidget());
  return w-&amp;gt;num_gadgets();
}  // `w` is properly destroyed.
&lt;/pre&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:unique&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;The word “unique” in the name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; was chosen to signify
the idea that no other &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; should be holding the same
non-null value. That is, at any moment during program execution,
amongst all the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;s that are not null, the addresses
held by all the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;s are unique. &lt;a href=&quot;#fnref:unique&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
          <pubDate>2020-11-11T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/187</link>
          <guid isPermaLink="true">https://abseil.io/tips/187</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #186: Prefer to Put Functions in the Unnamed Namespace</title>
          <description>&lt;p&gt;Originally posted as TotW #186 on November 5, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;James Dennett&lt;/a&gt; and &lt;a href=&quot;mailto:jrennie@google.com&quot;&gt;Jason Rennie&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-11-05&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/186&quot;&gt;abseil.io/tips/186&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Everything should be made as simple as possible, but no simpler.” ~ Roger
Sessions’s interpretation of Einstein&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When adding a new function, default to making it a non-member function local to
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file where it is called. While there are valid reasons to make another
choice, consider writing it in an unnamed namespace (also known as an “anonymous
namespace”).&lt;/p&gt;

&lt;h2 id=&quot;benefits&quot;&gt;Benefits&lt;/h2&gt;

&lt;p&gt;Writing a non-member in an unnamed namespace has benefits both by making
functions internal to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file (moving them out of header files) as well as
by making them non-members (moving them out of classes).&lt;/p&gt;

&lt;p&gt;Benefits over functions declared in a header file include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Making it easy for a reader to look up the definition (since it’s in the
same file as usage and above the first usage).&lt;/li&gt;
  &lt;li&gt;Placing the documentation, declaration, and definition in a single location
(versus two locations for functions which are declared in a header file).&lt;/li&gt;
  &lt;li&gt;Isolating it from other source files, making it easier to refactor.&lt;/li&gt;
  &lt;li&gt;Removing the need to worry about &lt;a href=&quot;/tips/109&quot;&gt;meaningful const&lt;/a&gt; as there is
no separate declaration.&lt;/li&gt;
  &lt;li&gt;Keeping them in the same place as other implementation helpers for a
library, such as convenience aliases and local types. See
&lt;a href=&quot;[Tip #119]\(/tips/119\)&quot;&gt;Tip of the Week #119: Using-declarations and Namespace Aliases&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Providing side benefits, such as allowing a type to also be moved to an
unnamed namespace (if it is only referenced in a single source file).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits over private methods include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Inputs and outputs are clear since they are (much more likely to be)
specified via arguments or the return value. Note that a method may read any
member variable and a non-const method may modify any non-const member.
Conversely, a non-member function may only read or modify according to its
interface (except for globals).&lt;/li&gt;
  &lt;li&gt;The class API is simpler and shorter, and hence easier to read—unnecessary
private methods may make it difficult to find inheritance-related private
declarations or declarations after the class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of these benefits remain even if there is no relevant header file, such as
for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*_test.cc&lt;/code&gt; or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*_main.cc&lt;/code&gt; file.&lt;/p&gt;

&lt;h2 id=&quot;reasons-to-look-elsewhere&quot;&gt;Reasons to Look Elsewhere&lt;/h2&gt;

&lt;p&gt;Sometimes a non-member local function does not make sense. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;When the function is useful in multiple source files. Declaring it in a
header file allows re-use.&lt;/li&gt;
  &lt;li&gt;When the function has complex interactions with an object or class. For
example, a function that reads from multiple fields and needs to modify
state in a way that can’t be handled naturally via a return value is likely
better written as a method. In particular, logic involving a mutex usually
belongs in a member function.&lt;/li&gt;
  &lt;li&gt;When the function belongs as part of a class’s API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;an-alternative-static-non-member-functions&quot;&gt;An Alternative: &lt;code&gt;static&lt;/code&gt; Non-Member Functions&lt;/h2&gt;

&lt;p&gt;Marking a non-member function as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt; has essentially the same effect as
placing it inside an unnamed namespace in terms of isolating it from code in
other translation units. While unnamed namespaces do this in a uniform manner
that covers types as well as functions and objects, some people like to see
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt; written explicitly in the declaration of a function to show that it is
local to a translation unit without having to check for an enclosing unnamed
namespace. While this tip recommends using an unnamed namespace, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt;
can be a reasonable choice.&lt;/p&gt;

&lt;h2 id=&quot;other-references&quot;&gt;Other References&lt;/h2&gt;

&lt;p&gt;Parts of &lt;a href=&quot;https://google.github.io/styleguide/cppguide.html&quot;&gt;the style guide&lt;/a&gt;
point us in this direction, but they don’t go as far. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Unnamed_Namespaces_and_Static_Variables&quot;&gt;The unnamed namespaces section&lt;/a&gt;
encourages that definitions go in an unnamed namespace (or be declared
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt;), but doesn’t talk about private methods.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs&quot;&gt;The inputs and outputs section&lt;/a&gt;
encourages using return values, but doesn’t address modification of members
(via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this&lt;/code&gt;); &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this&lt;/code&gt; is essentially an uber-input/output parameter.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Local_Variables&quot;&gt;The local variables section&lt;/a&gt;
encourages minimizing variable scope, but doesn’t extend the idea to classes
and objects.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Nonmember,_Static_Member,_and_Global_Functions&quot;&gt;The Nonmember, Static Member, and Global Functions section&lt;/a&gt;
discourages using a class merely to group functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;File-local functions simplify dependencies and improve locality. Non-member
functions increase encapsulation, simplify class definitions, and make
dependencies more explicit. When writing a function, consider making it a
file-local non-member function, such as by putting it in an unnamed namespace of
a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file.&lt;/p&gt;
</description>
          <pubDate>2020-11-11T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/186</link>
          <guid isPermaLink="true">https://abseil.io/tips/186</guid>
        </item>
      
    
      
        <item>
          <title>Abseil Platform Support Update</title>
          <description>&lt;h3 id=&quot;abseil-platform-support-update&quot;&gt;Abseil Platform Support Update&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:dmauro@google.com&quot;&gt;Derek Mauro&lt;/a&gt;, Abseil Engineer&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://abseil.io/about/compatibility&quot;&gt;In September 2017, Abseil made the following support
promise&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;i&gt;We will support our code for at least 5 years. We will support language
versions, compilers, platforms, and workarounds as needed for 5 years after
their replacement is available, when possible. If it is technically infeasible
(such as support for MSVC before 2015, which has limited C++11 functionality),
those will be noted specifically. After 5 years we will stop support and may
remove workarounds. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ABSL_HAVE_THREAD_LOCAL&lt;/code&gt; is a good example: the base
language feature works on everything except Xcode prior to Xcode 8 ; once
Xcode 8 is out for 5 years, we will drop that workaround support.
&lt;/i&gt;&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;The ability to evolve over time has long been a goal of the Abseil project, and
supporting older platforms comes with the cost of not being able to take
advantage of new features, and not being able to get the best performance
possible. With this is mind, the &lt;a href=&quot;https://github.com/abseil/abseil-cpp/tree/lts_2020_09_23&quot;&gt;September 2020 LTS release
branch&lt;/a&gt; will be the
last to support the following compilers:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;GCC 4.9&lt;/li&gt;
  &lt;li&gt;Clang 3.6&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will soon remove our continuous integration tests for these compilers.&lt;/p&gt;

&lt;h3 id=&quot;preparing-for-the-future&quot;&gt;Preparing for the Future&lt;/h3&gt;

&lt;p&gt;Of our supported platforms and compilers, the last to facilitate support for
C++14 was Microsoft Visual C++ 2017, which was released on March
7, 2017. Therefore, Abseil will only support C++11 (and Microsoft Visual C++
2015) until March 7, 2022. We will do one final Long Term Support release in
March of 2022, at which point we will announce that it is the final LTS release
to support C++11. We strongly recommend all users begin moving to C++14 or newer
as soon as possible and not wait for this LTS release, however.&lt;/p&gt;

&lt;p&gt;In addition, the following support changes will occur in the near future:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Clang 3.8, which replaced Clang 3.7, was released March 8, 2016. Therefore, we
intend to drop support for Clang 3.7 after March 8, 2021.&lt;/li&gt;
  &lt;li&gt;GCC 6.1, which replaced the GCC 5 series, was released on April
27, 2016. Therefore, we intend to drop support for the GCC 5 series after April
27, 2021.&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2020-10-01T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20201001-platforms</link>
          <guid isPermaLink="true">https://abseil.io/blog/20201001-platforms</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #76: Use &lt;code&gt;absl::Status&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #76 on May 4, 2014&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:titus@cs.ucr.edu&quot;&gt;Titus Winters&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-02-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/76&quot;&gt;abseil.io/tips/76&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some folks have questions about when and how to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt;, so here are
a few reasons why you ought to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt;, and some things to keep in mind
when using it.&lt;/p&gt;

&lt;h2 id=&quot;communicate-intent-and-force-the-caller-to-handle-errors&quot;&gt;Communicate Intent and Force the Caller to Handle Errors&lt;/h2&gt;

&lt;p&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; to force the caller to handle the possibility of errors. Since June
2013, a function returning an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; object cannot simply be ignored. That is,
this code produces a compilation error:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
absl::Status Foo();

void CallFoo1() {
  Foo();
}
&lt;/pre&gt;

&lt;p&gt;Whereas these calls are fine:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void CallFoo2() {
  Foo().IgnoreError();
}

void CallFoo3() {
  if (!status.ok()) std::abort();
}

void CallFoo4() {
  absl::Status status = Foo();
  if (!status.ok()) LOG(ERROR) &amp;lt;&amp;lt; status;
}
&lt;/pre&gt;

&lt;p&gt;Why is it OK for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; to have an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IgnoreError()&lt;/code&gt; method, while we just went
through all this effort to make the compiler check that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; isn’t ignored?
Imagine you’re the code reviewer looking at either &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CallFoo1()&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CallFoo2()&lt;/code&gt;.
The latter code snippets make the reviewer think “This function could have had
an error, but the author thinks its OK to ignore it. Is it?” &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CallFoo1()&lt;/code&gt; does
not trigger such a response.&lt;/p&gt;

&lt;h2 id=&quot;allow-the-caller-to-handle-errors-where-they-have-more-context&quot;&gt;Allow the Caller to Handle Errors Where They Have More Context&lt;/h2&gt;

&lt;p&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; when it’s not clear in your code how to handle the error. Instead,
return a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt;, and let the caller, who may have more appropriate insight,
handle the error.&lt;/p&gt;

&lt;p&gt;For example, logging locally might impact performance, such as when writing
infrastructure code. If your code is called in a tight loop, even a call to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LOG(INFO)&lt;/code&gt; may be too expensive. In other cases, users may not really care if a
call succeeds, and find the log spam intrusive.&lt;/p&gt;

&lt;p&gt;Logging is appropriate in many cases, but functions that return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; don’t
need to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LOG&lt;/code&gt; to explain why something failed: they can return the failure code
and error string and let the caller decide what the right error handling
response should be.&lt;/p&gt;

&lt;h2 id=&quot;isnt-this-just-re-inventing-exceptions&quot;&gt;Isn’t This Just Re-Inventing Exceptions?&lt;/h2&gt;

&lt;p&gt;The Google style guide famously prohibits exceptions (it’s discussed more than
any other prohibition). It can be tempting to view &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt; as a poor-
man’s exception mechanism, with a lot more overhead. While there may be
similarities on the surface, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt; differs in its need to be explicitly
handled, rather than just passed up the stack invisibly as an unhandled
exception. It forces engineers to decide how to handle errors, and explicitly
documents that in compilable code. And finally, returning an error using a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt; is orders of magnitude faster than throwing and catching an
exception. These features may seem onerous when writing code, but the result is
a net win for everyone that has to read that code, and for Google as a whole.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Error handling is one of the easiest things to get wrong: these are inherently
the edge cases. A utility like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; that adds consistency to error handling
across API boundaries, projects, processes, and languages helps us minimize a
large class of “There were issues with our error handling” bugs. If you’re
designing an interface that needs to express the possibility of failure, please
use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; if you don’t have a pretty strong reason to do otherwise.&lt;/p&gt;
</description>
          <pubDate>2020-09-11T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/76</link>
          <guid isPermaLink="true">https://abseil.io/tips/76</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #5: Disappearing Act</title>
          <description>&lt;p&gt;Originally posted as TotW #5 on June 26, 2012&lt;/p&gt;

&lt;p&gt;Updated 2020-06-01&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/5&quot;&gt;abseil.io/tips/5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Don’t know what you got till it’s gone.” –Cinderella&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, in order to use a C++ library the right way, you need to understand
both the library and the language. So … what’s wrong with the following?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// DON’T DO THIS
std::string s1, s2;
...
const char* p1 = (s1 + s2).c_str();             // Avoid!
const char* p2 = absl::StrCat(s1, s2).c_str();  // Avoid!
&lt;/pre&gt;

&lt;p&gt;Both (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s1+s2&lt;/code&gt;) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat(s1,s2)&lt;/code&gt; create temporary objects (in both
cases, strings, but the same rules apply for any objects). The member function
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c_str()&lt;/code&gt; returns a pointer to data that lives as long as the temporary object.
How long does the temporary object live? According to the C++17 standard
[class.temporary], “Temporary objects are destroyed as the last step in
evaluating the full-expression that (lexically) contains the point where they
were created.” (A “full-expression” is “an expression that is not a
subexpression of another expression”). In each example above, as soon as the
expression on the right side of the assignment operator was completed, the
temporary value was destroyed, and the return value from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c_str()&lt;/code&gt; became a
dangling pointer. tl;dr? By the time you hit a semicolon (often sooner), the
temporary object is history. Yikes! How can you avoid this kind of problem?&lt;/p&gt;

&lt;h2 id=&quot;option-1-finish-using-the-temporary-object-before-the-end-of-the-full-expression&quot;&gt;Option 1: Finish Using the Temporary Object Before the End of the full-expression:&lt;/h2&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Safe (albeit a silly example):
size_t len1 = strlen((s1 + s2).c_str());
size_t len2 = strlen(absl::StrCat(s1, s2).c_str());
&lt;/pre&gt;

&lt;h2 id=&quot;option-2-store-the-temporary-object&quot;&gt;Option 2: Store the Temporary Object.&lt;/h2&gt;

&lt;p&gt;You’re creating an object (on the stack) anyway; why not hang on to it for a
while? This is cheaper than it might first appear. Because of something called
“return value optimization,” (and move semantics on many value types, see
&lt;a href=&quot;/tips/77&quot;&gt;Tip #77&lt;/a&gt;) the temporary object will be constructed in the variable
you’re “assigning” it to, and won’t be copied:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Safe (and more efficient than you might think):
std::string tmp_1 = s1 + s2;
std::string tmp_2 = absl::StrCat(s1, s2);
// tmp_1.c_str() and tmp_2.c_str() are safe.
&lt;/pre&gt;

&lt;h2 id=&quot;option-3-store-a-reference-to-the-temporary-object&quot;&gt;Option 3: Store a Reference to the Temporary Object.&lt;/h2&gt;

&lt;p&gt;C++17 standard [class.temporary]: “The temporary to which the reference is bound
or the temporary that is the complete object of a sub-object to which the
reference is bound persists for the lifetime of the reference.”&lt;/p&gt;

&lt;p&gt;Because of return value optimization, this usually isn’t any cheaper than
storing the object itself (Option 2), and it is potentially confusing or
worrisome (see &lt;a href=&quot;/tips/101&quot;&gt;Tip #101&lt;/a&gt;). (Exceptional cases that need to use
lifetime extension should be commented!)&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Equally safe:
const std::string&amp;amp; tmp_1 = s1 + s2;
const std::string&amp;amp; tmp_2 = absl::StrCat(s1, s2);
// tmp_1.c_str() and tmp_2.c_str() are safe.
// The following behavior is dangerously subtle:
// If the compiler can see you’re storing a reference to a
// temporary object’s internals, it will keep the whole
// temporary object alive.
// struct Person { string name; ... }
// GeneratePerson() returns an object; GeneratePerson().name
// is clearly a sub-object:
const std::string&amp;amp; person_name = GeneratePerson().name; // safe
// If the compiler can’t tell, you’re at risk.
// class DiceSeries_DiceRoll { `const string&amp;amp;` nickname() ... }
// GenerateDiceRoll() returns an object; the compiler can’t tell
// if GenerateDiceRoll().nickname() is a subobject.
// The following may store a dangling reference:
const std::string&amp;amp; nickname = GenerateDiceRoll().nickname(); // BAD!
&lt;/pre&gt;

&lt;h2 id=&quot;option-4-design-your-functions-so-they-dont-return-objects&quot;&gt;Option 4: Design your functions so they don’t return objects???&lt;/h2&gt;

&lt;p&gt;Many functions follow this principle; but many don’t. Sometimes it really is
better to return an object than to require the caller to pass in a pointer to an
output parameter. Be aware of when the creation of temporaries can happen.
Anything that returns a pointer or reference to an object’s internals is
potentially a problem when operating on a temporary object. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c_str()&lt;/code&gt; is the
most obvious culprit, but protobuf getters (mutable or otherwise) and getters in
general can be equally problematic.&lt;/p&gt;
</description>
          <pubDate>2020-09-11T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/5</link>
          <guid isPermaLink="true">https://abseil.io/tips/5</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #181: Accessing the value of a StatusOr&amp;lt;T&amp;gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #181 on July 9, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:msheely@google.com&quot;&gt;Michael Sheely&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-09-02&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/181&quot;&gt;abseil.io/tips/181&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&amp;lt;Readability&amp;gt;&lt;/code&gt;: you don’t have to choose!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When the time comes to access the value inside an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;&lt;/code&gt; object, we
should strive to make that access &lt;em&gt;safe&lt;/em&gt;, &lt;em&gt;clear&lt;/em&gt;, and &lt;em&gt;efficient&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Note: This tip attempts to highlight
&lt;a href=&quot;https://moma.corp.google.com/glossary/term/11ngkm2f_v&quot;&gt;well lit paths&lt;/a&gt;
providing guidance for typical use-cases. It is not intended to be exhaustive.
If you encounter edge cases, consider the recommendations and reasoning here and
exercise judgement.&lt;/p&gt;

&lt;h2 id=&quot;recommendation&quot;&gt;Recommendation&lt;/h2&gt;

&lt;p&gt;Accessing the value held by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt; should be performed via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator*&lt;/code&gt; or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator-&amp;gt;&lt;/code&gt;, after a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ok()&lt;/code&gt; has verified that the value is present.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// The same pattern used when handling a unique_ptr...
std::unique_ptr&amp;lt;Foo&amp;gt; foo = TryAllocateFoo();
if (foo != nullptr) {
  foo-&amp;gt;DoBar();  // use the value object
}

// ...or an optional value...
std::optional&amp;lt;Foo&amp;gt; foo = MaybeFindFoo();
if (foo.has_value()) {
  foo-&amp;gt;DoBar();
}

// ...is also ideal for handling a StatusOr.
absl::StatusOr&amp;lt;Foo&amp;gt; foo = TryCreateFoo();
if (foo.ok()) {
  foo-&amp;gt;DoBar();
}
&lt;/pre&gt;

&lt;p&gt;You can limit the scope of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt; by declaring it in the initializer of
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; statement and checking &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ok()&lt;/code&gt; in the condition. If using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt;
immediately, you generally &lt;em&gt;should&lt;/em&gt; limit scope in this way (see
&lt;a href=&quot;/tips/165&quot;&gt;Tip #165&lt;/a&gt;):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
if (absl::StatusOr&amp;lt;Foo&amp;gt; foo = TryCreateFoo(); foo.ok()) {
  foo-&amp;gt;DoBar();
}
&lt;/pre&gt;

&lt;h2 id=&quot;background-on-statusor&quot;&gt;Background on &lt;code&gt;StatusOr&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;&lt;/code&gt; class is a
&lt;a href=&quot;https://en.wikipedia.org/wiki/Tagged_union&quot;&gt;tagged union&lt;/a&gt; with
&lt;a href=&quot;https://isocpp.org/wiki/faq/value-vs-ref-semantics&quot;&gt;value semantics&lt;/a&gt; indicating
exactly one of the following situations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;an object of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is available,&lt;/li&gt;
  &lt;li&gt;an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt; error (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!ok()&lt;/code&gt;) indicating why the value is not present.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read more about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&lt;/code&gt; in
&lt;a href=&quot;/tips/76&quot;&gt;Tip #76&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;safety-clarity-and-efficiency&quot;&gt;Safety, Clarity, and Efficiency&lt;/h2&gt;

&lt;p&gt;Treating the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt; object as one would treat a smart pointer helps code
achieve clarity while remaining safe and efficient. Below, we will consider some
of the other ways you might have seen a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt; accessed, and why we prefer
the approach using the indirection operators.&lt;/p&gt;

&lt;h3 id=&quot;alternative-value-accessor-safety-issues&quot;&gt;Alternative Value Accessor Safety Issues&lt;/h3&gt;

&lt;p&gt;What about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;::value()&lt;/code&gt;?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
absl::StatusOr&amp;lt;Foo&amp;gt; foo = TryCreateFoo();
foo.value().DoBar();  // Behavior depends on the build mode.
&lt;/pre&gt;

&lt;p&gt;Here, the behavior depends on the build mode – in particular, whether the code
was compiled with exceptions enabled.&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; As such, it is not clear to readers if
an error status will terminate the program.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value()&lt;/code&gt; method combines two actions: a test for validity followed by an
access of the value. It should therefore be used &lt;em&gt;only if&lt;/em&gt; both actions are
intended (and even then, think twice and consider that its behavior depends on
the build mode). If the status is already known to be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OK&lt;/code&gt;, then your ideal
accessor has semantics of simply accessing the value, which is exactly what
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator*&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator-&amp;gt;&lt;/code&gt; provide. In addition to making the code more
precisely indicate your intent, the access will be at least as efficient as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value()&lt;/code&gt;’s contract to test for validity and then access the value.&lt;/p&gt;

&lt;h3 id=&quot;avoiding-multiple-names-for-the-same-object&quot;&gt;Avoiding Multiple Names for the Same Object&lt;/h3&gt;

&lt;p&gt;Treating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&lt;/code&gt; objects as we would a smart pointer or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&lt;/code&gt;
value also allows us to avoid the conceptually awkward situation of having two
variables referring to the same value. It also avoids the naming dilemmas and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; overuse which come with this territory.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// Without digging up the declaration of TryCreateFoo(), a reader will not
// immediately understand the types here (optional? pointer? StatusOr?).
auto maybe_foo = TryCreateFoo();
// ...compounded by the use of implicit bool rather than `.ok()`.
if (!maybe_foo) { /* handle foo not present */ }
// Now two variables (maybe_foo, foo) represent the same value.
Foo&amp;amp; foo = maybe_foo.value();
&lt;/pre&gt;

&lt;h3 id=&quot;avoiding-the-_or-suffix&quot;&gt;Avoiding the &lt;code&gt;_or&lt;/code&gt; Suffix&lt;/h3&gt;

&lt;p&gt;Another benefit of using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt; variable’s intrinsic value type after
checking for validity (rather than creating multiple variables for the same
value) is that we can use the best name for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt; without the need (or
temptation!) to add a prefix or suffix.&lt;/p&gt;

&lt;p&gt;There is an analogy here to the
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Windows_Code&quot;&gt;avoidance of the “&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_ptr&lt;/code&gt;”&lt;/a&gt;
suffix when naming pointer variables.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// The type already describes that this is a unique_ptr; `foo` would be fine.
std::unique_ptr&amp;lt;Foo&amp;gt; foo_ptr;

absl::StatusOr&amp;lt;Foo&amp;gt; foo_or = MaybeFoo();
if (foo_or.ok()) {
  const Foo&amp;amp; foo = foo_or.value();
  foo.DoBar();
}
&lt;/pre&gt;

&lt;p&gt;If there is only one variable (the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt;, avoiding a second named variable
for the unwrapped value), we can drop the suffix, simply naming the variable
after its underlying value (just as we do with pointers).&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
const absl::StatusOr&amp;lt;Foo&amp;gt; foo = MaybeFoo();
if (foo.ok()) {
  MakeUseOf(*foo);
  foo-&amp;gt;DoBar();
}
&lt;/pre&gt;

&lt;h3 id=&quot;moving-from-the-value-of-an-abslstatusor&quot;&gt;Moving from the Value of an &lt;code&gt;absl::StatusOr&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;We might write code to move from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; of an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
absl::StatusOr&amp;lt;Foo&amp;gt; foo = MaybeFoo();
if (foo.ok()) {
  ConsumeFoo(std::move(*foo));
}
&lt;/pre&gt;

&lt;p&gt;It’s a little better, though, to move from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt; itself, indicating to
readers (both humans and machines) that the entire &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt; object should not
be used after its value has been moved from:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
absl::StatusOr&amp;lt;Foo&amp;gt; foo = MaybeFoo();
if (foo.ok()) {
  ConsumeFoo(*std::move(foo));
}
&lt;/pre&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;p&gt;Testing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&lt;/code&gt; object for validity (as you would a smart pointer
or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&lt;/code&gt;) and accessing it using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator*&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator-&amp;gt;&lt;/code&gt; is readable,
efficient, and safe.&lt;/p&gt;

&lt;p&gt;It helps you avoid the potential pitfalls of naming ambiguity mentioned above,
and does it all without the use of any macros.&lt;/p&gt;

&lt;p&gt;Code that accesses values via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator*&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator-&amp;gt;&lt;/code&gt; (whether using a
pointer, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatusOr&lt;/code&gt;, an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&lt;/code&gt;, or otherwise) must first verify that the
value is present. This validation should be close to where the value is accessed
so that readers can easily verify that it is present and correct.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Per the
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/status/statusor.h&quot;&gt;documentation&lt;/a&gt;
of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value()&lt;/code&gt; function, if exceptions are enabled, this will throw
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::BadStatusOrAccess&lt;/code&gt; (which may be caught, meaning the program may
not terminate). If compiled without exceptions, code will crash with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LOG(FATAL)&lt;/code&gt;. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
          <pubDate>2020-09-11T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/181</link>
          <guid isPermaLink="true">https://abseil.io/tips/181</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #165: &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;switch&lt;/code&gt; statements with initializers</title>
          <description>&lt;p&gt;Originally posted as TotW #165 on August 17, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:tkoeppe@google.com&quot;&gt;Thomas Köppe&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-01-17&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/165&quot;&gt;abseil.io/tips/165&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unless you use conditional control flow, you can stop reading now.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;a-new-syntax&quot;&gt;A new syntax&lt;/h2&gt;

&lt;p&gt;C++17
&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r1.html&quot;&gt;allows&lt;/a&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statements to include an initializer:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
if (init; cond) { /* ... */ }
switch (init; cond) { /* ... */ }
&lt;/pre&gt;

&lt;p&gt;This syntax lets you keep the scope of variables as tight as possible:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
if (auto it = m.find(&quot;key&quot;); it != m.end()) {
  return it-&amp;gt;second;
} else {
  return absl::NotFoundError(&quot;Entry not found&quot;);
}
&lt;/pre&gt;

&lt;p&gt;The semantics of the initializer are exactly as in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; statement; details
below.&lt;/p&gt;

&lt;h2 id=&quot;when-this-is-useful&quot;&gt;When this is useful&lt;/h2&gt;

&lt;p&gt;One of the most important ways to manage complexity is to break complex systems
down into non-interacting, local parts that can be understood in isolation and
ignored in their entirety. In C++, the presence of variables increases
complexity, and &lt;em&gt;scopes&lt;/em&gt; allow us to limit the extent of this complexity: the
less a variable is in scope, the less often a reader needs to remember that the
variable exists.&lt;/p&gt;

&lt;p&gt;When demanding reader attention, it is thus valuable to limit the scopes of
variables to where they are actually needed. The new syntax offers one new tool
for this. Contrast then this new syntax with the alternative code one would have
written prior to C++17: Either we keep the scopes tight, and thus need to write
additional braces:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
{
  auto it = m.find(&quot;key&quot;);
  if (it != m.end()) {
    return it-&amp;gt;second;
  } else {
    return absl::NotFoundError(&quot;Entry not found&quot;);
  }
}
&lt;/pre&gt;

&lt;p&gt;Or, as seems to be the more typical solution, we do &lt;em&gt;not&lt;/em&gt; keep the scopes tight
and just “leak” the variables:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
auto it = m.find(&quot;key&quot;);
if (it != m.end()) {
  return it-&amp;gt;second;
} else {
  return absl::NotFoundError(&quot;Entry not found&quot;);
}
&lt;/pre&gt;

&lt;p&gt;By contrast, the new style is self-contained: It is not possible to move the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; statement without also moving the variable and its scope. The local meaning
of the variable remains unchanged as code is moved around or copy-pasted. With
the previous styles, code movement could accidentally change the scope of the
variable (if the outer braces are not copied), or its meaning (if the variable
itself is not copied and a variable with that name is in scope), or introduce a
name clash.&lt;/p&gt;

&lt;p&gt;The complexity considerations lead to the common adage that variable name length
should match the variable scope’s size; that is, variables that are in
scope for longer should have longer names (since they need to make sense to a
reader that has long moved on). Conversely, smaller scopes permit shorter names.
When variable names are leaked (as above), we see regrettable patterns emerge
such as: multiple variables &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;it1&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;it2&lt;/code&gt;, … become necessary to avoid clashes;
variables are reassigned (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto it = m1.find(/* ... */); it = m2.find(/* ...
*/)&lt;/code&gt;; or variables get intrusively long names (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto database_index_iter =
m.find(/* ... */)&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;details-scopes-declarative-regions&quot;&gt;Details, scopes, declarative regions&lt;/h2&gt;

&lt;p&gt;The new, optional initializer in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statements works exactly like
the initializer in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; statement. (The latter is essentially a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;while&lt;/code&gt;
statement with initializer.) That is, the syntax-with-initializer is mostly just
syntactic sugar around the following rewrites:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Sugared form&lt;/th&gt;
      &lt;th&gt;Rewritten as&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (init; cond) BODY&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{ init; if (cond) BODY }&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch (init; cond) BODY&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{ init; switch (cond) BODY }&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for (init; cond; incr) BODY&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{ init; while (cond) { BODY; incr; } }&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Importantly, the names declared in the initializer are in scope of a potential
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt; arm of an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;There is one difference, though: In the sugared form, the initializer is in the
same scope as the condition and body (of both the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt; arm),
rather than in a separate, larger scope. This means that variable names must be
unique across all these parts, though they may shadow earlier declarations. The
following examples illustrate the various disallowed redeclarations and allowed
shadowing declarations:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
int w;

if (int x, y, z; int y = g()) {   // error: y redeclared, first declared in initializer
  int x;                          // error: x redeclared, first declared in initializer
  int w;                          // OK, shadows outer variable
  {
    int x, y;                     // OK, shadowing in nested scope is allowed
  }
} else {
  int z;                          // error: z redeclared, first declared in initializer
}

if (int w; int q = g()) {         // declaration of &quot;w&quot; OK, shadows outer variable
  int q;                          // error: q redeclared, first declared in condition
  int w;                          // error: w redeclared, first declared in initializer
}
&lt;/pre&gt;

&lt;h2 id=&quot;interaction-with-structured-bindings&quot;&gt;Interaction with structured bindings&lt;/h2&gt;

&lt;p&gt;C++17 also introduces &lt;em&gt;structured bindings&lt;/em&gt;, a mechanism to assign names to the
elements of a “destructurable” value (such as a tuple, an array, or
a simple struct): &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto [iter, ins] = m.insert(/* ... */);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That feature plays nicely with the new initializer in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; statement:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
if (auto [iter, ins] = m.try_emplace(key, data); ins) {
  use(iter-&amp;gt;second);
} else {
  LOG(ERROR) &amp;lt;&amp;lt; &quot;Key &apos;&quot; &amp;lt;&amp;lt; key &amp;lt;&amp;lt; &quot;&apos; already exists.&quot;;
}
&lt;/pre&gt;

&lt;p&gt;Another example comes from using C++17’s new &lt;em&gt;node handles&lt;/em&gt; that allow
true moving of elements between maps or sets without copying. This feature
defines an &lt;em&gt;insert-return-type&lt;/em&gt; that is destructurable and that results from
inserting a node handle:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
if (auto [iter, ins, node] = m2.insert(m1.extract(k)); ins) {
  LOG(INFO) &amp;lt;&amp;lt; &quot;Element with key &apos;&quot; &amp;lt;&amp;lt; k &amp;lt;&amp;lt; &quot;&apos; transferred successfully&quot;;
} else if (!node) {
  LOG(ERROR) &amp;lt;&amp;lt; &quot;Key &apos;&quot; &amp;lt;&amp;lt; k &amp;lt;&amp;lt; &quot;&apos; does not exist in first map.&quot;;
} else {
  LOG(ERROR) &amp;lt;&amp;lt; &quot;Key &apos;&quot; &amp;lt;&amp;lt; k &amp;lt;&amp;lt; &quot;&apos; already in m2; m2 unchanged; m1 changed.&quot;;
}
&lt;/pre&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Use the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (init; cond)&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch (init; cond)&lt;/code&gt; syntax when you need a
new variable for use within the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement that is not needed
outside of it. This simplifies the ambient code. Moreover, since the
variable’s scope is now small, its name can be shorter, too.&lt;/p&gt;
</description>
          <pubDate>2020-09-11T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/165</link>
          <guid isPermaLink="true">https://abseil.io/tips/165</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #116: Keeping References on Arguments</title>
          <description>&lt;p&gt;Originally posted as TotW #116 on May 26, 2016&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:pilki@google.com&quot;&gt;Alex Pilkiewicz&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-06-01&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/116&quot;&gt;abseil.io/tips/116&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;From painting to image, from image to text, from text to voice, a sort of
imaginary pointer indicates, shows, fixes, locates, imposes a system of
references, tries to stabilize a unique space. — This is Not a Pipe by Michel
Foucault&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;const-references-vs-pointers-to-const&quot;&gt;Const References vs. Pointers to Const&lt;/h2&gt;

&lt;p&gt;Used as arguments of functions, const references have several advantages when
compared to pointers to const: they cannot be null and it’s quite clear that the
function is not taking ownership of the object. But they have other differences
that can sometimes be problematic: they are more implicit (i.e. there is nothing
on the call site showing we are taking a reference) and they can be bound to a
temporary.&lt;/p&gt;

&lt;h2 id=&quot;risk-of-a-dangling-reference-in-classes&quot;&gt;Risk of a Dangling Reference in Classes&lt;/h2&gt;

&lt;p&gt;Consider the following class as an example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Foo {
 public:
  explicit Foo(const std::string&amp;amp; content) : content_(content) {}
  const std::string&amp;amp; content() const { return content_; }

 private:
  const std::string&amp;amp; content_;
};
&lt;/pre&gt;

&lt;p&gt;It looks reasonable. But what happens if we build a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; from a string literal?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void Func() {
  Foo foo(&quot;something&quot;);
  LOG(INFO) &amp;lt;&amp;lt; foo.content();  // BOOM!
}
&lt;/pre&gt;

&lt;p&gt;When creating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;content_&lt;/code&gt; member gets bound to the temporary
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; object that was created from the literal and passed to the
constructor. The temporary string goes out of scope at the end of the line where
it was created. Now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo.content_&lt;/code&gt; is a reference to an object that no longer
exists. Accessing it is undefined behavior and anything can happen, from working
fine in tests to going really wrong in production.&lt;/p&gt;

&lt;h2 id=&quot;a-solution-use-pointers&quot;&gt;A Solution: Use Pointers&lt;/h2&gt;

&lt;p&gt;In our example, the simplest solution is probably to pass and store the string
by value. But let’s assume that we need to refer to the original argument, e.g.
because it’s not a string, but some more interesting type. The solution is to
pass the argument by pointer:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Foo {
 public:
  // Do not forget this comment:
  // Does not take ownership of content, which must refer to a valid string that
  // outlives this object.
  explicit Foo(const std::string* content) : content_(content) {}
  const std::string&amp;amp; content() const { return *content_; }

 private:
  const std::string* const content_;  // not owned, can&apos;t be null
};
&lt;/pre&gt;

&lt;p&gt;Now the following will simply fail to compile:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string GetString();
void Func() {
  Foo foo1(&amp;amp;GetString());  // error: taking the address of a temporary of
                           // type &apos;std::string&apos;
  Foo foo2(&amp;amp;&quot;something&quot;);  // error: no matching constructor for initialization
                           // of &apos;Foo&apos;
}
&lt;/pre&gt;

&lt;p&gt;And it will be pretty clear at call site that the object might keep the address
of the argument:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void Func2() {
  std::string content = GetString();
  Foo foo(&amp;amp;content);
}
&lt;/pre&gt;

&lt;h2 id=&quot;one-step-further-one-less-comment-storing-a-reference&quot;&gt;One Step Further, One Less Comment: Storing a Reference&lt;/h2&gt;

&lt;p&gt;You might have noticed that we say twice that the pointer cannot be null and
that it is not owned, once in the documentation of the constructor then in the
comment for the instance variable. Is this necessary? Consider this:&lt;/p&gt;
&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Baz {
 public:
  // Does not take any ownership, and all pointers must refer to valid objects
  // that outlive the one constructed.
  explicit Baz(const Arg1* arg1, Arg2* arg2) : arg1_(*arg1), arg2_(*arg2) {}

 private:
  // It is now clear that we do not have ownership and that the references can&apos;t
  // be null.
  const Arg1&amp;amp; arg1_;
  Arg2&amp;amp; arg2_;  // Yes, non-const references are style-compliant!
};
&lt;/pre&gt;

&lt;p&gt;One downside of members of reference type is that you cannot reassign them,
meaning that your class will not have a copy assignment operator (copy
constructors are still OK) but it might make sense to explicitly delete it to
respect the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Rule_of_three_\(C%2B%2B_programming\)&quot;&gt;rule of 3&lt;/a&gt;.
If your class should be assignable you’ll need non-const pointers, still
potentially to const objects. &lt;a href=&quot;/tips/177&quot;&gt;Tip #177&lt;/a&gt; discusses this in more
detail.&lt;/p&gt;

&lt;p&gt;If you want defense in depth and think some caller might accidentally pass a
null pointer, you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*ABSL_DIE_IF_NULL(arg1)&lt;/code&gt; to cause a crash. Note that
just dereferencing the null pointer is not, as is commonly believed, guaranteed
to crash; rather it is undefined behavior and should not be relied upon. Here
what would probably happen is that since a reference is implemented as a
pointer, it will just be copied and the crash will happen later, when someone
actually accesses the field.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;It is still OK to pass an argument by const reference to a constructor if the
argument is copied, or just used in the constructor and no reference to it is
kept in the constructed object. In other cases, consider passing arguments by
pointers (to const or not). Also remember that if you are actually transferring
the ownership of an object, it should be passed as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Lastly, what is discussed here is not limited to constructors: any function that
somehow keeps an alias to one of its arguments, whether by putting a pointer in
a cache or binding the argument in a detached function, should take that
argument by pointer.&lt;/p&gt;

&lt;h2 id=&quot;related-reading&quot;&gt;Related Reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/5&quot;&gt;Tip of the Week #5: Disappearing Act&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/101&quot;&gt;Tip of the Week #101: Return Values, References, and Lifetimes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/176&quot;&gt;Tip of the Week #176: Prefer Return Values to Output Parameters&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/177&quot;&gt;Tip of the Week #177: Assignability vs. Data Member Types&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs&quot;&gt;C++ Style Guide: Inputs and Outputs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2020-09-11T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/116</link>
          <guid isPermaLink="true">https://abseil.io/tips/116</guid>
        </item>
      
    
      
        <item>
          <title>Abseil Status</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:zhangxy988@gmail.com&quot;&gt;Xiaoyi Zhang&lt;/a&gt;, Google Engineer, Emeritus&lt;/p&gt;

&lt;p&gt;The Abseil status library is now available on abseil.io. This library is used
within Google for error handling and contains the following two abstractions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Within Google, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt; is the primary mechanism to gracefully handle
errors across API boundaries (and in particular across RPC boundaries). Some of
these errors may be recoverable, but others may not. Most functions that can
produce a recoverable error should be designed to return either an
absl::Status (or the similar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;&lt;/code&gt;, which holds either an object
of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; or an error).&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;A Status can either return “OK” (represented by the enumumerated value
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusCode::kOk&lt;/code&gt;) or one of a number of canonical error codes to
indicate certain error conditions:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// encounter error&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// absl::StatusCode::kInvalidArgument&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InvalidArgumentError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bad mode&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// else, return OK&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OkStatus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Abseil also provides an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;&lt;/code&gt; class template to represent a union of an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt; object and an object of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StatusOr&amp;lt;T&amp;gt;&lt;/code&gt; will
either contain an object of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; (indicating a successful operation), or an
error (of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt;) explaining why such a value is not present. This
abstraction is similar to the proposal in C++ for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::expected&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;For more information, consult the &lt;a href=&quot;https://abseil.io/docs/cpp/guides/status&quot;&gt;Abseil Status guide&lt;/a&gt; and the list
of &lt;a href=&quot;https://abseil.io/docs/cpp/guides/status-codes&quot;&gt;canonical error codes&lt;/a&gt;.&lt;/p&gt;

</description>
          <pubDate>2020-09-10T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/2020-091021-status</link>
          <guid isPermaLink="true">https://abseil.io/blog/2020-091021-status</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #140: Constants: Safe Idioms</title>
          <description>&lt;p&gt;Originally posted as TotW #140 on December 8, 2017&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:gmatta@gmail.com&quot;&gt;Matt Armstrong&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-05-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/140&quot;&gt;abseil.io/tips/140&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What are best ways to express constants in C++? You probably have an idea of
what the word means in English, but it is easy to express the concept
incorrectly in code. Here we’ll first define a few key concepts, then get to a
list of safe techniques. For the curious, we then go into more detail about what
can go wrong, and describe a C++17 language feature that makes expressing
constants easier.&lt;/p&gt;

&lt;p&gt;There is no formal definition of a “C++ constant” so let’s propose an informal
one.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;The value:&lt;/strong&gt; A value never changes; five is always five. When we want to
express a constant, we need a value, but only one.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The object:&lt;/strong&gt; At each point in time an object has a value. C++ places a
strong emphasis on &lt;em&gt;mutable&lt;/em&gt; objects, but mutation of constants is
disallowed.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The name:&lt;/strong&gt; Named constants are more useful than bare literal constants.
Both variables and functions can evaluate to constant objects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Putting that all together, let’s call a &lt;em&gt;constant&lt;/em&gt; a variable or function that
always &lt;em&gt;evaluates&lt;/em&gt; to the same value. There are a few more key concepts.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Safe Initialization:&lt;/strong&gt; Many times constants are expressed as values in
static storage, which must be safely initialized. For more on that, see
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables&quot;&gt;the C++ Style Guide&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Linkage:&lt;/strong&gt; Linkage has to do with how many instances (or “copies”) of a
named object there are in a program. It is usually best for a constant with
one name to refer to a single object within the program. For global or
namespace-scoped variables this requires something called external linkage
(&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/storage_duration&quot;&gt;you can read more about linkage here&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compile-time evaluation:&lt;/strong&gt; Sometimes the compiler can do a better job
optimizing code if a constant’s value is known at compile time. This benefit
can sometimes justify defining the values of constants in header files,
despite the additional complexity.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we say we’re “adding a constant” we’re actually &lt;em&gt;declaring&lt;/em&gt; an API and
&lt;em&gt;defining&lt;/em&gt; its implementation in such a way that satisfies most or all of the
above criteria. The language doesn’t dictate how we do this, and some ways are
better than others. Often the simplest approach is declaring a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; variable, marked as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; if it’s in a header file. Another
approach is returning a value from a function, which is more flexible. We’ll
cover examples of both approaches.&lt;/p&gt;

&lt;p&gt;A note on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;: it isn’t enough. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; object is &lt;em&gt;read-only&lt;/em&gt; but this
does not imply that it is &lt;em&gt;immutable&lt;/em&gt; nor does it imply that the value is always
the same. The language provides ways to mutate values we think of as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;,
such as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutable&lt;/code&gt; keyword and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const_cast&lt;/code&gt;. But even straightforward code
can demonstrate the point:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void f(const std::string&amp;amp; s) {
  const int size = s.size();
  std::cout &amp;lt;&amp;lt; size &amp;lt;&amp;lt; &apos;\n&apos;;
}

f(&quot;&quot;);  // Prints 0
f(&quot;foo&quot;);  // Prints 3
&lt;/pre&gt;

&lt;p&gt;In the above code &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size&lt;/code&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; variable, yet it holds multiple values as
the program runs. It is not a constant.&lt;/p&gt;

&lt;h2 id=&quot;constants-in-header-files&quot;&gt;Constants in Header Files&lt;/h2&gt;

&lt;p&gt;All of the idioms in this section are robust and recommendable.&lt;/p&gt;

&lt;h3 id=&quot;an-inline-constexpr-variable&quot;&gt;An inline constexpr Variable&lt;/h3&gt;

&lt;p&gt;From C++17 variables can be marked as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt;, ensuring that there is only a
single copy of the variable. When used with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; to ensure safe
initialization and destruction this gives another way to define a constant whose
value is accessible at compile time. See &lt;a href=&quot;/tips/168&quot;&gt;Tip #168&lt;/a&gt; for more
information.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// in foo.h
inline constexpr int kMyNumber = 42;
inline constexpr absl::string_view kMyString = &quot;Hello&quot;;
&lt;/pre&gt;

&lt;h3 id=&quot;extern-const-variable&quot;&gt;An extern const Variable&lt;/h3&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Declared in foo.h
extern const int kMyNumber;
extern const char kMyString[];
extern const absl::string_view kMyStringView;
&lt;/pre&gt;

&lt;p&gt;The above example &lt;strong&gt;declares&lt;/strong&gt; &lt;em&gt;one&lt;/em&gt; instance of each object. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extern&lt;/code&gt;
keyword ensures external linkage, while the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; keyword helps prevent
accidental mutation of the value. This is a fine way to go, though it does mean
the compiler can’t “see” the constant values. This limits their utility
somewhat, but not in ways that matter for typical use cases. It also requires
&lt;strong&gt;defining&lt;/strong&gt; the variables in the associated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Defined in foo.cc
constexpr int kMyNumber = 42;
constexpr char kMyString[] = &quot;Hello&quot;;
constexpr absl::string_view kMyStringView = &quot;Hello&quot;;
&lt;/pre&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; keyword ensures each variable is a constant, is compile-time
initialized, and has a trivial destructor. This is a convenient way to ensure it
meets the
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables&quot;&gt;style guide rules&lt;/a&gt;
for globals.&lt;/p&gt;

&lt;p&gt;You should define the variables in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt;, unless you
need to &lt;a href=&quot;#non-portable-mistake&quot;&gt;support an old toolchain&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;NOTE: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; is a good way to declare a string constant. The type
has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; constructor and a trivial destructor, so it is safe to declare
instances of it as global variables. Because a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; knows its length,
using them does not require a runtime call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strlen()&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;a-constexpr-function&quot;&gt;A constexpr Function&lt;/h3&gt;

&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; function that takes no arguments will always return the same
value, so it functions as a constant, and can often be used to initialize other
constants at compile time. Because all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; functions are implicitly
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt;, there are no linkage concerns. The primary disadvantage of this
approach is the limitations placed on the code in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; functions.
Secondarily, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; is a non-trivial aspect of the API contract, which has
real consequences .&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// in foo.h
constexpr int MyNumber() { return 42; }
&lt;/pre&gt;

&lt;h3 id=&quot;an-ordinary-function&quot;&gt;An Ordinary Function&lt;/h3&gt;

&lt;p&gt;When a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; function isn’t desirable or possible, an ordinary function
may be an option. The function in the following example can’t be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt;
because it has a static variable:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
inline absl::string_view MyString() {
  static constexpr char kHello[] = &quot;Hello&quot;;
  return kHello;
}
&lt;/pre&gt;

&lt;p&gt;NOTE: make sure you use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static constexpr&lt;/code&gt; specifiers when returning array data,
such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;char[]&lt;/code&gt; strings, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Span&lt;/code&gt;, etc, to avoid
&lt;a href=&quot;#string-view-mistake&quot;&gt;subtle bugs&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;a-static-class-member&quot;&gt;A &lt;code&gt;static&lt;/code&gt; Class Member&lt;/h3&gt;

&lt;p&gt;Static members of a class are a good option, assuming you are already working
with a class. These always have external linkage.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Declared in foo.h
class Foo {
 public:
  static constexpr int kMyNumber = 42;
  static constexpr absl::string_view kMyHello1 = &quot;Hello&quot;;
  static constexpr char kMyHello2[] = &quot;Hello&quot;;  // No longer recommended
};
&lt;/pre&gt;

&lt;p&gt;Prior to C++17 it was necessary to also provide definitions for these &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt;
data members in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file, but for data members that are both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; these are now unnecessary (and deprecated).&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Defined in foo.cc, prior to C++17.
constexpr int Foo::kMyNumber;
constexpr absl::string_view Foo::kMyHello1;
constexpr char Foo::kMyHello2[];
&lt;/pre&gt;

&lt;p&gt;It isn’t worth introducing a class just to act as a scope for a bunch of
constants. Use one of the other techniques instead.&lt;/p&gt;

&lt;h3 id=&quot;discouraged-alternatives&quot;&gt;Discouraged Alternatives&lt;/h3&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
#define WHATEVER_VALUE 42
&lt;/pre&gt;

&lt;p&gt;Using the preprocessor is rarely justified, see
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Preprocessor_Macros&quot;&gt;the style guide&lt;/a&gt;.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
enum : int { kMyNumber = 42 };
&lt;/pre&gt;

&lt;p&gt;The enum technique used above can be justified in some circumstances. It
produces a constant &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kMyNumber&lt;/code&gt; that cannot cause the problems talked about in
this tip. But the alternatives already listed will be more familiar to most
people, and so are generally preferred. Use an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; when it makes sense in its
own right (for examples, see &lt;a href=&quot;/tips/86&quot;&gt;Tip #86&lt;/a&gt; “Enumerating with Class”).&lt;/p&gt;

&lt;h2 id=&quot;approaches-that-work-in-source-files&quot;&gt;Approaches that Work in Source Files&lt;/h2&gt;

&lt;p&gt;All of the approaches described above also work within a single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file, but
may be unnecessarily complex. Because constants declared within a source file
are visible only inside that file by default (see
&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/storage_duration&quot;&gt;internal linkage rules&lt;/a&gt;),
simpler approaches, such as defining &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; variables, often work:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// within a .cc file!
constexpr int kBufferSize = 42;
constexpr char kBufferName[] = &quot;example&quot;;
constexpr absl::string_view kOtherBufferName = &quot;other example&quot;;
&lt;/pre&gt;

&lt;p&gt;The above is fine in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file but not a header file (see
&lt;a href=&quot;#non-portable-mistake&quot;&gt;caveat&lt;/a&gt;). Read that again and commit it to memory. I’ll
explain why soon. Long story short: define variables &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; files
or declare them &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extern const&lt;/code&gt; in header files.&lt;/p&gt;

&lt;h3 id=&quot;within-a-header-file-beware&quot;&gt;Within a Header File, Beware!&lt;/h3&gt;

&lt;p&gt;Unless you take care to use idioms explained above, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt;
objects are likely to be &lt;em&gt;different&lt;/em&gt; objects in each translation unit.&lt;/p&gt;

&lt;p&gt;This implies:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Bugs&lt;/strong&gt;: any code that uses the address of a constant is subject to bugs
and even the dreaded
“&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/ub&quot;&gt;undefined behavior&lt;/a&gt;”.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Bloat&lt;/strong&gt;: each translation unit including your header gets its own copy of
the thing. Not such a big deal for simple things like the primitive numeric
types. Not so great for strings and bigger data structures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When at namespace scope (i.e. not in a function or in a class), both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; objects implicitly have internal linkage (the same linkage used for
unnamed-namespace variables and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt; variables not in a function or in a
class). The C++ standard guarantees that every translation unit that uses or
references the object gets a different “copy” or “instantiation” of the object,
each at a &lt;em&gt;different address&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Within a class, you must additionally declare these objects as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt;, or they
will be unchangeable instance variables, rather than unchangeable class
variables shared among every instance of the class.&lt;/p&gt;

&lt;p&gt;Likewise, within a function, you must declare these objects as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt;, or they
will take up space on the stack and be constructed every time the function is
called.&lt;/p&gt;

&lt;h4 id=&quot;example-bug&quot;&gt;An Example Bug&lt;/h4&gt;

&lt;p&gt;So, is this a real risk? Consider:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// Declared in do_something.h
constexpr char kSpecial[] = &quot;special&quot;;

// Does something.  Pass kSpecial and it will do something special.
void DoSomething(const char* value);
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// Defined in do_something.cc
void DoSomething(const char* value) {
  // Treat pointer equality to kSpecial as a sentinel.
  if (value == kSpecial) {
    // do something special
  } else {
    // do something boring
  }
}
&lt;/pre&gt;

&lt;p&gt;Notice that this code compares the address of the first char in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kSpecial&lt;/code&gt; to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; as a kind of magic value for the function. You sometimes see code do
this in an effort to short circuit a full string comparison.&lt;/p&gt;

&lt;p&gt;This causes a subtle bug. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kSpecial&lt;/code&gt; array is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; which implies that
it is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt; (with “internal” linkage). Even though we think of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kSpecial&lt;/code&gt; as
“a constant” – it really isn’t – it’s a whole family of constants, one per
translation unit! Calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoSomething(kSpecial)&lt;/code&gt; look like they should do the
same thing, but the function takes different code paths depending on where the
call occurs.&lt;/p&gt;

&lt;p&gt;Any code using a constant array defined in a header file, or code that takes the
address of a constant defined in a header file, suffices for this kind of bug.
This class of bug is usually seen with string constants, because they are the
most common reason to define arrays in header files.&lt;/p&gt;

&lt;h4 id=&quot;an-example-of-undefined-behavior&quot;&gt;An Example of Undefined Behavior&lt;/h4&gt;

&lt;p&gt;Just tweak the above example, and move &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoSomething&lt;/code&gt; into the header file as an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; function. Bingo: now we’ve got undefined behavior, or UB. The language
requires all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; functions to be defined exactly the same way in every
translation unit (source file) – this is part of the language’s “One Definition
Rule.” This particular &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoSomething&lt;/code&gt; implementation references a static
variable, so every translation unit actually defines &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoSomething&lt;/code&gt;
&lt;em&gt;differently&lt;/em&gt;, hence the undefined behavior.&lt;/p&gt;

&lt;p&gt;Unrelated changes to program code and compilers can change inlining decisions,
which can cause undefined behavior like this to change from benign behavior to
bug.&lt;/p&gt;

&lt;h4 id=&quot;does-this-cause-problems-in-practice&quot;&gt;Does this Cause Problems in Practice?&lt;/h4&gt;

&lt;p&gt;Yes. In one real-life bug we’ve encountered, the compiler was able to determine
that in a particular translation unit (source file), a large static const array
defined in a header file was only partially used. Rather than emit the entire
array, it optimized away the parts it knew weren’t used. One of the ways the
array was partially used was through an inline function declared in a header.&lt;/p&gt;

&lt;p&gt;The trouble is, the array was used by other translation units in such a way that
the static const array was fully used. For those translation units, the compiler
generated a version of the inline function that used the full array.&lt;/p&gt;

&lt;p&gt;Then the linker came along. The linker assumed that all instances of the inline
function were the same, because the One Definition Rule said they had to be. And
it discarded all but one copy of the function - and that was the copy with the
partially-optimized array.&lt;/p&gt;

&lt;p&gt;This kind of bug is possible when code uses a variable in a way that requires
its address to be known. The technical term for this is “ODR used”. It is
difficult to prevent ODR use of variables in modern C++ programs, particularly
if those values are passed to template functions (as was the case in the above
example).&lt;/p&gt;

&lt;p&gt;These bugs do happen and are not easily caught in tests or code review. It pays
to stick to safe idioms when defining constants.&lt;/p&gt;

&lt;h2 id=&quot;other-common-mistakes&quot;&gt;Other Common Mistakes&lt;/h2&gt;

&lt;h3 id=&quot;mistake-1-the-non-constant-constant&quot;&gt;Mistake #1: the Non-Constant Constant&lt;/h3&gt;

&lt;p&gt;Seen most often with pointers:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
const char* kStr = ...;
const Thing* kFoo = ...;
&lt;/pre&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kFoo&lt;/code&gt; above is a pointer to const, but the pointer itself is not a
constant. You can assign to it, set it null, etc.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Corrected.
const Thing* const kFoo = ...;
// This works too.
constexpr const Thing* kFoo = ...;
&lt;/pre&gt;

&lt;h3 id=&quot;string-view-mistake&quot;&gt;Mistake #2: the Non-Constant MyString()&lt;/h3&gt;

&lt;p&gt;Consider this code:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
inline absl::string_view MyString() {
  return &quot;Hello&quot;;  // may return a different value with every call
}
&lt;/pre&gt;

&lt;p&gt;The address of a string literal constant is allowed to change every time it is
evaluated&lt;sup id=&quot;fnref:string_literals_can_move&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:string_literals_can_move&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, so the above is subtly wrong because it
returns a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; that might have a different &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.data()&lt;/code&gt; value for each
call. While in many cases this won’t be a problem, it can lead to
&lt;a href=&quot;#example-bug&quot;&gt;the bug described above&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Making the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyString()&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; does not fix the issue, because the language
standard does not say it does&lt;sup id=&quot;fnref:string_literals_can_move_in_constexpr&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:string_literals_can_move_in_constexpr&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. One way
to look at this is that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; function is just an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; function that
is allowed to execute at compile time when initializing constant values. At run
time it is not different from an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; function.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
constexpr absl::string_view MyString() {
  return &quot;Hello&quot;;  // may return a different value with every call
}
&lt;/pre&gt;

&lt;p&gt;To avoid the bug, use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static constexpr&lt;/code&gt; variable in a function instead:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
inline absl::string_view MyString() {
  static constexpr char kHello[] = &quot;Hello&quot;;
  return kHello;
}
&lt;/pre&gt;

&lt;p&gt;Rule of thumb: if your “constant” is an array type, store it in a function local
static before returning it. This fixes its address.&lt;/p&gt;

&lt;!-- force separation between footnotes so migration script does the right thing --&gt;

&lt;h3 id=&quot;non-portable-mistake&quot;&gt;Mistake #3: Non-Portable Code&lt;/h3&gt;

&lt;p&gt;For the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extern const&lt;/code&gt;
&lt;a href=&quot;#extern-const-variable&quot;&gt;variables declared in header files&lt;/a&gt; the following
approach to defining their values is valid according to the standard C++, and is
generally preferable to C++20’s
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/constinit&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constinit&lt;/code&gt;&lt;/a&gt; (or the
older &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ABSL_CONST_INIT&lt;/code&gt;), but runs afoul of a bug with at least one common
compiler:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Defined in foo.cc -- valid C++, but not supported by MSVC 19 by default.
constexpr absl::string_view kOtherBufferName = &quot;other example&quot;;
&lt;/pre&gt;

&lt;p&gt;Unfortunately, MSVC++19 incorrectly gives a C2370 error for this code unless the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Zc:externConstexpr&lt;/code&gt; option is used. If code needs to compile with MSVC++19 and
cannot rely on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Zc:externConstexpr&lt;/code&gt;, as a workaround you can provide its value
to other files through functions instead of as a global variable.&lt;/p&gt;

&lt;h3 id=&quot;mistake-4-improperly-initialized-constants&quot;&gt;Mistake #4: Improperly Initialized Constants&lt;/h3&gt;

&lt;p&gt;The style guide has some detailed rules intended to keep us safe from common
problems related to run-time initialization of static and global variables. The
root issue arises when the initialization of global variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X&lt;/code&gt; references
another global variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y&lt;/code&gt;. How can we be sure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y&lt;/code&gt; itself doesn’t somehow
depend on the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X&lt;/code&gt;? Cyclic initialization dependencies can easily happen
with global variables, especially with those we think of as constants.&lt;/p&gt;

&lt;p&gt;This is a pretty thorny area of the language in its own right.
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables&quot;&gt;The style guide&lt;/a&gt;
is an authoritative reference.&lt;/p&gt;

&lt;p&gt;Consider the above links required reading. With a focus on initialization of
constants, the phases of initialization can be explained as:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Zero initialization&lt;/strong&gt;. This is what initializes otherwise uninitialized
static variables to the “zero” value for the type (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.0&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;\0&apos;&lt;/code&gt;,
null, etc.).&lt;/p&gt;

    &lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
const int kZero;  // this will be zero-initialized to 0
const int kLotsOfZeroes[5000];  // so will all of these
&lt;/pre&gt;

    &lt;p&gt;Note that relying on zero initialization is fairly popular in C code but is
fairly rare and niche in C++. It is generally clearer to assign variables
explicit values, even if the value is zero, which brings us to…&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Constant initialization&lt;/strong&gt;.&lt;/p&gt;

    &lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
const int kZero = 0;  // this will be constant-initialized to 0
const int kOne = 1;   // this will be constant-initialized to 1
&lt;/pre&gt;

    &lt;p&gt;Both “constant initialization” and “zero initialization” are called “static
initialization” in the C++ language standard. Both are always safe.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Dynamic initialization&lt;/strong&gt;.&lt;/p&gt;

    &lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// This will be dynamically initialized at run-time to
// whatever ArbitraryFunction returns.
const int kArbitrary = ArbitraryFunction();
&lt;/pre&gt;

    &lt;p&gt;Dynamic initialization is where most problems happen. The style guide
explains why at
https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables.&lt;/p&gt;

    &lt;p&gt;Note that documents like the Google C++ style guide have historically
included dynamic initialization in the broad category of “static
initialization.” The word “static” applies to a few different concepts in
C++, which can be confusing. “Static initialization” can mean
“initialization &lt;em&gt;of&lt;/em&gt; static variables,” which can include run-time
computation (dynamic initialization). The language standard uses the term
“static initialization” in a different, narrower, sense: initialization that
is done statically or at compile-time.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;initialization-cheat-sheet&quot;&gt;Initialization Cheat Sheet&lt;/h2&gt;

&lt;p&gt;Here is a super-quick constant initialization cheat sheet (not in header files):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; guarantees safe constant initialization as well as safe
(trivial) destruction. Any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; variable is entirely fine when
defined in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file, but is problematic in header files for reasons
explained earlier.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constinit&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ABSL_CONST_INIT&lt;/code&gt; prior to C++20) guarantees safe constant
initialization. Unlike &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt;, it does not actually make the variable
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;, nor does it ensure the destructor is trivial, so care must still be
taken when declaring static variables with it. See again
https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables.&lt;/li&gt;
  &lt;li&gt;Otherwise, you’re most likely best off using a static variable within a
function and returning it. See the “ordinary function” example shown
earlier.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;further-reading-and-collected-links&quot;&gt;Further Reading and Collected Links&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables&lt;/li&gt;
  &lt;li&gt;http://en.cppreference.com/w/cpp/language/constexpr&lt;/li&gt;
  &lt;li&gt;http://en.cppreference.com/w/cpp/language/inline&lt;/li&gt;
  &lt;li&gt;http://en.cppreference.com/w/cpp/language/storage_duration (linkage rules)&lt;/li&gt;
  &lt;li&gt;http://en.cppreference.com/w/cpp/language/ub (Undefined Behavior)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; variable from C++17 can’t come soon enough. Until then all we can
do is use the safe idioms that steer us clear of the rough edges.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:string_literals_can_move&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;We conclude that string literals are not required
to evaluate to the same object from the following
language in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[lex.string]&lt;/code&gt; in the C++17 language
standard. Equivalent language is also present in
C++11 and C++14. &lt;a href=&quot;#fnref:string_literals_can_move&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:string_literals_can_move_in_constexpr&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;There is no language in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[lex.string]&lt;/code&gt;
describing different behavior in a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; context. &lt;a href=&quot;#fnref:string_literals_can_move_in_constexpr&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
          <pubDate>2020-09-01T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/140</link>
          <guid isPermaLink="true">https://abseil.io/tips/140</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #5: Disappearing Act</title>
          <description>&lt;p&gt;Originally posted as TotW #5 on June 26, 2012&lt;/p&gt;

&lt;p&gt;Updated 2020-06-01&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/5&quot;&gt;abseil.io/tips/5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Don’t know what you got till it’s gone.” –Cinderella&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, in order to use a C++ library the right way, you need to understand
both the library and the language. So … what’s wrong with the following?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// DON’T DO THIS
std::string s1, s2;
...
const char* p1 = (s1 + s2).c_str();             // Avoid!
const char* p2 = absl::StrCat(s1, s2).c_str();  // Avoid!
&lt;/pre&gt;

&lt;p&gt;Both (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s1+s2&lt;/code&gt;) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat(s1,s2)&lt;/code&gt; create temporary objects (in both
cases, strings, but the same rules apply for any objects). The member function
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c_str()&lt;/code&gt; returns a pointer to data that lives as long as the temporary object.
How long does the temporary object live? According to the C++17 standard
[class.temporary], “Temporary objects are destroyed as the last step in
evaluating the full-expression that (lexically) contains the point where they
were created.” (A “full-expression” is “an expression that is not a
subexpression of another expression”). In each example above, as soon as the
expression on the right side of the assignment operator was completed, the
temporary value was destroyed, and the return value from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c_str()&lt;/code&gt; became a
dangling pointer. tl;dr? By the time you hit a semicolon (often sooner), the
temporary object is history. Yikes! How can you avoid this kind of problem?&lt;/p&gt;

&lt;h2 id=&quot;option-1-finish-using-the-temporary-object-before-the-end-of-the-full-expression&quot;&gt;Option 1: Finish Using the Temporary Object Before the End of the full-expression:&lt;/h2&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Safe (albeit a silly example):
size_t len1 = strlen((s1 + s2).c_str());
size_t len2 = strlen(absl::StrCat(s1, s2).c_str());
&lt;/pre&gt;

&lt;h2 id=&quot;option-2-store-the-temporary-object&quot;&gt;Option 2: Store the Temporary Object.&lt;/h2&gt;

&lt;p&gt;You’re creating an object (on the stack) anyway; why not hang on to it for a
while? This is cheaper than it might first appear. Because of something called
“return value optimization,” (and move semantics on many value types, see
&lt;a href=&quot;/tips/77&quot;&gt;Tip #77&lt;/a&gt;) the temporary object will be constructed in the variable
you’re “assigning” it to, and won’t be copied:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Safe (and more efficient than you might think):
std::string tmp_1 = s1 + s2;
std::string tmp_2 = absl::StrCat(s1, s2);
// tmp_1.c_str() and tmp_2.c_str() are safe.
&lt;/pre&gt;

&lt;h2 id=&quot;option-3-store-a-reference-to-the-temporary-object&quot;&gt;Option 3: Store a Reference to the Temporary Object.&lt;/h2&gt;

&lt;p&gt;C++17 standard [class.temporary]: “The temporary to which the reference is bound
or the temporary that is the complete object of a sub-object to which the
reference is bound persists for the lifetime of the reference.”&lt;/p&gt;

&lt;p&gt;Because of return value optimization, this usually isn’t any cheaper than
storing the object itself (Option 2), and it is potentially confusing or
worrisome (see &lt;a href=&quot;/tips/101&quot;&gt;Tip #101&lt;/a&gt;). (Exceptional cases that need to use
lifetime extension should be commented!)&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Equally safe:
const std::string&amp;amp; tmp_1 = s1 + s2;
const std::string&amp;amp; tmp_2 = absl::StrCat(s1, s2);
// tmp_1.c_str() and tmp_2.c_str() are safe.
// The following behavior is dangerously subtle:
// If the compiler can see you’re storing a reference to a
// temporary object’s internals, it will keep the whole
// temporary object alive.
// struct Person { string name; ... }
// GeneratePerson() returns an object; GeneratePerson().name
// is clearly a sub-object:
const std::string&amp;amp; person_name = GeneratePerson().name; // safe
// If the compiler can’t tell, you’re at risk.
// class DiceSeries_DiceRoll { `const string&amp;amp;` nickname() ... }
// GenerateDiceRoll() returns an object; the compiler can’t tell
// if GenerateDiceRoll().nickname() is a subobject.
// The following may store a dangling reference:
const std::string&amp;amp; nickname = GenerateDiceRoll().nickname(); // BAD!
&lt;/pre&gt;

&lt;h2 id=&quot;option-4-design-your-functions-so-they-dont-return-objects&quot;&gt;Option 4: Design your functions so they don’t return objects???&lt;/h2&gt;

&lt;p&gt;Many functions follow this principle; but many don’t. Sometimes it really is
better to return an object than to require the caller to pass in a pointer to an
output parameter. Be aware of when the creation of temporaries can happen.
Anything that returns a pointer or reference to an object’s internals is
potentially a problem when operating on a temporary object. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c_str()&lt;/code&gt; is the
most obvious culprit, but protobuf getters (mutable or otherwise) and getters in
general can be equally problematic.&lt;/p&gt;
</description>
          <pubDate>2020-06-01T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/5</link>
          <guid isPermaLink="true">https://abseil.io/tips/5</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #177: Assignability vs. Data Member Types</title>
          <description>&lt;p&gt;Originally posted as TotW #177 on April 6, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:titus@cs.ucr.edu&quot;&gt;Titus Winters&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/177&quot;&gt;abseil.io/tips/177&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When implementing a type, decide on type design first. Prioritize API over
implementation details. One common example of this is the tradeoff between
assignability of a type vs. qualifiers for data members.&lt;/p&gt;

&lt;h2 id=&quot;deciding-how-to-represent-data-members&quot;&gt;Deciding how to represent data members&lt;/h2&gt;

&lt;p&gt;Imagine you are writing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;City&lt;/code&gt; class, and discussing how to represent its
member variables. You know that it is short-lived, representing the city as a
snapshot in time, so things like population, name, and mayor could conceivably
be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; - we aren’t going to use the same object in a given program for years
and years, so we don’t need to account for changes in population, new census
results, or elections.&lt;/p&gt;

&lt;p&gt;Should we have members like this?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
 private:
  const std::string city_name_;
  const Person mayor_;
  const int64_t population_;
&lt;/pre&gt;

&lt;p&gt;Why or why not?&lt;/p&gt;

&lt;p&gt;The common suggestion for “Yes, make those &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;” hinges on the idea “Well,
those values aren’t going to change for a given &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;City&lt;/code&gt;, so since everything that
can be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; should be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;, make them &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;.” That will make it easier
for maintainers of the class to avoid accidentally modifying those fields.&lt;/p&gt;

&lt;p&gt;This misses a critically important concern: what sort of type is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;City&lt;/code&gt;? Is this
a value? Or a bundle of business logic? Is it expected to be copyable,
move-only, or non-copyable? The set of operations you can write efficiently for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;City&lt;/code&gt; (as a whole) may be impacted by the question of whether a single member
is made &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;, and that is often a bad tradeoff.&lt;/p&gt;

&lt;p&gt;Specifically, if your class has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; members, it cannot be assigned to
(whether by copy-assignment or move-assignment). The language understands this:
if your type has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; member, copy-assignment and move-assignment operators
will not be synthesized. You can still copy (or move) &lt;em&gt;construct&lt;/em&gt; such an
object, but you cannot change it in any way after construction (even “just” to
copy from another object of the same type). Even if you write your own
assignment operators, you’ll quickly find that you (obviously) can’t overwrite
these &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; members.&lt;/p&gt;

&lt;p&gt;So it is possible that the question becomes “Which should we prefer: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;
members or assignment operations?” However, even that is misleading, because
both are answered by the one &lt;em&gt;important&lt;/em&gt; question, “What sort of type is
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;City&lt;/code&gt;?” If it is intended to be a &lt;em&gt;value type&lt;/em&gt;, that specifies the API
(including assignment operations), and API trumps implementation concern in
general.&lt;/p&gt;

&lt;p&gt;It is important for those API design decisions to take priority over
implementation-detail choices: in the general case, there are more engineers
affected by the API of a type than implementation of a type. That is, there are
more users of a type than maintainers of that type, so priority should go to
design choices that affect the user above the implementer. Even if you think the
type will never be used by anyone outside of the team that is maintaining it,
software engineering is about interface design and abstraction - we should be
prioritizing good interfaces.&lt;/p&gt;

&lt;h2 id=&quot;reference-members&quot;&gt;Reference Members&lt;/h2&gt;

&lt;p&gt;The same reasoning applies to storing references as data members. Even if we
know that the member must be non-null, it is still usually preferable to store
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T*&lt;/code&gt; for value types, because references are not rebindable. That is, we cannot
re-point a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&amp;amp;&lt;/code&gt; - any modifications of such a member are modifying the
underlying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Consider the implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;T&amp;gt;&lt;/code&gt;. There will almost certainly be
a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T* data&lt;/code&gt; member in any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; implementation, pointing to the
allocation. We know from the specification of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; that such an
allocation must usually be valid (except possibly for empty vectors). An
implementation that always has an allocation could make that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&amp;amp;&lt;/code&gt;, right? (Yes,
I’m ignoring arrays and offsets here.)&lt;/p&gt;

&lt;p&gt;Clearly not. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; is a value type, it is copyable and assignable. If
the allocation was stored with a reference-to-the-first-member instead of
pointer-to-the-first-member, we wouldn’t be able to move-assign the storage, and
it’s unclear how we’d update &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; when resizing normally. Our clever way of
telling other maintainers “This value is non-null” would be getting in the way
of providing users the desired API. Hopefully it is clear that this is the wrong
tradeoff.&lt;/p&gt;

&lt;h2 id=&quot;non-copyable--assignable-types&quot;&gt;Non-copyable / assignable types&lt;/h2&gt;

&lt;p&gt;Of course, if your choices about type design suggest that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;City&lt;/code&gt; (or whatever
type you are thinking about) should be non-copyable, that leaves far fewer
constraints on your implementation. It isn’t &lt;em&gt;right&lt;/em&gt; or &lt;em&gt;wrong&lt;/em&gt; for a class to
hold &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; or reference members, it’s only a concern when those implementation
decisions are constraining or corrupting the interface presented by that class.
If you’ve already made a thoughtful and conscious decision that your type need
not be copyable, it’s very reasonable for you to make different choices about
how to represent the data members of the class. (But see &lt;a href=&quot;/tips/116&quot;&gt;Tip #116&lt;/a&gt;
for some more thoughts and pitfalls around argument lifetime and reference
storage).&lt;/p&gt;

&lt;h2 id=&quot;the-unusual-case-immutable-types&quot;&gt;The Unusual Case: immutable types&lt;/h2&gt;

&lt;p&gt;There is one useful-but-unusual design that may &lt;em&gt;mandate&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; members:
intentionally immutable types. Instances of such a type are immutable after
construction: no mutating methods, no assignment operators. These are fairly
rare, but can sometimes be useful. In particular, such a type is inherently
&lt;em&gt;thread-safe&lt;/em&gt; because there are no mutating operations. Objects of such a type
can be freely shared among threads with no concern about data races or
synchronization. However, in exchange these objects may have significant
run-time overhead stemming from the need to copy them constantly. The
immutability even prevents these objects from being efficiently moved.&lt;/p&gt;

&lt;p&gt;It is almost always preferable to design your type to be mutable but still
thread-compatible, rather than relying on thread-safety-via-immutability. Users
of your type are usually in a better position to judge the benefits of
mutability case-by-case. Don’t force them to work around unusual design choices
without very strong evidence showing why your use case is unusual.&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Decide on the design of your type before considering implementation details.&lt;/li&gt;
  &lt;li&gt;Value types are common and recommended. So are business-logic types, which
are often non-copyable.&lt;/li&gt;
  &lt;li&gt;Immutable types are sometimes useful, but the cases where they are justified
are fairly rare.&lt;/li&gt;
  &lt;li&gt;Prioritize API design and the needs of users over the (usually smaller)
concerns of maintainers.&lt;/li&gt;
  &lt;li&gt;Avoid &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; and reference data members when building value types or
move-only types.&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2020-04-06T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/177</link>
          <guid isPermaLink="true">https://abseil.io/tips/177</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #176: Prefer Return Values to Output Parameters</title>
          <description>&lt;p&gt;Originally posted as TotW #176 on March 12, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:edechamps@google.com&quot;&gt;Etienne Dechamps&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/176&quot;&gt;abseil.io/tips/176&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;/h2&gt;

&lt;p&gt;Consider the following:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// Extracts the foo spec and the bar spec from the provided doodad.
// Returns false if the input is invalid.
bool ExtractSpecs(Doodad doodad, FooSpec* foo_spec, BarSpec* bar_spec);
&lt;/pre&gt;

&lt;p&gt;Using (or implementing) this function correctly requires the developer to ask
themselves a surprising number of questions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo_spec&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar_spec&lt;/code&gt; &lt;em&gt;out&lt;/em&gt; or &lt;em&gt;in/out&lt;/em&gt; parameters?&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What happens to pre-existing data&lt;/strong&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo_spec&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar_spec&lt;/code&gt;? Is it
appended to? Is it overwritten? Does it make the function CHECK-fail? Does
it make it return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;? Is it undefined behavior?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Can &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo_spec&lt;/code&gt; be null?&lt;/strong&gt; Can &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar_spec&lt;/code&gt;? If they cannot, does a null
pointer make the function CHECK-fail? Does it make it return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;? Is it
undefined behavior?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What are the lifetime requirements&lt;/strong&gt; on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo_spec&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar_spec&lt;/code&gt;? In
other words, do they need to outlive the function call?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt; is returned&lt;/strong&gt;, what happens to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo_spec&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar_spec&lt;/code&gt;? Are
they guaranteed to be unchanged? Are they “reset” in some way? Is it
unspecified?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One cannot answer any of these questions from the function signature alone, and
cannot rely on the C++ compiler to enforce these contracts. Function comments
can help, but often don’t. This function’s documentation, for example, is silent
on most of these issues, and is also ambiguous about what “input” means. Does it
refer only to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;doodad&lt;/code&gt;, or to the other parameters too?&lt;/p&gt;

&lt;p&gt;Furthermore, this approach inflicts boilerplate on every callsite: the caller
has to allocate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FooSpec&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BarSpec&lt;/code&gt; objects in advance in order to call the
function.&lt;/p&gt;

&lt;p&gt;In this case, there’s a simple way to eliminate the boilerplate &lt;em&gt;and&lt;/em&gt; encode the
contracts in a way that the compiler can enforce.&lt;/p&gt;

&lt;h2 id=&quot;the-solution&quot;&gt;The solution&lt;/h2&gt;

&lt;p&gt;Here’s how to make all these questions moot:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct ExtractSpecsResult {
  FooSpec foo_spec;
  BarSpec bar_spec;
};
// Extracts the foo spec and the bar spec from the provided doodad.
// Returns nullopt if the input is invalid.
std::optional&amp;lt;ExtractSpecsResult&amp;gt; ExtractSpecs(Doodad doodad);
&lt;/pre&gt;

&lt;p&gt;This new API is semantically the same, but it is now much harder to misuse:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It is clearer what the inputs and outputs are.&lt;/li&gt;
  &lt;li&gt;There are no questions about pre-existing data in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo_spec&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar_spec&lt;/code&gt;
because they are created from scratch by the function.&lt;/li&gt;
  &lt;li&gt;There are no questions about null pointers because there are no pointers.&lt;/li&gt;
  &lt;li&gt;There are no questions about lifetimes because everything is passed and
returned by value.&lt;/li&gt;
  &lt;li&gt;There are no questions about what happens to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo_spec&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar_spec&lt;/code&gt; in
case of failure because they cannot even be accessed if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nullopt&lt;/code&gt; is
returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This in turn reduces the likelihood of bugs and reduces cognitive load on the
developer.&lt;/p&gt;

&lt;p&gt;There are other benefits, too. For example the function is more easily
composable; that is, it can easily be used as part of a wider expression, e.g.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SomeFunction(ExtractSpecs(...))&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;caveats&quot;&gt;Caveats&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;This approach doesn’t work for in-out parameters.
    &lt;ul&gt;
      &lt;li&gt;In some cases it is possible to use a variant of this approach whereby
the parameter is taken by value, mutated, and then returned by value.
Whether this is a good idea or not depends on how the function is used
and whether the value is efficiently movable (&lt;a href=&quot;/tips/117&quot;&gt;Tip #117&lt;/a&gt;).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;This approach doesn’t let the caller easily customize the creation of the
returned objects.
    &lt;ul&gt;
      &lt;li&gt;For example, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FooSpec&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BarSpec&lt;/code&gt; are protos, the out-parameter
approach lets the caller allocate those protos on a particular arena if
they wish. In the return-values approach, the arena would need to be
specified as an additional parameter or the callee would have to know it
already.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Performance might differ depending on which approach you choose and the
specifics of the situation.
    &lt;ul&gt;
      &lt;li&gt;In some cases returning values can be less efficient, for example if it
leads to repeated allocation in a loop.&lt;/li&gt;
      &lt;li&gt;In other cases, returning values might be more efficient than you think,
thanks to (N)RVO (&lt;a href=&quot;/tips/11&quot;&gt;Tip #11&lt;/a&gt;, &lt;a href=&quot;/tips/166&quot;&gt;Tip #166&lt;/a&gt;). It might
even be &lt;em&gt;more&lt;/em&gt; efficient than output parameters because the optimizer
doesn’t have to worry about aliasing.&lt;/li&gt;
      &lt;li&gt;As always, avoid premature optimization. Choose the API that makes the
most sense, and only cater to performance if you have evidence that it
makes a difference.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Prefer return values to output parameters&lt;/strong&gt; whenever possible. This is
consistent with the
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Output_Parameters&quot;&gt;style guide&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Use generic wrappers&lt;/strong&gt; like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; to represent a missing return
value. Consider returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&lt;/code&gt;if you need a more flexible
representation with multiple alternatives.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Use a struct&lt;/strong&gt; to return multiple values from a function.
    &lt;ul&gt;
      &lt;li&gt;Feel free to write a new struct specifically to represent the return
value of the function if that makes sense.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Structs_vs._Tuples&quot;&gt;Resist&lt;/a&gt;
the temptation to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::tuple&lt;/code&gt; for this purpose.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2020-04-06T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/176</link>
          <guid isPermaLink="true">https://abseil.io/tips/176</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #175: Changes to Literal Constants in C++14 and C++17.</title>
          <description>&lt;p&gt;Originally posted as TotW #175 on January 30, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;James Dennett&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/175&quot;&gt;abseil.io/tips/175&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“The only thing that stays the same is change” – Melissa Etheridge&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;p&gt;C++ now has some features that can make numeric literals more readable.&lt;/p&gt;

&lt;p&gt;Integer literals can now be written in binary (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0b00101010&lt;/code&gt;) as well as the
decimal (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;42&lt;/code&gt;), hex (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A&lt;/code&gt;), and octal (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;052&lt;/code&gt;) formats that have been supported
since the dawn of time.&lt;/p&gt;

&lt;p&gt;Single quotes (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;&lt;/code&gt;) serve as digit separators, and can be used to group digits
in numeric literals of any base (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xDEAD&apos;C0DE&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Floating point literals can be specified in hex (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A0p-4&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;binary-literals&quot;&gt;Binary Literals&lt;/h2&gt;

&lt;p&gt;Binary literals such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0b1110&apos;0000&lt;/code&gt; can be more readable than hex (the next
best option) when manipulating bit sets or working with low-level protocols.&lt;/p&gt;

&lt;h2 id=&quot;digit-separators&quot;&gt;Digit Separators&lt;/h2&gt;

&lt;p&gt;C++14 allows a single quote (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;&lt;/code&gt;) to be used to group digits in a numeric
literal. These digit separators have no effect on the value of the constant:
their only function is to help readers. They can make it easy to see at a glance
how many digits are present, and know that none are missing. For example,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&apos;000&apos;000&apos;000&lt;/code&gt; is more obviously one billion than is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1000000000&lt;/code&gt; (and unlike
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1e9&lt;/code&gt; it is an integer, not a floating point value).&lt;/p&gt;

&lt;p&gt;There are no restrictions on the number of digits per group, not even a
requirement of consistency within a literal: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0b1&apos;001&apos;0001&lt;/code&gt; is a valid way to
write the number 145 (and may even make sense for a byte that is interpreted as
three separate fields).&lt;/p&gt;

&lt;h2 id=&quot;hex-floating-point-literals&quot;&gt;Hex Floating Point Literals&lt;/h2&gt;

&lt;p&gt;While most &lt;em&gt;decimal&lt;/em&gt; floating point literals are not exactly representable in
the binary floating point formats used by most computers, &lt;em&gt;hex&lt;/em&gt; floating
literals do map directly to bit patterns in floating point so long as enough
bits are available. This avoids rounding errors when converting a literal to
floating point format (though truncation errors are still possible if too many
hex digits are present).&lt;/p&gt;

&lt;p&gt;Hex floating point literals are indicated by writing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt; (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P&lt;/code&gt;) to separate
the significand from the exponent—where decimal floating point literals would
use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt; (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;E&lt;/code&gt;). For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2Ap12&lt;/code&gt; is another way to write the value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A
&amp;lt;&amp;lt; 12&lt;/code&gt;, i.e., 0x2A000, except that is a floating point value, not an integer. As
a result, our style guide
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Floating_Literals&quot;&gt;requires&lt;/a&gt;
it to be written as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2A.0p12&lt;/code&gt; to be explicit that it is a floating point value
and not just another way to write an integer.&lt;/p&gt;

&lt;p&gt;The exponent is always written in decimal, denotes a power of 2, and may be
negative: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x1p-10&lt;/code&gt; is (exactly) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.0/1024&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Binary literals should be used sparingly, for code which cares about bit
manipulation.&lt;/li&gt;
  &lt;li&gt;Consider using digit separators when a numeric literal is too long to take
in at a single glance.&lt;/li&gt;
  &lt;li&gt;When using digit separators, use conventional group sizes:
    &lt;ul&gt;
      &lt;li&gt;For decimal, use groups of three digits unless there is a conflicting
convention (as with some currencies, for example).&lt;/li&gt;
      &lt;li&gt;For binary, prefer groups of four bits (nibble) or eight bits
(octet/byte) unless the digits have a more semantically significant
grouping.&lt;/li&gt;
      &lt;li&gt;For hex, use groups of 2, 4 or 8 hex digits.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;see-also&quot;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;64&quot;&gt;Tip of the Week #64: Raw String Literals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2020-04-06T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/175</link>
          <guid isPermaLink="true">https://abseil.io/tips/175</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #173: Wrapping Arguments in Option Structs</title>
          <description>&lt;p&gt;Originally posted as TotW #173 on December 19, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jbandela@google.com&quot;&gt;John Bandela&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/173&quot;&gt;abseil.io/tips/173&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It came without packages, boxes or bags. And he puzzled and puzzled ‘till his
puzzler was sore.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;-Dr. Seuss&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;designated-initializers&quot;&gt;Designated Initializers&lt;/h2&gt;

&lt;p&gt;Designated initializers are a C++20 feature that is available in most compilers
today. Designated initializers make using option structs easier and safer since
we can construct the options object in the call to the function. This results in
shorter code and avoids a lot of temporary lifetime issues with option structs.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct PrintDoubleOptions {
  absl::string_view prefix = &quot;&quot;;
  int precision = 8;
  char thousands_separator = &apos;,&apos;;
  char decimal_separator = &apos;.&apos;;
  bool scientific = false;
};

void PrintDouble(double value,
                 const PrintDoubleOptions&amp;amp; options = PrintDoubleOptions{});

std::string name = &quot;my_value&quot;;
PrintDouble(5.0, {.prefix = absl::StrCat(name, &quot;=&quot;), .scientific = true});
&lt;/pre&gt;

&lt;p&gt;For more background on why option structs are helpful and the potential pitfalls
in using them that designated initializers help avoid, read on.&lt;/p&gt;

&lt;h2 id=&quot;the-problem-of-passing-many-arguments&quot;&gt;The Problem of Passing Many Arguments&lt;/h2&gt;

&lt;p&gt;Functions that take many arguments can be confusing. To illustrate, let us
consider this function for printing out a floating point value.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void PrintDouble(double value, absl::string_view prefix,  int precision,
                 char thousands_separator, char decimal_separator,
                 bool scientific);

&lt;/pre&gt;

&lt;p&gt;This function provides us a lot of flexibility because it takes so many options.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
PrintDouble(5.0, &quot;my_value=&quot;, 2, &apos;,&apos;, &apos;.&apos;, false);
&lt;/pre&gt;

&lt;p&gt;The above code will print out: “my_value=5.00”.&lt;/p&gt;

&lt;p&gt;However, it is hard to read this code and know to which parameter each argument
corresponds. For instance, here we have inadvertently mixed up the order of our
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;precision&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thousands_separator&lt;/code&gt;.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
PrintDouble(5.0, &quot;my_value=&quot;, &apos;,&apos;, &apos;.&apos;, 2, false);
&lt;/pre&gt;

&lt;p&gt;Historically, we have used
&lt;a href=&quot;http://clang.llvm.org/extra/clang-tidy/checks/bugprone/argument-comment.html&quot;&gt;argument comments&lt;/a&gt;
to clarify argument meanings at call sites to reduce this sort of ambiguity. The
addition of argument comments to the above example would allow ClangTidy to
detect the error:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
PrintDouble(5.0, &quot;my_value=&quot;,
            /*precision=*/2,
            /*thousands_separator=*/&apos;,&apos;,
            /*decimal_separator=*/&apos;.&apos;,
            /*scientific=*/false);
&lt;/pre&gt;

&lt;p&gt;However, argument comments still have several drawbacks:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;No enforcement: ClangTidy warnings are not caught at buildtime. Subtle
errors (e.g. a missing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&lt;/code&gt; sign) can disable the check entirely with no
warning, providing a false sense of security.&lt;/li&gt;
  &lt;li&gt;Availability: not all projects and platforms support ClangTidy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No matter whether your arguments are commented or not, specifying lots of
options can also be tedious. Many times there are sensible defaults for the
options. To address this concern, we can add defaults to the parameters.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void PrintDouble(double value, absl::string_view prefix = &quot;&quot;, int precision = 8,
                 char thousands_separator = &apos;,&apos;, char decimal_separator = &apos;.&apos;,
                 bool scientific = false);
&lt;/pre&gt;

&lt;p&gt;Now we can call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PrintDouble&lt;/code&gt; with less boilerplate.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
PrintDouble(5.0, &quot;my_value=&quot;);

&lt;/pre&gt;

&lt;p&gt;However, if we want to specify a non-default argument for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scientific&lt;/code&gt;, we would
still be forced to specify values for all of the parameters that come before it:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
PrintDouble(5.0, &quot;my_value=&quot;,
            /*precision=*/8,              // unchanged from default
            /*thousands_separator=*/&apos;,&apos;,  // unchanged from default
            /*decimal_separator=*/&apos;.&apos;,    // unchanged from default
            /*scientific=*/true);
&lt;/pre&gt;

&lt;p&gt;We can address all of these issues by grouping all of the options together in an
&lt;em&gt;option struct&lt;/em&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct PrintDoubleOptions {
  absl::string_view prefix = &quot;&quot;;
  int precision = 8;
  char thousands_separator = &apos;,&apos;;
  char decimal_separator = &apos;.&apos;;
  bool scientific = false;
};

void PrintDouble(double value,
                 const PrintDoubleOptions&amp;amp; options = PrintDoubleOptions{});
&lt;/pre&gt;

&lt;p&gt;Now we can have names for our values, as well as flexibly use defaults.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
PrintDoubleOptions options;
options.prefix = &quot;my_value=&quot;;
PrintDouble(5.0, options);
&lt;/pre&gt;

&lt;h2 id=&quot;caveats&quot;&gt;Caveats&lt;/h2&gt;

&lt;p&gt;There are some issues with this solution, though. First is that we now have some
extra boilerplate in passing options, though that’s often a minor cost compared
to the benefits. But there are a few more things to consider.&lt;/p&gt;

&lt;h3 id=&quot;lifetime-of-temporaries&quot;&gt;Lifetime of Temporaries&lt;/h3&gt;

&lt;p&gt;For example, when we took all the options as parameters the following code was
safe:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string name = &quot;my_value&quot;;
PrintDouble(5.0, absl::StrCat(name, &quot;=&quot;));

&lt;/pre&gt;

&lt;p&gt;In the code above, we are creating a temporary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; and binding a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; to that. The temporary lifetime is the duration of the function
call so we are safe, but using an options struct in the same manner, results in
a dangling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
std::string name = &quot;my_value&quot;;
PrintDoubleOptions options;
options.prefix = absl::StrCat(name, &quot;=&quot;);
PrintDouble(5.0, options);
&lt;/pre&gt;

&lt;p&gt;There are two ways we can fix this. The first is to simply change the type of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prefix&lt;/code&gt; from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;. The downside of doing this is that now
the option struct is less efficient than directly passing the arguments. The
other way that we can fix this is to add setter member functions.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class PrintDoubleOptions {
 public:
  PrintDoubleOptions&amp;amp; set_prefix(absl::string_view prefix) {
    prefix_ = prefix;
    return *this;
  }

  absl::string_view prefix() const { return prefix_; }

  // Setters and getters for the other member variables.

 private:
  absl::string_view prefix_ = &quot;&quot;;
  int precision_ = 8;
  char thousands_separator_ = &apos;,&apos;;
  char decimal_separator_ = &apos;.&apos;;
  bool scientific_ = false;
};
&lt;/pre&gt;

&lt;p&gt;This can then be used to set the variables in the call.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string name = &quot;my_value&quot;;
PrintDouble(5.0, PrintDoubleOptions{}.set_prefix(absl::StrCat(name, &quot;=&quot;)));
&lt;/pre&gt;

&lt;p&gt;As you can see, the cost is that our option struct became a more complicated
class with a lot more boilerplate.&lt;/p&gt;

&lt;p&gt;The simpler alternative is to use
&lt;a href=&quot;#designated-initializers&quot;&gt;designated initializers&lt;/a&gt; as shown at the top.&lt;/p&gt;

&lt;h3 id=&quot;type-deduction&quot;&gt;Type Deduction&lt;/h3&gt;

&lt;p&gt;Designated initializers are often used with
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/list_initialization#Copy-list-initialization&quot;&gt;copy list initialization&lt;/a&gt;,
where a brace-enclosed list of initializers doesn’t have an explicit type
specified nearby.&lt;/p&gt;

&lt;p&gt;When directly passing options to a function with the option struct as a
parameter, the braced list is immediately turned into an argument of the
specific type. So, this works well:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
PrintDouble(5.0, {.scientific=true})
&lt;/pre&gt;

&lt;p&gt;But in a function like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&lt;/code&gt; that uses “perfect forwarding”, where
the type of the parameter must be deduced, the braced list’s type cannot be
found. So, this does not work:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
class DoublePrinter {
  explicit DoublePrinter(const PrintDoubleOptions&amp;amp; options);
  ...
};

auto printer1 = std::make_unique&amp;lt;DoublePrinter&amp;gt;({.scientific=true});
&lt;/pre&gt;

&lt;p&gt;The caller must name the option struct’s type, or there must be a helper factory
function that does so.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class DoublePrinter {
  static std::unique_ptr&amp;lt;DoublePrinter&amp;gt; Make(const PrintDoubleOptions&amp;amp; options);
  explicit DoublePrinter(const PrintDoubleOptions&amp;amp; options);
};

auto printer1 = std::make_unique&amp;lt;DoublePrinter&amp;gt;(
    PrintDoubleOptions{.scientific=true});
auto printer2 = DoublePrinter::Make({.scientific=true});
&lt;/pre&gt;

&lt;h3 id=&quot;default-values-in-a-nested-type&quot;&gt;Default Values in a Nested Type&lt;/h3&gt;

&lt;p&gt;If an option struct is associated with a class, it’s often reasonable to nest
the struct within the class.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class DoublePrinter {
  struct Options {
    int precision = 8;
    ...
  };

  explicit DoublePrinter(const Options&amp;amp; options);

  static std::unique_ptr&amp;lt;DoublePrinter&amp;gt; Make(const Options&amp;amp; options);
};
&lt;/pre&gt;

&lt;p&gt;But then if you need to allow the option struct to be skipped entirely, such as
when it’s being added to an existing class, and the nested struct has a default
member initializer (the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;= 8&lt;/code&gt; after the field name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;precision&lt;/code&gt;, for example),
you cannot have a
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Default_Arguments&quot;&gt;default argument&lt;/a&gt;
whose value leaves the field implicit.&lt;/p&gt;

&lt;p&gt;In this case, provide another overload instead of using a default argument.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class DoublePrinter {
  struct Options {
    int precision = 8;
    ...
  };

  static std::unique_ptr&amp;lt;DoublePrinter&amp;gt; Make() { return Make({}); }
  static std::unique_ptr&amp;lt;DoublePrinter&amp;gt; Make(const Options&amp;amp; options);

  explicit DoublePrinter() : DoublePrinter({}) {}
  explicit DoublePrinter(const Options&amp;amp; options);

  // Cannot do this:
  //   static std::unique_ptr&amp;lt;DoublePrinter&amp;gt; Make(const Options&amp;amp; options = {});
  //   explicit DoublePrinter(const Options&amp;amp; options = {});
};
&lt;/pre&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;For functions which take multiple arguments which may be confused by the
caller or where you want to specify default arguments without having to
worry about the order, strongly consider using option structs to increase
both convenience and code clarity.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When calling functions that take option structs, using designated
initializers can result in shorter code as well as potentially avoiding
temporary lifetime issues.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Designated initializers by virtue of their conciseness and clarity further
tip the balance towards preferring functions that take option structs over
those that have many parameters.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;
</description>
          <pubDate>2020-04-06T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/173</link>
          <guid isPermaLink="true">https://abseil.io/tips/173</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #172: Designated Initializers</title>
          <description>&lt;p&gt;Originally posted as TotW #172 on December 11, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jacobsa@google.com&quot;&gt;Aaron Jacobs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/172&quot;&gt;abseil.io/tips/172&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/aggregate_initialization#Designated_initializers&quot;&gt;Designated initializers&lt;/a&gt;
are a syntax in the C++20 standard for specifying the contents of a struct in a
compact yet readable and maintainable manner. Instead of the repetitive&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Point {
  double x;
  double y;
  double z;
};

Point point;
point.x = 3.0;
point.y = 4.0;
point.z = 5.0;
&lt;/pre&gt;

&lt;p&gt;one can use designated initializers to write&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
Point point = {
    .x = 3.0,
    .y = 4.0,
    .z = 5.0,
};
&lt;/pre&gt;

&lt;p&gt;This is a little less repetitive, but more importantly, can be used in more
contexts. For example, it means the struct can be made &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; without resorting
to awkward workarounds:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Make it clear to the reader (of the potentially complicated larger piece of
// code) that this struct will never change.
const Point character_position = { .x = 3.0 };
&lt;/pre&gt;

&lt;p&gt;Or can be used directly in a function call without introducing an additional
identifier into the scope:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::vector&amp;lt;Point&amp;gt; points;
[...]
points.push_back(Point{.x = 3.0, .y = 3.0});
points.push_back(Point{.x = 4.0, .y = 4.0});
&lt;/pre&gt;

&lt;h2 id=&quot;semantics&quot;&gt;Semantics&lt;/h2&gt;

&lt;p&gt;Designated initializers are a form of
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/aggregate_initialization&quot;&gt;aggregate initialization&lt;/a&gt;, and so can be used only
with &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/aggregate_initialization#Explanation&quot;&gt;aggregates&lt;/a&gt;. This means approximately “structs or classes with no
user-provided constructors or virtual functions”, which in turn is approximately
when we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; (as opposed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt;) in typical Google style.&lt;/p&gt;

&lt;p&gt;The semantics of C++20 designated initializers are what you might expect given
other C++ language features like member initialization lists in constructors.
Explicitly mentioned fields are initialized, in order, with the expression
provided, and it is permissible to leave out fields that you want to have
“default” behavior for:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
Point point = {
    .x = 1.0,
    // y will be 0.0
    .z = 2.0,
};
&lt;/pre&gt;

&lt;p&gt;What does “default” mean above? Outside of special cases like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;union&lt;/code&gt;s the
answer is:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If the struct definition contains a default member initializer (i.e. the
field definition looks like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string foo = &quot;default value&quot;;&lt;/code&gt;) then that
is used.&lt;/li&gt;
  &lt;li&gt;Otherwise the field is initialized as if with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;= {}&lt;/code&gt;. In practice this means
that for plain old data types you get the zero value, and for more
complicated classes you get a default-constructed instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is typically the least surprising behavior. See the
&lt;a href=&quot;http://eel.is/c++draft/dcl.init#aggr-5&quot;&gt;standard&lt;/a&gt; for details.&lt;/p&gt;

&lt;h2 id=&quot;some-history-and-language-trivia&quot;&gt;Some History and Language Trivia&lt;/h2&gt;

&lt;p&gt;Designated initializers have been a standard part of the C language since C99,
and have been offered by compilers as a
&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html&quot;&gt;non-standard extension&lt;/a&gt;
since before that. But until recently they were not part of C++: a notable
example where C is not a subset of C++. For this reason the Google style guide
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Nonstandard_Extensions&quot;&gt;used to say not to use them&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After two decades the situation has finally changed: designated initializers are
now &lt;a href=&quot;http://eel.is/c++draft/dcl.init#aggr-3&quot;&gt;part&lt;/a&gt; of the C++20 standard.&lt;/p&gt;

&lt;p&gt;The C++20 form of designated initializers has some restrictions compared to the
C version:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;C++20 requires fields to be listed in the designator in the same order as
they are listed in the struct definition (so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Point{.y = 1.0, .x = 2.0}&lt;/code&gt; is
not legal). C does not require this.&lt;/li&gt;
  &lt;li&gt;C allows you to mix designated and non-designated initializers (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Point{1.0,
.z = 2.0}&lt;/code&gt;), but C++20 does not.&lt;/li&gt;
  &lt;li&gt;C supports a syntax for sparsely initializing arrays known as “array
designators”. This is not part of C++20.&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2020-04-06T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/172</link>
          <guid isPermaLink="true">https://abseil.io/tips/172</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #171: Avoid Sentinel Values</title>
          <description>&lt;p&gt;Originally posted as TotW #171 on November 8, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:hwright@google.com&quot;&gt;Hyrum Wright&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/171&quot;&gt;abseil.io/tips/171&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Sentinel_value&quot;&gt;Sentinel values&lt;/a&gt; are values that
have special meaning in a specific context. For example, consider the following
API:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// Returns the account balance, or -5 if the account has been closed.
int AccountBalance();
&lt;/pre&gt;

&lt;p&gt;Every value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; is documented to be a valid return value for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AccountBalance&lt;/code&gt;, except for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-5&lt;/code&gt;. Intuitively, this feels a bit odd: should
callers only check against &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-5&lt;/code&gt; specifically, or is any negative value a
reliable “account closed” signal? What happens when the system supports negative
balances and the API needs to be adjusted to return negative values?&lt;/p&gt;

&lt;p&gt;Using sentinel values increases the complexity of the calling code. If the
caller is rigorous, it explicitly checks against the sentinel value:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
int balance = AccountBalance();
if (balance == -5) {
  LOG(ERROR) &amp;lt;&amp;lt; &quot;account closed&quot;;
  return;
}
// use `balance` here
&lt;/pre&gt;

&lt;p&gt;Some callers may check against a broader range of values than is specified:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
int balance = AccountBalance();
if (balance &amp;lt;= 0) {
  LOG(ERROR) &amp;lt;&amp;lt; &quot;where is my account?&quot;;
  return;
}
// use `balance` here
&lt;/pre&gt;

&lt;p&gt;And some callers may just ignore the sentinel value altogether, assuming that it
doesn’t actually occur in practice:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
int balance = AccountBalance();
// use `balance` here
&lt;/pre&gt;

&lt;h2 id=&quot;problems-with-sentinel-values&quot;&gt;Problems with Sentinel Values&lt;/h2&gt;

&lt;p&gt;The above example illustrates some of the common problems with using sentinel
values. Others include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Different systems may use different sentinel values, such as a single
negative value, all negative values, an infinite value, or any arbitrary
value. The only way to communicate the special value is through
documentation.&lt;/li&gt;
  &lt;li&gt;The sentinel values are still part of the type’s domain of valid values, so
neither the caller nor the callee is forced by the type system to
acknowledge that a value may be invalid. When code and comments disagree,
both are usually wrong.&lt;/li&gt;
  &lt;li&gt;Sentinel values limit interface evolution, as the specific sentinel may
someday be a valid value for use in that system.&lt;/li&gt;
  &lt;li&gt;One system’s sentinel value is another’s valid value, increasing cognitive
overhead and code complexity when interfacing with multiple systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Forgetting to check for specified sentinel values is a common bug. In the best
case, the use of an unchecked sentinel value will immediately crash the system
during runtime. More frequently, an unchecked sentinel value may continue to
propagate through the system, producing bad results as it goes.&lt;/p&gt;

&lt;h2 id=&quot;use-stdoptional-instead&quot;&gt;Use &lt;code&gt;std::optional&lt;/code&gt; Instead&lt;/h2&gt;

&lt;p&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; to indicate unavailable or invalid information instead of
using special values.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Returns the account balance, or std::nullopt if the account has been closed.
std::optional&amp;lt;int&amp;gt; AccountBalance();
&lt;/pre&gt;

&lt;p&gt;The caller of our new version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AccountBalance()&lt;/code&gt; now must explicitly look
inside the returned value for a potential balance, signalling that the result
might be invalid in the process. Barring additional documentation, the caller
can assume that any valid &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; value can be returned from this function,
without excluding specific sentinel values. This simplification clarifies the
intent of calling code.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::optional&amp;lt;int&amp;gt; balance = AccountBalance();

if (!balance.has_value()) {
  LOG(ERROR) &amp;lt;&amp;lt; &quot;Account doesn&apos;t exist&quot;;
  return;
}
// use `*balance` here
&lt;/pre&gt;

&lt;p&gt;Next time you are tempted to use a sentinel value within your system, strongly
consider using an appropriate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; instead.&lt;/p&gt;

&lt;h2 id=&quot;see-also&quot;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;For more information about using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; to pass values as
parameters, see &lt;a href=&quot;163&quot;&gt;TotW #163&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;For help deciding when to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;,
see &lt;a href=&quot;123&quot;&gt;TotW #123&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2020-04-06T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/171</link>
          <guid isPermaLink="true">https://abseil.io/tips/171</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #163: Passing &lt;code&gt;std::optional&lt;/code&gt; parameters</title>
          <description>&lt;p&gt;Originally posted as TotW #163 on July 11, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:puddles@google.com&quot;&gt;Ian Eldred Pudney&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/163&quot;&gt;abseil.io/tips/163&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Are nulls really a billion-dollar mistake?&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;/h2&gt;

&lt;p&gt;Let’s say you need to implement a function with a parameter that may or may not
exist. You might be tempted to use modern, fancy-schmancy &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; for
this. However, if the object is big enough that it should be passed by
reference, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; is probably not what you want. Consider the following
two declarations:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
void MyFunc(const std::optional&amp;lt;Foo&amp;gt;&amp;amp; foo);  // May copy by value
void MyFunc(std::optional&amp;lt;const Foo&amp;amp;&amp;gt; foo);  // Doesn&apos;t compile
&lt;/pre&gt;

&lt;p&gt;The first option probably doesn’t do what you want. If someone passes a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;Foo&amp;gt;&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyFunc&lt;/code&gt;, it is passed by reference, but if someone
passes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyFunc&lt;/code&gt; (for example as a return value), the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; will be
copied &lt;em&gt;by value&lt;/em&gt; into a temporary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;Foo&amp;gt;&lt;/code&gt;, which will then be
passed by reference into the function. If your goal was to avoid copying the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;, you haven’t.&lt;/p&gt;

&lt;p&gt;The second option would be great, but unfortunately is not supported by
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;recommendation&quot;&gt;Recommendation&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Avoid function parameters of the form &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::optional&amp;amp;&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your object is small enough to not need pass-by-reference, you should take
the object wrapped in an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; by value. For example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void MyFunc(std::optional&amp;lt;int&amp;gt; bar);
void MyFunc(std::optional&amp;lt;absl::string_view&amp;gt; baz);
&lt;/pre&gt;

&lt;p&gt;If you are &lt;em&gt;intentionally&lt;/em&gt; making a copy of the argument, you should also accept
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; by value to make that clear:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void MyFunc(std::optional&amp;lt;Foo&amp;gt; foo);
&lt;/pre&gt;

&lt;p&gt;Otherwise, skip the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; altogether.&lt;/p&gt;

&lt;p&gt;You can pass it by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Nullable&amp;lt;const Foo*&amp;gt;&lt;/code&gt; and let &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nullptr&lt;/code&gt; indicate “does
not exist.”&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void MyFunc(absl::Nullable&amp;lt;const Foo*&amp;gt; foo);
&lt;/pre&gt;

&lt;p&gt;This will be just as efficient as passing by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const Foo&amp;amp;&lt;/code&gt;, but supports null
values. See &lt;a href=&quot;/tips/116&quot;&gt;Tip #116&lt;/a&gt; for more on when to use a pointer instead of a
const reference.&lt;/p&gt;

&lt;h3 id=&quot;then-what-on-earth-is-stdoptional-for&quot;&gt;Then what on Earth is &lt;code&gt;std::optional&lt;/code&gt; for???&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; can be used if you &lt;em&gt;own&lt;/em&gt; the thing that’s optional. For example,
class members and function return values often work well with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;exception&quot;&gt;Exception&lt;/h3&gt;

&lt;p&gt;If you expect all callers of your function to already have a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;Foo&amp;gt;&lt;/code&gt; and never pass in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;, then you may take a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
std::optional&amp;lt;Foo&amp;gt;&amp;amp;&lt;/code&gt;. However, this is rare; it usually only occurs if your
function is private within your own file/library.&lt;/p&gt;

&lt;h3 id=&quot;what-about-stdreference_wrapper&quot;&gt;What about &lt;code&gt;std::reference_wrapper&lt;/code&gt;?&lt;/h3&gt;

&lt;p&gt;The documentation for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt; points out that you can use a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::reference_wrapper&lt;/code&gt; to work around the fact that optional references aren’t
supported:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void MyFunc(std::optional&amp;lt;std::reference_wrapper&amp;lt;const Foo&amp;gt;&amp;gt; foo);
&lt;/pre&gt;

&lt;p&gt;However, we don’t recommend this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::reference_wrapper&lt;/code&gt; has surprisingly subtle semantics, making it
difficult to understand and use safely. For instance, various utilities in
the standard library special case it in ways that make it act differently
from a normal value or reference.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;std::reference_wrapper&amp;lt;const Foo&amp;gt;&amp;gt;&lt;/code&gt; is cumbersome and
verbose, compared to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Nullable&amp;lt;const Foo*&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2020-04-06T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/163</link>
          <guid isPermaLink="true">https://abseil.io/tips/163</guid>
        </item>
      
    
      
        <item>
          <title>Announcing TCMalloc</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto: ckennelly@google.com&quot;&gt;Chris Kennelly&lt;/a&gt;, Google Software Engineer&lt;/p&gt;

&lt;p&gt;We are happy to announce the arrival of TCMalloc, a fast memory allocator with
useful profiling and introspection features.&lt;/p&gt;

&lt;p&gt;The source code can be found &lt;a href=&quot;https://github.com/google/tcmalloc&quot;&gt;on Github&lt;/a&gt;. This is a distinct
repository, allowing Abseil to be used independently of TCMalloc. The library
includes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A lockfree, per-CPU cache implementation based on &lt;a href=&quot;https://blog.linuxplumbersconf.org/2013/ocw/system/presentations/1695/original/LPC%20-%20PerCpu%20Atomics.pdf&quot;&gt;restartable sequences&lt;/a&gt;,
 available on modern Linux kernels, and a per-thread based fallback
 implementation.&lt;/li&gt;
  &lt;li&gt;A hugepage-aware backend that reduces TLB stalls by more densely populating
hugepage subregions while reducing memory waste.&lt;/li&gt;
  &lt;li&gt;Optimizations leveraging modern C++ language features, including sized
delete from C++14 and overaligned allocation from C++17.&lt;/li&gt;
  &lt;li&gt;Always-on, sampling-based heap profiling, allowing an application to obtain
a heap profile without additional configuration. We also provide a “peak
heap” profile, a snapshot of the application’s memory usage near its high
watermark of usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;!--break--&gt;

&lt;p&gt;This blog post covers getting started and a peek at one of our key optimization
techniques: per-CPU caches. For a more detailed explanation of the design of
TCMalloc and its features, take a look at our &lt;a href=&quot;https://google.github.io/tcmalloc/design&quot;&gt;design note&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;

&lt;p&gt;Adding TCMalloc to a binary involves specifying it as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt; attribute of
a Bazel &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cc_binary&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cc_test&lt;/code&gt; rule. For example, with
&lt;a href=&quot;https://github.com/abseil/abseil-hello&quot;&gt;Abseil hello&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cc_binary(
  name = &quot;hello_main&quot;,
  srcs = [&quot;hello_main.cc&quot;],
  deps = [
    &quot;:hello&quot;,
  ],
  malloc = &quot;@com_google_tcmalloc//tcmalloc&quot;,
)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can also leverage the telemetry TCMalloc provides into our
heap with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MallocExtension&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include “tcmalloc/malloc_extension.h”

int main(int argc, char** argv) { 
  absl::optional&amp;lt;size_t&amp;gt; heap_size =
    tcmalloc::MallocExtension::GetNumericProperty(
      &quot;generic.current_allocated_bytes&quot;);
  if (heap_size.has_value()) {
    std::cout &amp;lt;&amp;lt; &quot;heap size = &quot; &amp;lt;&amp;lt; *heap_size &amp;lt;&amp;lt; &quot; bytes&quot; &amp;lt;&amp;lt; std::endl;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MallocExtension&lt;/code&gt; is a separate library from TCMalloc, allowing it to be
used when another malloc implementation is linked-in, for example, when
using C++ sanitizers. The library is crafted so that although the
telemetry and controls it provides will be inoperative, the code using
it will still link and compile.&lt;/p&gt;

&lt;h2 id=&quot;key-optimizations-per-cpu-caches&quot;&gt;Key Optimizations: Per-CPU Caches&lt;/h2&gt;

&lt;p&gt;TCMalloc’s name comes from “thread caching” malloc. These caches allow us
to allocate memory most of the time without taking locks, falling back to
a more centralized cache when the thread cache is exhausted or full.&lt;/p&gt;

&lt;p&gt;The cost of per-thread caches has increased as thread counts in applications
have grown. Because we do not allow one thread to access another’s thread
cache, to avoid locks, we need to carefully balance between ensuring a cache
is large enough to hold needed objects and avoiding stranding memory in an
idle cache. Objects held by idle threads are effectively wasted.&lt;/p&gt;

&lt;p&gt;Our per-CPU caches take advantage of the fact that only one thread can run
on a single core at any given time and that pre-emptions during the critical
sequence of an allocation are relatively rare. These caches are based on the
Linux kernel’s &lt;a href=&quot;https://blog.linuxplumbersconf.org/2013/ocw/system/presentations/1695/original/LPC%20-%20PerCpu%20Atomics.pdf&quot;&gt;restartable sequences (RSEQ)&lt;/a&gt; feature, developed by
Paul Turner and Andrew Hunter at Google and Mathieu Desnoyers at EfficiOS.
Restartable sequences let us execute a region of code atomically and restart
if we are interrupted by the kernel.&lt;/p&gt;

&lt;p&gt;RSEQ allows us to share a cache across many interleaving threads of execution,
improving the usefulness of the cache. When one thread is idle, another thread
can still allocate from the core’s cache. Additionally, because the number of
caches is bounded by the total number of cpus, we can allocate an array-based
metadata structure for each cache. This allows us to reduce memory indirections,
common in the linked-list data structures we use for our thread-cache
implementation.&lt;/p&gt;

&lt;p&gt;For systems without this feature, we fall back to a per-thread cache
implementation.&lt;/p&gt;

&lt;h2 id=&quot;more-information&quot;&gt;More Information&lt;/h2&gt;

&lt;p&gt;For more information, consult the following documentation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;a href=&quot;https://google.github.io/tcmalloc/quickstart&quot;&gt;TCMalloc Quickstart&lt;/a&gt;, which covers downloading, installing
and running the TCMalloc code. contains updated links to all documentation&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://google.github.io/tcmalloc/overview&quot;&gt;TCMalloc Overview&lt;/a&gt;, for a basic overview of TCMalloc usage
and configuration&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://google.github.io/tcmalloc/reference&quot;&gt;TCMalloc API Reference&lt;/a&gt;, for complete usage information for
our implementations of C and C++ API endpoints such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;free()&lt;/code&gt;,
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::operator new&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://google.github.io/tcmalloc/tuning&quot;&gt;TCMalloc Tuning Guide&lt;/a&gt;, for more complete information on
selecting a proper configuration, and tuning certain aspects of TCMalloc.&lt;/li&gt;
&lt;/ul&gt;

</description>
          <pubDate>2020-02-12T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/20200212-tcmalloc</link>
          <guid isPermaLink="true">https://abseil.io/blog/20200212-tcmalloc</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #108: Avoid &lt;code&gt;std::bind&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #108 on January 7, 2016&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:roman.perepelitsa@gmail.com&quot;&gt;Roman Perepelitsa&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-08-19&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/108&quot;&gt;abseil.io/tips/108&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;avoid-stdbind&quot;&gt;Avoid &lt;code&gt;std::bind&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;This Tip summarizes reasons why you should stay away from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; when
writing code.&lt;/p&gt;

&lt;p&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; correctly is hard. Let’s look at a few examples. Does this
code look good to you?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void DoStuffAsync(std::function&amp;lt;void(absl::Status)&amp;gt; cb);

class MyClass {
  void Start() {
    DoStuffAsync(std::bind(&amp;amp;MyClass::OnDone, this));
  }
  void OnDone(absl::Status status);
};
&lt;/pre&gt;

&lt;p&gt;Many seasoned C++ engineers have written code like this only to find that it
doesn’t compile. It works with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::function&amp;lt;void()&amp;gt;&lt;/code&gt; but breaks when you add
an extra parameter to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyClass::OnDone&lt;/code&gt;. What gives?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; doesn’t just bind the first N arguments&lt;/strong&gt; like many C++
engineers expect (this is called
&lt;a href=&quot;https://en.wikipedia.org/wiki/Partial_application&quot;&gt;partial function application&lt;/a&gt;).
You must instead specify every argument, so the correct incantation of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; is this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::bind(&amp;amp;MyClass::OnDone, this, std::placeholders::_1)
&lt;/pre&gt;

&lt;p&gt;Ugh, that’s ugly. Is there a better way? Why yes, use
&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/functional/bind_front&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind_front()&lt;/code&gt;&lt;/a&gt;
instead. (For code that cannot yet use C++20, there’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::bind_front&lt;/code&gt;.)&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::bind_front(&amp;amp;MyClass::OnDone, this)
&lt;/pre&gt;

&lt;p&gt;Remember partial function application – the thing that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; &lt;em&gt;does not
do&lt;/em&gt;? Well, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind_front()&lt;/code&gt; does exactly that: it binds the first N arguments
and perfect-forwards the rest: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind_front(F, a, b)(x, y)&lt;/code&gt; evaluates to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F(a, b, x, y)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ahhh, sanity is restored. Want to see something truly terrifying now? What does
this code do?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void DoStuffAsync(std::function&amp;lt;void(absl::Status)&amp;gt; cb);

class MyClass {
  void Start() {
    DoStuffAsync(std::bind(&amp;amp;MyClass::OnDone, this));
  }
  void OnDone();  // No absl::Status here.
};
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OnDone()&lt;/code&gt; takes no parameters, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoStuffAsync()&lt;/code&gt; callback should take a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Status&lt;/code&gt;. You might expect a compile error here but this code actually
compiles without warnings, because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind&lt;/code&gt; over-aggressively bridges the
gap. Potential errors from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoStuffAsync()&lt;/code&gt; get silently ignored.&lt;/p&gt;

&lt;p&gt;Code like this can cause serious damage. Thinking that some IO has succeeded
when it actually hasn’t can be devastating. Perhaps the author of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyClass&lt;/code&gt;
didn’t realize that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoStuffAsync()&lt;/code&gt; may produce an error that needs to be
handled. Or maybe &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoStuffAsync()&lt;/code&gt; used to accept &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::function&amp;lt;void()&amp;gt;&lt;/code&gt; and
then its author decided to introduce the error mode and updated all callers that
stopped compiling. Either way the bug made its way into production code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; disables one of the basic compile time checks&lt;/strong&gt; that we all rely
on. The compiler usually tells you if the caller is passing more arguments than
you expect, but not for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt;. Terrifying enough?&lt;/p&gt;

&lt;p&gt;Another example. What do you think of this one?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void Process(std::unique_ptr&amp;lt;Request&amp;gt; req);

void ProcessAsync(std::unique_ptr&amp;lt;Request&amp;gt; req) {
  thread::DefaultQueue()-&amp;gt;Add(
      ToCallback(std::bind(&amp;amp;MyClass::Process, this, std::move(req))));
}
&lt;/pre&gt;

&lt;p&gt;Good old passing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; across async boundaries. Needless to say,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; isn’t a solution – the code doesn’t compile, because
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; doesn’t move the bound move-only argument to the target function.
Simply replacing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind_front()&lt;/code&gt; fixes it.&lt;/p&gt;

&lt;p&gt;The next example regularly trips even C++ experts. See if you can find the
problem.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// F must be callable without arguments.
template &amp;lt;class F&amp;gt;
void DoStuffAsync(F cb) {
  auto DoStuffAndNotify = [](F cb) {
    DoStuff();
    cb();
  };
  thread::DefaultQueue()-&amp;gt;Schedule(std::bind(DoStuffAndNotify, cb));
}

class MyClass {
  void Start() {
    DoStuffAsync(std::bind(&amp;amp;MyClass::OnDone, this));
  }
  void OnDone();
};
&lt;/pre&gt;

&lt;p&gt;This doesn’t compile because &lt;strong&gt;passing the result of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; to another
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; is a special case&lt;/strong&gt;. Normally, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind(F, arg)()&lt;/code&gt; evaluates to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F(arg)&lt;/code&gt;, &lt;em&gt;except&lt;/em&gt; when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arg&lt;/code&gt; is the result of another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; call, in
which case it evaluates to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F(arg())&lt;/code&gt;. If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arg&lt;/code&gt; is converted to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::function&amp;lt;void()&amp;gt;&lt;/code&gt;, the magic behavior is lost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applying std::bind() to a type you don’t control is always a bug&lt;/strong&gt;.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoStuffAsync()&lt;/code&gt; shouldn’t apply &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; to the template argument. Either
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind_front()&lt;/code&gt; or lambda would work fine.&lt;/p&gt;

&lt;p&gt;The author of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoStuffAsync()&lt;/code&gt; might even have entirely green tests because they
always pass a lambda or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::function&lt;/code&gt; as the argument but never the result of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt;. The author of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyClass&lt;/code&gt; will be puzzled when hitting on this bug.&lt;/p&gt;

&lt;p&gt;Is this special case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; ever useful? Not really. It only gets in
the way. If you are composing functions by writing nested &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; calls,
you really should write a lambda or a named function instead.&lt;/p&gt;

&lt;p&gt;Hopefully you are convinced that it’s easy to go wrong with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt;.
Runtime and compile time traps are easy to fall into both for newcomers and C++
experts. Now I’ll try to show that even when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; is used correctly,
there is usually another option that is more readable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; without placeholders are better off as lambdas.&lt;/strong&gt;&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::bind(&amp;amp;MyClass::OnDone, this)
&lt;/pre&gt;

&lt;p&gt;vs&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
[this]() { OnDone(); }
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Calls to std::bind() that perform partial application are better off as
std::bind_front().&lt;/strong&gt; The more placeholders you have, the more obvious it gets.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::bind(&amp;amp;MyClass::OnDone, this, std::placeholders::_1)
&lt;/pre&gt;

&lt;p&gt;vs&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::bind_front(&amp;amp;MyClass::OnDone, this)
&lt;/pre&gt;

&lt;p&gt;(Whether to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind_front()&lt;/code&gt; or a lambda when performing partial function
application is a judgement call; use your discretion.)&lt;/p&gt;

&lt;p&gt;This covers 99% of all calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt;. The remaining calls do something
fancy:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ignore some of the arguments: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind(F, _2)&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Use the same argument more than once: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind(F, _1, _1)&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Bind arguments at the end: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind(F, _1, 42)&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Change argument order: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind(F, _2, _1)&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Use function composition: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind(F, std::bind(G))&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These advanced uses may have their place. Before resorting to them, consider all
known issues with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind()&lt;/code&gt; and ask yourself whether the potential savings
of a few characters or lines of code are worth it.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Avoid &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind&lt;/code&gt;. Use a lambda or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind_front&lt;/code&gt; instead.&lt;/p&gt;

&lt;h3 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h3&gt;

&lt;p&gt;&apos;’Effective Modern C++’’, Item 34: Prefer lambdas to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::bind&lt;/code&gt;.&lt;/p&gt;
</description>
          <pubDate>2019-12-19T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/108</link>
          <guid isPermaLink="true">https://abseil.io/tips/108</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #166: When a Copy is not a Copy</title>
          <description>&lt;p&gt;Originally posted as TotW #166 on August 28, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:richardsmith@google.com&quot;&gt;Richard Smith&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/166&quot;&gt;abseil.io/tips/166&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Entia non sunt multiplicanda praeter necessitatem.” (“Entities should not be
multiplied without necessity”) – William of Ockham&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“If you don’t know where you’re going, you’re probably going wrong.” – Terry
Pratchett&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;p&gt;Starting in C++17, objects are created “in place” when possible.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class BigExpensiveThing {
 public:
  static BigExpensiveThing Make() {
    // ...
    return BigExpensiveThing();
  }
  // ...
 private:
  BigExpensiveThing();
  std::array&amp;lt;OtherThing, 12345&amp;gt; data_;
};

BigExpensiveThing MakeAThing() {
  return BigExpensiveThing::Make();
}

void UseTheThing() {
  BigExpensiveThing thing = MakeAThing();
  // ...
}
&lt;/pre&gt;

&lt;p&gt;How many times does this copy or move a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BigExpensiveThing&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Prior to C++17, the answer was &lt;a href=&quot;/tips/117&quot;&gt;up to&lt;/a&gt; three: one for each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt;
statement, and one more when initializing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thing&lt;/code&gt;. This makes some sense: each
function potentially puts the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BigExpensiveThing&lt;/code&gt; in a different place, so a
move may be needed in order to put the value where the ultimate caller wants it.
In practice, however, the object was always constructed “in place” in the
variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thing&lt;/code&gt;, with no moves being performed, and the C++ language rules
permitted these move operations to be “elided” to facilitate this optimization.&lt;/p&gt;

&lt;p&gt;Since C++17, this code is guaranteed to perform zero copies or moves. In fact,
the above code is valid even if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BigExpensiveThing&lt;/code&gt; is not moveable. The
constructor call in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BigExpensiveThing::Make&lt;/code&gt; directly constructs the local
variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thing&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UseTheThing&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So what’s going on?&lt;/p&gt;

&lt;p&gt;When the compiler sees an expression like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BigExpensiveThing()&lt;/code&gt;, it does not
immediately create a temporary object. Instead, it treats that expression as
instructions for how to initialize some eventual object, but defers creating
(formally, “materializing”) a temporary object for as long as possible.&lt;/p&gt;

&lt;p&gt;Generally, creation of an object is deferred until the object is given a name.
The named object (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thing&lt;/code&gt; in the above example) is directly initialized using
the instructions found by evaluating the initializer. If the name is a
reference, a temporary object will be materialized to hold the value.&lt;/p&gt;

&lt;p&gt;As a consequence, objects are constructed directly in the right place, instead
of being constructed somewhere else and then copied. This behavior is sometimes
referred to as “guaranteed copy elision”, but that’s inaccurate: there was never
a copy in the first place.&lt;/p&gt;

&lt;p&gt;All you need to know is: objects are not copied until after they are first given
a name. There is no extra cost in returning by value.&lt;/p&gt;

&lt;p&gt;(Even after being given a name, local variables might still not be copied when
returned from a function, due to the Named Return Value Optimization. See
&lt;a href=&quot;/tips/11&quot;&gt;Tip 11&lt;/a&gt; for details.)&lt;/p&gt;

&lt;h2 id=&quot;gritty-details-when-unnamed-objects-are-copied&quot;&gt;Gritty Details: When Unnamed Objects Are Copied&lt;/h2&gt;

&lt;p&gt;There are two corner cases where a use of an object with no name results in a
copy anyway:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Constructing base classes: in the base class initializer list of a
constructor, copies will be made even when constructing from an unnamed
expression of the base class type. This is because classes may have a
somewhat different layout and representation when used as base classes (due
to virtual base classes and vpointer values), so initializing base classes
directly may not result in a correct representation.&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
class DerivedThing : public BigExpensiveThing {
 public:
  DerivedThing() : BigExpensiveThing(MakeAThing()) {}  // might copy data_
};
&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;Passing or returning small trivial objects: when a sufficiently small object
that is trivially copyable is passed to or returned from a function, it may
be passed in registers, and hence may have a different address before and
after it is passed.&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
struct Strange {
  int n;
  int *p = &amp;n;
};
void f(Strange s) {
  CHECK(s.p == &amp;amp;s.n);  // might fail
}
void g() { f(Strange{0}); }
&lt;/pre&gt;

&lt;h2 id=&quot;gritty-details-value-category&quot;&gt;Gritty Details: Value Category&lt;/h2&gt;

&lt;p&gt;There are two flavors of expression in C++:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Those that produce a value, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MakeAThing()&lt;/code&gt; – expressions
that you might consider to have a non-reference type.&lt;/li&gt;
  &lt;li&gt;Those that produce the location of some existing object, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thing.data_[5]&lt;/code&gt; – expressions that you might consider to have a reference
type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This division is called the “value category”; the former are &lt;em&gt;prvalues&lt;/em&gt; and the
latter are &lt;em&gt;glvalues&lt;/em&gt;. When we talked about objects without a name above, what
we were really referring to was prvalue expressions.&lt;/p&gt;

&lt;p&gt;All prvalue expressions are evaluated in some context that determines where they
put their value, and the execution of the prvalue expression initializes that
location with its value.&lt;/p&gt;

&lt;p&gt;For example, in&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
  BigExpensiveThing thing = MakeAThing();
&lt;/pre&gt;

&lt;p&gt;the prvalue expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MakeAThing()&lt;/code&gt; is evaluated as the initializer of the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thing&lt;/code&gt; variable, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MakeAThing()&lt;/code&gt; will directly initialize &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thing&lt;/code&gt;. The
constructor passes a pointer to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thing&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MakeAThing()&lt;/code&gt;, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt;
statement in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MakeAThing()&lt;/code&gt; initializes whatever the pointer points to.
Similarly, in&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
  return BigExpensiveThing();
&lt;/pre&gt;

&lt;p&gt;the compiler has a pointer to an object to initialize, and initializes that
object directly by calling the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BigExpensiveThing&lt;/code&gt; constructor.&lt;/p&gt;

&lt;h2 id=&quot;related-reading&quot;&gt;Related Reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/11&quot;&gt;Tip #11: Return Policy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/24&quot;&gt;Tip #24: Copies, Abbrv.&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/77&quot;&gt;Tip #77: Temporaries, moves, and copies&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/117&quot;&gt;Tip #117: Copy Elision and Pass-by-Value&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2019-12-12T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/166</link>
          <guid isPermaLink="true">https://abseil.io/tips/166</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #146: Default vs Value Initialization</title>
          <description>&lt;p&gt;Originally posted as TotW #146 on April 19, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:dominic@google.com&quot;&gt;Dominic Hamon&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/146&quot;&gt;abseil.io/tips/146&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“The road to success is always under construction.” –
&lt;a href=&quot;https://en.wikipedia.org/wiki/Lily_Tomlin&quot;&gt;Lily Tomlin&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;p&gt;For safety and readability, you should assume scalar objects are not initialized
to a reasonable value until they have been explicitly set to a value. Use of
initializers can ensure that scalar values are initialized to safe values.&lt;/p&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;When objects are created, they may be initialized or uninitialized.
Uninitialized objects are not safe to read, but understanding when the object is
uninitialized is not trivial.&lt;/p&gt;

&lt;p&gt;The first thing to understand is if the type under construction is scalar,
aggregate, or some other type. A &lt;em&gt;scalar&lt;/em&gt; type can be thought of as a simple
type: an integral or floating point arithmetic object; a pointer; an enum; a
pointer-to-member; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nullptr_t&lt;/code&gt;. An &lt;em&gt;aggregate&lt;/em&gt; type is an array or a class with
nothing virtual, no non-public fields or bases, and no constructor declarations.&lt;/p&gt;

&lt;p&gt;Another factor affecting whether an instance has been initialized to a value
that is safe to read is whether it has an explicit &lt;em&gt;initializer&lt;/em&gt;. That is, the
object name in the statement is followed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{}&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;= {}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As these rules are not intuitive, the easiest rule to remember to ensure an
object is initialized is to provide an initializer. This is called
&lt;em&gt;value-initialization&lt;/em&gt; and is distinct from &lt;em&gt;default-initialization&lt;/em&gt;, which is
what the compiler will perform otherwise for scalar and aggregate types.&lt;/p&gt;

&lt;h2 id=&quot;user-provided-constructors&quot;&gt;User-Provided Constructors&lt;/h2&gt;

&lt;p&gt;If a type is defined with a user-defined constructor, it is not an aggregate
type, and initialization gets much simpler with both value- and
default-initialization invoking the constructor:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Foo {
  Foo() : v() {}

  int v;
  std::string s;
};

int main() {
  Foo default_foo;
  Foo value_foo = {};
  ...
}
&lt;/pre&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;= {}&lt;/code&gt; triggers value-initialization of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_foo&lt;/code&gt;, which calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;’s
default constructor. After, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; is safe to read, because the constructor’s
initializer list value-initializes it. In fact, as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; does not have a class
type, this is a special case of value-initialization called
&lt;em&gt;zero-initialization&lt;/em&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_foo.v&lt;/code&gt; will have the value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Similarly, while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default_foo&lt;/code&gt; is default-initialized, it calls the same
constructor, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default_foo.v&lt;/code&gt; is also zero-initialized and is safe to read.&lt;/p&gt;

&lt;p&gt;Note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo::s&lt;/code&gt; has a user-provided constructor, so it is value-initialized
in either case, and safe to read.&lt;/p&gt;

&lt;h2 id=&quot;user-declared-vs-user-provided-constructors&quot;&gt;User-Declared vs User-Provided Constructors&lt;/h2&gt;

&lt;p&gt;It is possible for the user to &lt;em&gt;declare&lt;/em&gt; a constructor while asking the compiler
to &lt;em&gt;provide&lt;/em&gt; the definition via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt;. For example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Foo {
  Foo() = default; // &quot;User-declared&quot;, NOT &quot;user-provided&quot;.

  int v;
};

int main() {
  Foo default_foo;
  Foo value_foo = {};
}
&lt;/pre&gt;

&lt;p&gt;In this case, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; defines a &lt;em&gt;user-declared&lt;/em&gt;, but not &lt;em&gt;user-provided&lt;/em&gt;,
constructor. While this type will not be an aggregate, members will be
initialized as if for an aggregate. This means that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default_foo.v&lt;/code&gt; will be
uninitialized, while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_foo.v&lt;/code&gt; will be &lt;em&gt;zero-initialized&lt;/em&gt;. Note that
“user-declared” only applies to a default constructor which is defaulted (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=
default&lt;/code&gt;) &lt;em&gt;at its point of declaration&lt;/em&gt;. A defaulted out-of-line
&lt;em&gt;implementation&lt;/em&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo::Foo() = default&lt;/code&gt;) is considered user-provided and will
behave equivalently to a definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo::Foo() {}&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;uninitialized-members-in-user-provided-constructors&quot;&gt;Uninitialized Members in User-Provided Constructors&lt;/h3&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Foo {
  Foo() {}

  int v;
};

int main() {
  Foo foo = {};
}
&lt;/pre&gt;

&lt;p&gt;In this case, although &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; has a user-provided constructor, it fails to
initialize &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt;. In this case, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; is once more default-initialized, which means
its value is undetermined, and it is unsafe to read.&lt;/p&gt;

&lt;h3 id=&quot;explicit-value-initialization&quot;&gt;Explicit Value-Initialization&lt;/h3&gt;

&lt;p&gt;In general, it is a good idea to replace the initializer with an explicit
initialization to a value, even if that value is 0, for the benefit of the
reader. This is called &lt;em&gt;direct-initialization&lt;/em&gt;, which is a more specific form of
value-initialization.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Foo {
  Foo() : v(0) {}

  int v;
};
&lt;/pre&gt;

&lt;h2 id=&quot;default-member-initialization&quot;&gt;Default Member Initialization&lt;/h2&gt;

&lt;p&gt;A simpler solution than defining constructors for classes, while still avoiding
the pitfalls of default- vs value-initialization, is to initialize members of
classes at declaration, wherever possible:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Foo {
  int v = 0;
};
&lt;/pre&gt;

&lt;p&gt;This ensures that no matter how the instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; is constructed, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; will
be initialized to a determinate value.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Default member initialization&lt;/em&gt; also serves as documentation, especially in the
case of booleans, or non-zero initial values, as to what is a safe initial value
for the member.&lt;/p&gt;

&lt;h2 id=&quot;pro-tip-scalar-zero-initialization&quot;&gt;Pro Tip: Scalar Zero-Initialization&lt;/h2&gt;

&lt;p&gt;The full set of rules for when scalar values are safe to read after
initialization:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The type is followed by an explicit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{}&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;= {}&lt;/code&gt; initializer.&lt;/li&gt;
  &lt;li&gt;The instance of the type under construction is an element of an array with
an initializer as above. E.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new int[10]()&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;The instance of the type under construction is a member of a class with a
disabled default constructor, and the instance of the outer object is
value-initialized.&lt;/li&gt;
  &lt;li&gt;The instance of the type under construction is static or thread-local.&lt;/li&gt;
  &lt;li&gt;The instance of the type under construction is a member of a class with an
aggregate type that has an initializer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;array-types&quot;&gt;Array Types&lt;/h3&gt;

&lt;p&gt;It’s easy to forget to add an explicit initializer to array declarations, but
this can lead to particularly pernicious initialization issues.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
int main() {
  int foo[3];
  int bar[3] = {};
  ...
}
&lt;/pre&gt;

&lt;p&gt;Every element of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; is default-initialized, while every element of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar&lt;/code&gt; will
be zero-initialized.&lt;/p&gt;

&lt;h2 id=&quot;a-digression-discerning-defaulted-default-constructor-declarations&quot;&gt;A Digression Discerning Defaulted Default Constructor Declarations&lt;/h2&gt;

&lt;p&gt;Pop quiz: Do these stylistically different declarations affect the behaviour of
the code?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Foo {
  Foo() = default;

  int v;
};

struct Bar {
  Bar();

  int v;
};

Bar::Bar() = default;

int main() {
  Foo f = {};
  Bar b = {};
  ...
}
&lt;/pre&gt;

&lt;p&gt;Many developers would reasonably assume that this may affect code generation
quality, but otherwise is a style preference. As you might have guessed, because
I’m asking, this is not the case.&lt;/p&gt;

&lt;p&gt;The reason goes back to the section above on
&lt;a href=&quot;#user-declared-vs-user-provided-constructors&quot;&gt;User-Declared vs User-Provided Constructors&lt;/a&gt;.
As the constructor for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; is defaulted on declaration, it is not
user-provided (but it &lt;em&gt;is&lt;/em&gt; user-declared). This means that while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; is not an
aggregate type, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f.v&lt;/code&gt; is still zero-initialized. However, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; has a
user-provided constructor, albeit created by the compiler as a defaulted
constructor. As this constructor does not explicitly initialize &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar::v&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b.v&lt;/code&gt;
will be default-initialized and unsafe to read.&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Be explicit about the value to which scalar types are being initialized
instead of relying on zero-initialization.&lt;/li&gt;
  &lt;li&gt;Treat all instances of scalar types as having indeterminate values until you
explicitly initialize or assign to them.&lt;/li&gt;
  &lt;li&gt;If a member has a sensible default, and the class has multiple constructors,
use a default member initializer to ensure it isn’t left uninitialized. Be
aware that
&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/data_members&quot;&gt;a member initializer within a constructor will override the default&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/61&quot;&gt;Tip #61&lt;/a&gt;: Default Member Initializers&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/88&quot;&gt;Tip #88&lt;/a&gt;: Initialization: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;()&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{}&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/131&quot;&gt;Tip #131&lt;/a&gt;: Special member functions and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/initialization&quot;&gt;CppReference - Initialization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2019-12-12T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/146</link>
          <guid isPermaLink="true">https://abseil.io/tips/146</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #168: &lt;code&gt;inline&lt;/code&gt; Variables</title>
          <description>&lt;p&gt;Originally posted as TotW #168 on September 12, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;James Dennett&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/168&quot;&gt;abseil.io/tips/168&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s one safe way to define a string constant in a header file with C++17’s
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; variables.:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
inline constexpr absl::string_view kHelloWorld = &quot;Hello World.&quot;;
&lt;/pre&gt;

&lt;p&gt;Safety of initialization and destruction is ensured by the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt;,
and using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; here ensures that there is only one copy of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kHelloWorld&lt;/code&gt; in
the program.&lt;/p&gt;

&lt;p&gt;Using the keyword &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; here may seem strange at first, particularly if you
are used to thinking of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; as being primarily an optimization hint. The
use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; for functions in headers is a close analogy; compare the
variable definition above to something like&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
inline constexpr absl::string_view HelloWorld() {
  return &quot;Hello World.&quot;;
}
&lt;/pre&gt;

&lt;p&gt;but with the advantage that the string is guaranteed to be at the same memory
address every time.&lt;/p&gt;

&lt;p&gt;Almost every global variable defined in a header file should be marked as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; – and should generally be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; too. If they are not marked as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; then there will be a separate instance of the variable for each .cc
file that includes the header, which can lead to subtle violations of the ODR
(one definition rule).&lt;/p&gt;

&lt;p&gt;Outside of header files there is no need to mark variables as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note: A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static constexpr&lt;/code&gt; data member of a class is &lt;em&gt;implicitly&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; from
C++17. This special case does not change the semantics of existing code, but
means that it is now unnecessary to provide a separate definition for the member
in a source file. This applies &lt;em&gt;only&lt;/em&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static constexpr&lt;/code&gt; data members, not to
other &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; variables, and not to data members that are merely &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static
const&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables&quot;&gt;Google C++ Style Guide - Static and Global Variables&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2019-11-25T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/168</link>
          <guid isPermaLink="true">https://abseil.io/tips/168</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #161: Good Locals and Bad Locals</title>
          <description>&lt;p&gt;Originally posted as TotW #161 on April 16, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;James Dennett&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/161&quot;&gt;abseil.io/tips/161&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We may freak out globally, but we suffer locally. – Jonathan Franzen&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;synopsis&quot;&gt;Synopsis&lt;/h2&gt;

&lt;p&gt;Local variables are great, but can be overused. We can often simplify code by
restricting their use to situations in which they provide a specific benefit.&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;p&gt;Use local variables only when one or more of the following applies:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Their name adds useful documentation.&lt;/li&gt;
  &lt;li&gt;They simplify excessively complicated expressions.&lt;/li&gt;
  &lt;li&gt;They factor out a repeated expression to make it clear to humans (and to a
lesser extent compilers) that it’s the same value every time.&lt;/li&gt;
  &lt;li&gt;An object’s lifetime needs to extend across multiple statements (for
example, because references to the object are retained beyond the end of a
single statement or because the variable holds a value that is updated
during its lifetime).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other cases, consider removing a layer of indirection by eliminating the
local variable and writing the expression directly where it’s used.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;Naming values adds a level of indirection to code comprehension unless the
variable’s name fully captures the relevant aspects of its meaning. Giving a
name to a value in C++ also exposes it to the rest of the scope. It also affects
the “value category”, as every named variable is an lvalue even if declared as
an rvalue reference and initialized from an rvalue. This can require additional
uses of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move&lt;/code&gt;, which warrant care during code review to avoid
use-after-move bugs. Given these downsides, use of local variables is best
reserved for situations in which it provides a specific benefit.&lt;/p&gt;

&lt;h2 id=&quot;examples-bad-uses-of-local-variables&quot;&gt;Examples: Bad Uses of Local Variables&lt;/h2&gt;

&lt;h4 id=&quot;eliminating-a-local-variable-thats-immediately-returned&quot;&gt;Eliminating a Local Variable That’s Immediately Returned&lt;/h4&gt;

&lt;p&gt;As a simple example of eliminating an unhelpful local variable, instead of&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
MyType value = SomeExpression(args);
return value;
&lt;/pre&gt;

&lt;p&gt;prefer&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
return SomeExpression(args);
&lt;/pre&gt;

&lt;h4 id=&quot;inline-expressions-under-test-into-googletests-expect_that&quot;&gt;Inline Expressions Under Test Into GoogleTest’s &lt;code&gt;EXPECT_THAT&lt;/code&gt;&lt;/h4&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
std::vector&amp;lt;string&amp;gt; actual = SortedAges(args);
EXPECT_THAT(actual, ElementsAre(21, 42, 63));
&lt;/pre&gt;

&lt;p&gt;Here the variable name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;actual&lt;/code&gt; doesn’t add anything useful (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPECT_THAT&lt;/code&gt;
always takes the actual value as its first argument), it’s not simplifying a
complicated expression, and its value is used once only. Inlining the expression
as in&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
EXPECT_THAT(SortedAges(args), ElementsAre(21, 42, 63));
&lt;/pre&gt;

&lt;p&gt;makes it clear at a glance what’s being tested, and by avoiding giving a name to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;actual&lt;/code&gt; ensures that it cannot be unintentionally re-used. It also allows the
testing framework to show the failing call in error output.&lt;/p&gt;

&lt;p&gt;Note: the shorter version hides the expected type of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SortedAges&lt;/code&gt;. If verifying
the type is important, consider declaring a variable in order to show its type.&lt;/p&gt;

&lt;h4 id=&quot;use-matchers-to-eliminate-variables-in-tests&quot;&gt;Use Matchers to Eliminate Variables in Tests.&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/google/googletest/blob/master/docs/reference/matchers.md&quot;&gt;Matchers&lt;/a&gt;
can help to avoid the need to name local variables in tests by allowing
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPECT_THAT&lt;/code&gt; to directly express everything we expect of a value. Instead of
writing code like this&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
std::optional&amp;lt;std::vector&amp;lt;int&amp;gt;&amp;gt; maybe_ages = GetAges(args);
ASSERT_NE(maybe_ages, std::nullopt);
std::vector&amp;lt;int&amp;gt; ages = maybe_ages.value();
ASSERT_EQ(ages.size(), 3);
EXPECT_EQ(ages[0], 21);
EXPECT_EQ(ages[1], 42);
EXPECT_EQ(ages[2], 63);
&lt;/pre&gt;

&lt;p&gt;where we have to be careful to write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ASSERT*&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPECT*&lt;/code&gt; to avoid
crashes, we can express the intent directly in code:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
EXPECT_THAT(GetAges(args),
            Optional(ElementsAre(21, 42, 63)));
&lt;/pre&gt;

&lt;h2 id=&quot;examples-good-uses-of-local-variables&quot;&gt;Examples: Good Uses of Local Variables&lt;/h2&gt;

&lt;h4 id=&quot;factoring-out-a-repeated-expression&quot;&gt;Factoring Out a Repeated Expression&lt;/h4&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
myproto.mutable_submessage()-&amp;gt;mutable_subsubmessage()-&amp;gt;set_foo(21);
myproto.mutable_submessage()-&amp;gt;mutable_subsubmessage()-&amp;gt;set_bar(42);
myproto.mutable_submessage()-&amp;gt;mutable_subsubmessage()-&amp;gt;set_baz(63);
&lt;/pre&gt;

&lt;p&gt;Here the repetition makes the code verbose (sometimes requiring unfortunate line
breaks), and can require more effort from readers to see that this is setting
three fields of the same proto message. Using a local variable to alias the
relevant message can clean it up:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
SubSubMessage&amp;amp; subsubmessage =
    *myproto.mutable_submessage()-&amp;gt;mutable_subsubmessage();
subsubmessage.set_foo(21);
subsubmessage.set_bar(42);
subsubmessage.set_baz(63);
&lt;/pre&gt;

&lt;p&gt;In some cases this can also help the compiler to generate better code as it
doesn’t need to prove that the repeated expression returns the same value each
time. Beware of premature optimization, though: if eliminating a common
subexpression doesn’t help human readers, profile before trying to help the
compiler.&lt;/p&gt;

&lt;h4 id=&quot;giving-meaningful-names-to-pair-and-tuple-elements&quot;&gt;Giving Meaningful Names to Pair and Tuple Elements&lt;/h4&gt;

&lt;p&gt;While it’s usually better to use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; with meaningfully-named fields than
a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pair&lt;/code&gt; or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tuple&lt;/code&gt;, we can mitigate the problems with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pair&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tuple&lt;/code&gt; by
binding meaningfully-named aliases to their elements. For example, instead of&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
for (const auto&amp;amp; name_and_age : ages_by_name) {
  if (IsDisallowedName(name_and_age.first)) continue;
  if (name_and_age.second &amp;lt; 18) children.insert(name_and_age.first);
}
&lt;/pre&gt;

&lt;p&gt;in C++11 we could write&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
for (const auto&amp;amp; name_and_age : ages_by_name) {
  const std::string&amp;amp; name = name_and_age.first;
  const int&amp;amp; age = name_and_age.second;

  if (IsDisallowedName(name)) continue;
  if (age &amp;lt; 18) children.insert(name);
}
&lt;/pre&gt;

&lt;p&gt;and in C++17, we can more simply use “structured bindings” to achieve the same
result of giving meaningful names:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
for (const auto&amp;amp; [name, age] : ages_by_name) {
  if (IsDisallowedName(name)) continue;
  if (age &amp;lt; 18) children.insert(name);
}
&lt;/pre&gt;
</description>
          <pubDate>2019-11-25T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/161</link>
          <guid isPermaLink="true">https://abseil.io/tips/161</guid>
        </item>
      
    
      
        <item>
          <title>Abseil Random</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:asoffer@google.com&quot;&gt;Andy Soffer&lt;/a&gt;, Engineer&lt;/p&gt;

&lt;p&gt;We are happy to announce the arrival of the Abseil Random library, providing
simple tools for generating random numbers and testing code that uses random
numbers.&lt;/p&gt;

&lt;p&gt;Abseil now includes a random number generation library, which can be found in
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/tree/master/absl/random/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl/random/&lt;/code&gt;&lt;/a&gt;.
The library includes
&lt;!--break--&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Drop-in replacements for some distributions available through the standard
library &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;random&amp;gt;&lt;/code&gt; header, with some modest performance improvements.&lt;/li&gt;
  &lt;li&gt;Two good default bit generators for users without the domain expertise
to make meaningful choices amongst the many options available in the
standard.&lt;/li&gt;
  &lt;li&gt;Distribution functions that provide a simple interface for generating random
values.&lt;/li&gt;
  &lt;li&gt;A bit-generator
(&lt;a href=&quot;https://github.com/abseil/abseil-cpp/tree/master/absl/random/mocking_bit_gen.h&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::MockingBitGen&lt;/code&gt;&lt;/a&gt;)
that, with &lt;a href=&quot;https://github.com/google/googletest&quot;&gt;GoogleTest&lt;/a&gt;, enables
deterministic testing of application code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This blog post discusses how to get started using this library. For a more
detailed explanation on the design of the helper functions and testing
facilities provided by this library, take a look at our &lt;a href=&quot;/about/design/random&quot;&gt;design
note&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy sampling!&lt;/p&gt;

&lt;h2 id=&quot;bit-generation&quot;&gt;Bit Generation&lt;/h2&gt;

&lt;p&gt;We provide several bit generators:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/random/random.h&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::BitGen&lt;/code&gt;&lt;/a&gt;:
A general-purpose random bit generator whose default constructor is seeded
correctly.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/random/random.h&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InsecureBitGen&lt;/code&gt;&lt;/a&gt;:
A fast bit generator for performance-sensitive use cases when the
computational cost of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::BitGen&lt;/code&gt; is prohibitively expensive.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/random/mocking_bit_gen.h&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::MockingBitGen&lt;/code&gt;&lt;/a&gt;:
A bit generator to be used only in unit tests. For details, see the &lt;a href=&quot;/about/design/random&quot;&gt;design
note&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/random/bit_gen_ref.h&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::BitGenRef&lt;/code&gt;&lt;/a&gt;:
A type-erased reference to a bit generator. Used primarily as a means of
swapping bit generators at run-time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the bit generator, we recommend using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::BitGen&lt;/code&gt; unless you have
specific performance requirements and have thoroughly vetted
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InsecureBitGen&lt;/code&gt; for your use case. Neither &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::BitGen&lt;/code&gt; nor
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InsecureBitGen&lt;/code&gt; are guaranteed to be cryptographically secure.&lt;/p&gt;

&lt;p&gt;Bit generators are well-seeded by default, so default constructing an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::BitGen&lt;/code&gt; is a correct and intended usage. All of our bit generators
provide no stability guarantees. The implementation may change at any time, and
the sequence of variates produced need not be the same, even between two
invocations of the same process.&lt;/p&gt;

&lt;h2 id=&quot;distribution-function-templates&quot;&gt;Distribution Function Templates&lt;/h2&gt;

&lt;p&gt;Distribution function templates are thin wrappers around distribution objects
that provide a straightforward API for getting randomness.  A generator should
be passed to a distribution function as in the examples below:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Using the C++ standard &amp;lt;random&amp;gt; facilities&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_device&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mt19937&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;die_roll&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uniform_int_distribution&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fair_coin_landed_heads&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bernoulli_distribution&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Using Abseil Random&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitGen&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;die_roll&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IntervalClosedClosed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fair_coin_landed_heads&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bernoulli&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The full list of distribution functions provided can be seen in
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/random/distributions.h&quot;&gt;distributions.h&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;testing-facilities&quot;&gt;Testing Facilities&lt;/h2&gt;

&lt;p&gt;For testing functions that require randomness, we provide &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::MockingBitGen&lt;/code&gt;,
a bit generator that enables a test author to specify the result of a
call to a distribution. As you will notice in the code-snippet below, this is
&lt;em&gt;not&lt;/em&gt; done via a deterministic bit generator (for reasons discusesd in the
&lt;a href=&quot;/about/design/random&quot;&gt;design note&lt;/a&gt;). Rather, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::MockingBitGen&lt;/code&gt; allows the user
to specify the result not of the bit generator, but of the entire random sample.
The design note goes into detail about why we believe this is a maintainable
approach to testing code with random behavior. These testing facilities rely on
&lt;a href=&quot;https://github.com/google/googletest&quot;&gt;GoogleTest&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Lt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ComputeValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitGenRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bernoulli&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.00001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TEST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ComputeValueTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UnlikelyCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MockingBitGen&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ON_CALL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MockBernoulli&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Lt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WillByDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;EXPECT_EQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ComputeValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
          <pubDate>2019-11-21T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/20191121-random</link>
          <guid isPermaLink="true">https://abseil.io/blog/20191121-random</guid>
        </item>
      
    
      
        <item>
          <title>Introducing Abseil Options</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:gfalcon@google.com&quot;&gt;Greg Falcon&lt;/a&gt;, Abseil Engineer&lt;/p&gt;

&lt;p&gt;Abseil now provides an &lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/base/options.h&quot;&gt;options
file&lt;/a&gt;,
providing a limited means of configuring Abseil’s features. In the initial
release of this options mechanism, we have added the ability to override
Abseil’s automatic type detection and force (for example) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; to
either always alias to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string_view&lt;/code&gt;, or always remain using our Abseil
implementation.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;The key word above is “limited”: these options are dangerous if used
incorrectly, and can only be safely used in some contexts. This blog post
explains this feature and how to correctly use it.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;While we discourage relying on compiled representations of libraries,
we recognize this isn’t always possible for providers of binaries or compiled
libraries (such as package managers). This options mechanism is provided to
allow those providers to ensure that copies of Abseil use the same
implementation. For information on how to use this options mechanism to
provide such ABI stability, consult our
&lt;a href=&quot;/docs/cpp/guides/options&quot;&gt;Options guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;caveats&quot;&gt;Caveats&lt;/h2&gt;

&lt;p&gt;Two copies of Abseil configured with different options are incompatible, in
exactly the same way that two different source snapshots of Abseil are
incompatible. Abseil options must be set consistently across an entire program.
They cannot be changed on a per-library basis.&lt;/p&gt;

&lt;p&gt;These options are dangerous if used incorrectly, and can only be safely used in
some contexts.&lt;/p&gt;

&lt;p&gt;Because of the increased testing burden they impose, we plan to keep the set of
options we support small. If you change any options, we recommend that you run
the Abseil unit tests, to ensure your settings work with your toolchain. The
default options we ship with reflect how we use Abseil internally. This is the
configuration that is “battle tested” in Google’s C++ codebase.&lt;/p&gt;
</description>
          <pubDate>2019-11-15T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/201901115-options</link>
          <guid isPermaLink="true">https://abseil.io/blog/201901115-options</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #182: Initialize Your Ints!</title>
          <description>&lt;p&gt;Originally posted as TotW #182 on July 23, 2020&lt;/p&gt;

&lt;p&gt;Updated 2020-07-23&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/182&quot;&gt;abseil.io/tips/182&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“In any moment of decision, the best thing you can do is the right thing, the
next best thing is the wrong thing, and the worst thing you can do is nothing.”
–Theodore Roosevelt&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;C++ makes it too easy to leave variables uninitialized. This is scary, because
almost any access to an uninitialized object results in &lt;em&gt;Undefined Behavior&lt;/em&gt;.
Default initialization &lt;em&gt;is&lt;/em&gt; the default, among many forms, and occurs when no
initial value is specified for a variable, but it is not always
&lt;em&gt;initialization&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;default-initialization-of-trivial-types&quot;&gt;Default Initialization of Trivial Types&lt;/h2&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
{
  bool bool_one;
  bool bool_two = bool_one;
}
&lt;/pre&gt;

&lt;p&gt;It surprises many to learn that the above code snippet invokes &lt;em&gt;Undefined
Behavior&lt;/em&gt;. In the first statement, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool_one&lt;/code&gt; is &lt;em&gt;default initialized&lt;/em&gt;, which
(ironically) is not guaranteed to actually initialize the variable. In the
example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool_one&lt;/code&gt; is left uninitialized even though it uses “default
initialization”. How do we know this?&lt;/p&gt;

&lt;p&gt;To understand this phenomenon, let’s first clarify when default initialization
does and does not behave in this way. In C++, not all types expose the ability
to skip initialization. There are two primary categories that are worth
highlighting.&lt;/p&gt;

&lt;p&gt;1) For types that have default constructors, including most &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt; types,
default initialization will invoke the default constructor in all cases. For
example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string str;&lt;/code&gt; is guaranteed to initialize &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str&lt;/code&gt; as if it had been
&lt;em&gt;value initialized&lt;/em&gt; as in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string str{};&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;2) For types with no constructors, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;, default initialization can
exhibit one of two possible behaviors. A) If the variable being initialized is
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt; or defined at namespace scope, so-called “value initialization” will be
performed. B) However, for non-&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt;, block-scope variables, default
initialization performs no initialization at all for these types, leaving the
variable uninitialized with an &lt;em&gt;indeterminate&lt;/em&gt; value.&lt;/p&gt;

&lt;p&gt;As a result, in the above example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool_one&lt;/code&gt; is uninitialized because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;
has no constructors and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool_one&lt;/code&gt; is a non-&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt;, block-scope variable. When
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool_two&lt;/code&gt;’s initialization reads the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool_one&lt;/code&gt;, the resulting
behavior is undefined.&lt;/p&gt;

&lt;p&gt;Which types in C++ lack constructors?&lt;/p&gt;

&lt;p&gt;C++ inherits types from C, referred to as &lt;em&gt;trivially default constructible&lt;/em&gt; (or
colloquially “trivial”) types, which are implemented with no constructors. This
includes fundamental types like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;double&lt;/code&gt; as well as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; types
that contain only trivial fields with no member-wise initializers. It also
includes all raw pointer types, even when they point to classes as in
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyClass*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Said another way, since C does not have constructors, such types when used in
C++ retain that behavior for default initialization.&lt;/p&gt;

&lt;p&gt;Why does C++ allow for uninitialized objects?&lt;/p&gt;

&lt;p&gt;The ability to leave some objects uninitialized is needed on rare occasion for
performance or for providing placeholders where there is truly no initial value.
Since most access patterns of uninitialized values are undefined, sanitizers can
also use this information to find bugs.&lt;/p&gt;

&lt;h2 id=&quot;default-initialization-of-potentially-trivial-types&quot;&gt;Default Initialization of Potentially-Trivial Types&lt;/h2&gt;

&lt;p&gt;Like the code snippet before, the following code also uses &lt;em&gt;default
initialization&lt;/em&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
{
  MyType my_variable;
}
&lt;/pre&gt;

&lt;p&gt;Is it safe to read the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_variable&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;To answer that question, we must know more about the implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyType&lt;/code&gt;.
The callsite shown does not have enough information to determine whether reading
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_variable&lt;/code&gt; is safe. For example, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyType&lt;/code&gt; is a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; type with
only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; fields, no constructors and no member-wise initializers,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_variable&lt;/code&gt; will be uninitialized. However, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyType&lt;/code&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt; type with
a user-defined implementation for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyType::MyType()&lt;/code&gt;, the constructor is
responsible for initializing the variable such that immediately reading its
value is a safe operation.&lt;/p&gt;

&lt;h2 id=&quot;suggestion-initialize-trivial-objects&quot;&gt;Suggestion: Initialize Trivial Objects&lt;/h2&gt;

&lt;p&gt;In most code, you &lt;strong&gt;probably&lt;/strong&gt; don’t want uninitialized objects. Rarely, it can
make sense for reasons of performance or encoding semantics. However, unless in
one of these exceptional cases, prefer initializing trivial objects in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;
fields and variables as in the following examples:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
float ComputeValueWithDefault() {
  float value = 0.0;  // Guarantees initialization by providing a default value.
  ComputeValue(&amp;amp;value);
  return value;
}
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct MySequence {
  // Member-wise initializers guarantee initialization.
  MyClass* first_element = nullptr;
  int element_count = 0;
};

MySequence GetPopulatedMySequence() {
  MySequence my_sequence;  // Made safe by the member-wise initializers.
  MaybePopulateMySequence(&amp;amp;my_sequence);
  return my_sequence;
}
&lt;/pre&gt;

&lt;p&gt;Additionally, where feasible, refrain from making type aliases for trivial
types. We want &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt; types to be safely initialized in all cases.
Since fundamental types (integers, pointers, etc.) do not guarantee
initialization from default initialization, giving names to such types that
appear to be safe can make code more difficult to reason about.&lt;/p&gt;

&lt;p&gt;Examples of aliases for trivial types are shown below:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
{
  using KeyType = float;  // C++-style alias
  typedef bool ResultT;  // C-style alias

  // [Many lines of code...]

  // Surprise! These variables are uninitialized!
  KeyType some_key;
  ResultT some_result;
}
&lt;/pre&gt;

&lt;h2 id=&quot;additional-information&quot;&gt;Additional Information&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/default_initialization&quot;&gt;CppReference: Default initialization&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/88&quot;&gt;Tip of the Week #88: Initialization: =, (), and {}&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/tips/146&quot;&gt;Tip of the Week #146: Default vs Value Initialization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2019-10-01T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/182</link>
          <guid isPermaLink="true">https://abseil.io/tips/182</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #180: Avoiding Dangling References</title>
          <description>&lt;p&gt;Originally posted as TotW #180 on June 11, 2020&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:titus@cs.ucr.edu&quot;&gt;Titus Winters&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-06-11&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/180&quot;&gt;abseil.io/tips/180&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Unlike many languages, C++ lacks the safety checks necessary to avoid
referencing invalid memory (aka “dangling references”). You can easily
dereference a pointer to an object that was already &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delete&lt;/code&gt;-ed, or follow a
reference to an object that has gone out of scope. Even class types carry this
risk. Importantly, we are building naming conventions around the names &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view&lt;/code&gt;
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; to signify “This is an object that has reference semantics and may
dangle.” These types, like all types with reference semantics, never own the
underlying data that they point to. Be mindful whenever you see instances of any
of these types stored.&lt;/p&gt;

&lt;h2 id=&quot;dangling-and-understanding-c&quot;&gt;Dangling, And Understanding C++&lt;/h2&gt;

&lt;p&gt;If you’re coming to C++ from other languages, there are quite a few fundamental
surprises. The type system is meaningfully more complicated than most languages,
requiring a sometimes-subtle understanding of references, temporaries,
shallow-const, pointers, object lifetimes, etc. One of the most uniquely
important issues when learning C++ is recognizing that having a pointer or a
reference to an object doesn’t mean the object still exists. C++ is not
garbage-collected nor reference-counted, and as a result holding a handle to an
object isn’t enough to ensure the object stays alive.&lt;/p&gt;

&lt;p&gt;Consider:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
int* int_handle;
{
  int foo = 42;
  int_handle = &amp;foo;
}
std::cout &amp;lt;&amp;lt; *int_handle &amp;lt;&amp;lt; &quot;\n&quot;;  // Boom
&lt;/pre&gt;

&lt;p&gt;When we dereference &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int_handle&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator*&lt;/code&gt;, we are following a pointer to
an object whose lifetime is ended. This is a bug. Formally, this is &lt;em&gt;undefined
behavior&lt;/em&gt;, and anything can happen.&lt;/p&gt;

&lt;p&gt;Distressingly, one of the “anything can happen” options is “this does what you
naively think it might” - printing 42. &lt;em&gt;C++ is a language that does not promise
to diagnose or react to your bugs.&lt;/em&gt; The fact that your program seems to work
does not mean it is correct. It means at best that the compiler happened to
choose an outcome that worked for you. But make no mistake: this is no less
buggy than if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int_handle&lt;/code&gt; was a pointer to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From this we draw two important points:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Unlike most languages we use today, the fact that a program runs to
completion or behaves as expected is only weakly correlated with “this is
correct.” Other languages would diagnose (at compile time or runtime) our
errors, C++ chooses to focus instead on optimization and efficiency:
spending extra computing power to check that you didn’t make an error isn’t
the C++ way. In most languages “It works” is much better evidence for “It is
correct.” C++ requires that we question that evidence.&lt;/li&gt;
  &lt;li&gt;Holding a handle (a pointer or reference) to an object does not guarantee
that the object is alive and valid to access. Other languages have runtime
overhead to keep objects alive, or statically constrain the code you can
write. C++ focuses instead on optimization and efficiency. Anytime you use a
handle to access the underlying object you need a mental proof to understand
why you’re sure the underlying object is still alive. It may have gone out
of scope, it may have been explicitly &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delete&lt;/code&gt;-ed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is critically important to understand that our informal “handle” discussion
applies to values of certain class types as well as to the more-obvious pointers
and references. Consider iterators:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::vector&amp;lt;int&amp;gt;::iterator int_handle;
{
  std::vector&amp;lt;int&amp;gt; v = {42};
  int_handle = v.begin();
}
std::cout &amp;lt;&amp;lt; *int_handle &amp;lt;&amp;lt; &quot;\n&quot;; // Boom
&lt;/pre&gt;

&lt;p&gt;This is morally identical to the previous example. On some platforms, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt;
iterators may in fact be implemented as pointers. Even if these iterators are
class types, the same language rules apply: dereferencing the iterator will
(under the hood) eventually be following a pointer or reference to an object
that is no longer in scope (in this case, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v[0]&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Because C++ does not define what happens when code uses an invalid pointer,
reference, or iterator, code that does so is &lt;em&gt;always&lt;/em&gt; incorrect (even if it
appears to work). This allows debugging tools such as sanitizers and debugging
iterators to report bugs with no false positives.&lt;/p&gt;

&lt;h2 id=&quot;class-types-that-may-dangle&quot;&gt;Class Types that May Dangle&lt;/h2&gt;

&lt;p&gt;Over the past few years, Abseil and the C++ standard library have been
introducing additional class types with similar “handle” behavior. The most
common of these is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;, which is a handle to some contiguous buffer of
characters (often a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;). Holding a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; is exactly like holding
any other handle type: there is no general guarantee that the underlying data
lives. It is up the programmer to prove that the underlying buffer outlives the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;. Importantly the handle that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; provides does not allow
for mutation: a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; cannot be used to modify the underlying data.&lt;/p&gt;

&lt;p&gt;Another handle design that is becoming common is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&amp;lt;T&amp;gt;&lt;/code&gt;, which is a
contiguous buffer of any type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;. If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is non-const, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; allows
mutation of the underlying data. If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is const, then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; cannot modify
it, in the same fashion that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; cannot modify the underlying buffer.
Thus, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&amp;lt;const char&amp;gt;&lt;/code&gt; is similar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;. Although the two types
have different APIs, reasoning about the handles or underlying buffers works in
exactly the same way.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; tend to be very safe to use as function parameters,
abstracting away from a variety of input argument formats. Because of the
possibility of a dangling reference, any time that types of this design are
&lt;em&gt;stored&lt;/em&gt;, they become a significant source of programmer error. Every storage of
any handle type requires critical thinking to understand why we are sure the
underlying object stays valid for the lifetime of the &lt;em&gt;handle&lt;/em&gt;. Using
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; in a container is not always wrong but is a subtle
optimization that warrants clear comments describing the associated storage.
Using these types for data members of a class is rarely the right choice.&lt;/p&gt;

&lt;p&gt;It is critically important going forward that C++ programmers understand these
design patterns, and how to use these “reference parameter types.” To assist in
that understanding, type designers and library providers tend toward the
following meaning for types:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;view&lt;/strong&gt; - a reference type that cannot be used to mutate the underlying
data&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;span&lt;/strong&gt; - a reference type that might be used to mutate the underlying data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since both of these naming indicators suggest reference types, any storage of a
library-provided type called a “view” or a “span” needs to be accompanied by the
same logic you would use when thinking about the lifetimes of a pointer or
reference: how do I know that the underlying object is still alive?&lt;/p&gt;

&lt;h2 id=&quot;caveats-and-further-reading&quot;&gt;Caveats and Further Reading&lt;/h2&gt;

&lt;p&gt;The popular external &lt;a href=&quot;https://github.com/ericniebler/range-v3&quot;&gt;range_v3&lt;/a&gt;
library and the upcoming C++20 ranges library have a different meaning for
“view”, although the types described by these definitions overlap. In ranges,
“view” means “a range that can be copied in O(1)”. This includes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;.
However, this definition does not preclude mutation of the underlying data. This
mismatch is unfortunate, and largely recognized by the C++ standards committee,
but nobody could find consensus on any alternative to “view” after the concern
was raised.&lt;/p&gt;

&lt;p&gt;The C++20 &lt;a href=&quot;https://en.cppreference.com/w/cpp/container/span&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;&lt;/a&gt; type and
Abseil’s
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&lt;/code&gt;&lt;/a&gt;
type have slightly different interfaces and semantics when it comes to
comparability and copying. The most notable difference is with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Span::operator==&lt;/code&gt;, which &lt;a href=&quot;http://wg21.link/P1085R2&quot;&gt;we now know&lt;/a&gt; to
probably be a design mistake.&lt;/p&gt;

&lt;p&gt;For more on the design theory underlying modern reference parameter types, see
&lt;a href=&quot;https://abseil.io/blog/20180531-regular-types&quot;&gt;Revisiting Regular Types&lt;/a&gt;.&lt;/p&gt;
</description>
          <pubDate>2019-10-01T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/180</link>
          <guid isPermaLink="true">https://abseil.io/tips/180</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #158: Abseil Associative containers and &lt;code&gt;contains()&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #158 on January 3, 2019&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;James Dennett&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-20&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/158&quot;&gt;abseil.io/tips/158&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“I cannot contain myself” – Bertrand Russell&lt;/p&gt;

&lt;h2 id=&quot;does-that-container-contain-this-thing-or-not&quot;&gt;Does That Container Contain This Thing or Not?&lt;/h2&gt;

&lt;p&gt;When checking whether a set contains a value or a map contains a key, C++ has
historically forced users to choose between writing the rather verbose&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
container.find(value) != container.end()
&lt;/pre&gt;

&lt;p&gt;or the arguably obtuse (and sometimes inefficient)&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
container.count(value) != 0
&lt;/pre&gt;

&lt;p&gt;instead of writing&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
container.contains(value)
&lt;/pre&gt;

&lt;p&gt;as we’d like to.&lt;/p&gt;

&lt;h2 id=&quot;containercontainsvalue-to-the-rescue&quot;&gt;&lt;code&gt;container.contains(value)&lt;/code&gt; to the Rescue&lt;/h2&gt;

&lt;p&gt;The simpler syntax is part of the C++20 Standard, and Abseil’s
&lt;!-- [hashed containers][hashmaps] --&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::{flat,node}_hash_{map,set}&lt;/code&gt;) and
btree containers (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::btree_*&lt;/code&gt;) support it today.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;contains&lt;/code&gt; has the same support for &lt;a href=&quot;/tips/144&quot;&gt;heterogeneous lookup&lt;/a&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt;,
so (for example) it’s possible to check whether an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_set&amp;lt;std::string&amp;gt;&lt;/code&gt; contains an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; value without
paying the costs of converting to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; object:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
constexpr absl::string_view name = &quot;Willard Van Orman Quine&quot;;
absl::flat_hash_set&amp;lt;std::string&amp;gt; names = {std::string(name)};
assert(names.contains(name));  // No dynamic allocation here.
&lt;/pre&gt;

&lt;p&gt;Given that most of our code that needs associative containers (whether sets or
maps) should be using the Abseil hashed containers today (see
&lt;a href=&quot;/tips/136&quot;&gt;Tip #136&lt;/a&gt;), it should rarely be necessary to use one of the other
formulations in new code.&lt;/p&gt;

&lt;p&gt;NOTE: As described in &lt;a href=&quot;/tips/132&quot;&gt;Tip #132&lt;/a&gt; (“Avoid Redundant Map Lookups”),
don’t check if an item is in a container and then do another operation that
implies a lookup (such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insert&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;remove&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Querying whether an item can be found in an associative container is a common
operation, and a natural syntax for it is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;container.contains(value)&lt;/code&gt;. Prefer
that syntax when possible.&lt;/p&gt;

</description>
          <pubDate>2019-10-01T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/158</link>
          <guid isPermaLink="true">https://abseil.io/tips/158</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #147: Use Exhaustive &lt;code&gt;switch&lt;/code&gt; Statements Responsibly</title>
          <description>&lt;p&gt;Originally posted as TotW #147 on April 25, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jnewsome@google.com&quot;&gt;Jim Newsome&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/147&quot;&gt;abseil.io/tips/147&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Werror&lt;/code&gt; compiler flag, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement over a value of an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; type without a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default&lt;/code&gt; label will fail to compile if any enumerator of
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; doesn’t have a corresponding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;case&lt;/code&gt;. This is sometimes called an
&lt;em&gt;exhaustive&lt;/em&gt; or &lt;em&gt;defaultless&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;An exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement is an excellent construct for ensuring at
compile time that every enumerator of a given enum is explicitly handled.
However, we must ensure that we handle the fall-through case when the variable
(legally!) has a non-enumerator value, and one of:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The owner of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; guarantees no new enumerators will be added,&lt;/li&gt;
  &lt;li&gt;The owner of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; is willing and able to fix our code when new
enumerators are added (e.g. the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; definition is part of the same
project),&lt;/li&gt;
  &lt;li&gt;The owner of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; will not be blocked by breaking our build (e.g.
their code is in a separate source control repository), and we’re willing to
be forced to update our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statements when updating to the latest
version of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt;-owner’s code.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;an-initial-attempt&quot;&gt;An Initial Attempt&lt;/h3&gt;

&lt;p&gt;Suppose we are writing a function that maps each enumerator of an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; to a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;. We decide to use an exhaustive switch statement to ensure we
didn’t forget to handle any of the enumerators:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
std::string AnEnumToString(AnEnum an_enum) {
  switch (an_enum) {
    case AnEnum::kFoo:
      return &quot;kFoo&quot;;
    case AnEnum::kBar:
      return &quot;kBar&quot;;
    case AnEnum::kBaz:
      return &quot;kBaz&quot;;
  }
}
&lt;/pre&gt;

&lt;p&gt;Assuming that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnum&lt;/code&gt; indeed has only those three enumerators, this code will
compile, and will seem to have the desired effect. However, there are two
important issues that must be accounted for.&lt;/p&gt;

&lt;h2 id=&quot;enums-with-non-enumerator-values&quot;&gt;Enums with Non-Enumerator Values&lt;/h2&gt;

&lt;p&gt;In C++, enums are permitted to have values other than the explicit enumerators.
All enums can legally take on at least all of the values representable by an
integral type with just enough bits to represent every enumerator, and enums
with a fixed underlying type (e.g. those declared with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum class&lt;/code&gt;) can take on
any value representable by that type. This is sometimes intentionally leveraged
to use an &lt;a href=&quot;https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang:c%2B%2B,source:&apos;%23include+&amp;lt;cstdint&amp;gt;%0A%0A//+kEnableX+%7C+kEnableY+%3D+3+is+a+legal+and+reasonable+value+for+a+MyFlags.%0Aenum+MyFlags+:+uint32_t+%7B%0A++++kEnableX+%3D+1,%0A++++kEnableY+%3D+1+&amp;lt;&amp;lt;+1,++//+2%0A++++kEnableZ+%3D+1+&amp;lt;&amp;lt;+2,++//+4%0A%7D%3B&apos;),l:&apos;5&apos;,n:&apos;0&apos;,o:&apos;C%2B%2B+source+%231&apos;,t:&apos;0&apos;)),k:51.75805047867712,l:&apos;4&apos;,n:&apos;0&apos;,o:&apos;&apos;,s:0,t:&apos;0&apos;),(g:!((h:compiler,i:(compiler:clang800,filters:(b:&apos;0&apos;,binary:&apos;1&apos;,commentOnly:&apos;0&apos;,demangle:&apos;0&apos;,directives:&apos;0&apos;,execute:&apos;1&apos;,intel:&apos;0&apos;,libraryCode:&apos;1&apos;,trim:&apos;1&apos;),lang:c%2B%2B,libs:!(),options:&apos;&apos;,source:1),l:&apos;5&apos;,n:&apos;0&apos;,o:&apos;x86-64+clang+8.0.0+(Editor+%231,+Compiler+%231)+C%2B%2B&apos;,t:&apos;0&apos;),(h:output,i:(compiler:1,editor:1,wrap:&apos;1&apos;),l:&apos;5&apos;,n:&apos;0&apos;,o:&apos;%231+with+x86-64+clang+8.0.0&apos;,t:&apos;0&apos;)),k:48.241949521322894,l:&apos;4&apos;,n:&apos;0&apos;,o:&apos;&apos;,s:0,t:&apos;0&apos;)),l:&apos;2&apos;,n:&apos;0&apos;,o:&apos;&apos;,t:&apos;0&apos;)),version:4&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; as a bitfield&lt;/a&gt; or to represent enumerators that
didn’t exist when we compiled our code (as in
&lt;a href=&quot;https://developers.google.com/protocol-buffers/docs/reference/cpp-generated#enum&quot;&gt;proto 3&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;So what happens in our code if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;an_enum&lt;/code&gt; isn’t one of the handled enumerator
types?&lt;/p&gt;

&lt;p&gt;In general when a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement doesn’t have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;case&lt;/code&gt; matching the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt;
condition and doesn’t have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default&lt;/code&gt; case, execution falls through past the
whole &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement. This can lead to surprising behavior; in our example
it leads to &lt;strong&gt;undefined behavior&lt;/strong&gt;. After execution falls through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt;
statement, it reaches the end of the function without returning a value, which
is undefined behavior for a function with a non-void return type.&lt;/p&gt;

&lt;p&gt;We can address this issue by explicitly handling the case where execution falls
through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement. This ensures we always get defined and
predictable behavior at run time, while continuing to benefit from the
compile-time check that all enumerators are explicitly handled.&lt;/p&gt;

&lt;p&gt;In our example, we’ll log a warning and return a sentinel value. Another
reasonable alternative, especially if we’re convinced that the function
(currently) &lt;em&gt;can’t&lt;/em&gt; receive a non-enumerator value, would be to immediately
crash with a debuggable error message and stack trace.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string AnEnumToString(AnEnum an_enum) {
  switch (an_enum) {
    case AnEnum::kFoo:
      return &quot;kFoo&quot;;
    case AnEnum::kBar:
      return &quot;kBar&quot;;
    case AnEnum::kBaz:
      return &quot;kBaz&quot;;
  }
  LOG(ERROR) &amp;lt;&amp;lt; &quot;Unexpected value for AnEnum: &quot; &amp;lt;&amp;lt; static_cast&amp;lt;int&amp;gt;(an_enum);
  return kUnknownAnEnumString;
}
&lt;/pre&gt;

&lt;p&gt;We’ve now ensured that something reasonable happens for &lt;em&gt;any&lt;/em&gt; possible value of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;an_enum&lt;/code&gt;, but there’s still potentially a problem.&lt;/p&gt;

&lt;h2 id=&quot;what-happens-when-a-new-enumerator-is-added&quot;&gt;What Happens When a New Enumerator Is Added?&lt;/h2&gt;

&lt;p&gt;Suppose someone later wants to add a new enumerator to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnum&lt;/code&gt;. Doing so causes
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnumToString&lt;/code&gt; to no longer compile. Whether that’s a bug or a feature depends
on who owns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnum&lt;/code&gt; and what guarantees they provide.&lt;/p&gt;

&lt;p&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnum&lt;/code&gt; is part of the same project as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnumToString&lt;/code&gt;, then the engineer
adding a new enumerator is likely to be blocked from submitting their change
before fixing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnumToString&lt;/code&gt; due to compilation errors. They are also
reasonably likely to be willing and able to do so. In this case our use of an
exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement is a win: it successfully ensured that the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement is updated appropriately, and everyone is happy.&lt;/p&gt;

&lt;p&gt;Similarly, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnum&lt;/code&gt; is part of a different project in a &lt;em&gt;different
repository&lt;/em&gt;, then the breakage won’t surface until the engineers on our project
try to update to a newer version of that code. If we expect that those engineers
will be willing and able to fix the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement, then all is well.&lt;/p&gt;

&lt;p&gt;However, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnum&lt;/code&gt; is owned by a different project in the &lt;em&gt;same repository&lt;/em&gt;
the situation is a bit more precarious. A change to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnum&lt;/code&gt; might cause our
code to break at head, and the engineer making the change might not be willing
or able to fix it for us. Indeed, if there were many similar exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt;
statements over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnum&lt;/code&gt;, it’d be extremely challenging for them to fix all such
usages.&lt;/p&gt;

&lt;p&gt;For these reasons, it’s best to use exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statements only on
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; types that either we own, or whose owner has explicitly guaranteed that
no new enumerators will be added.&lt;/p&gt;

&lt;p&gt;In our example, let’s suppose that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnEnum&lt;/code&gt; is owned by a different project, but
the documentation promises that no new enumerators will be added. Let’s add a
comment so that future readers understand our reasoning.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::string AnEnumToString(AnEnum an_enum) {
  switch (an_enum) {
    case AnEnum::kFoo:
      return &quot;kFoo&quot;;
    case AnEnum::kBar:
      return &quot;kBar&quot;;
    case AnEnum::kBaz:
      return &quot;kBaz&quot;;
    // No default. The API of AnEnum guarantees no new enumerators will be
    // added.
  }
  LOG(ERROR) &amp;lt;&amp;lt; &quot;Unexpected value for AnEnum: &quot; &amp;lt;&amp;lt; static_cast&amp;lt;int&amp;gt;(an_enum);
  return kUnknownAnEnumString;
}
&lt;/pre&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;Exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statements can be an excellent tool for ensuring that all
enumerators are explicitly handled, provided that we:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Explicitly handle the case where the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; has a non-enumerator value,
falling through the entire &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement. In particular if the
enclosing function has a return value, we must ensure that the function
still either returns a value or crashes in a well-defined and debuggable
way.&lt;/li&gt;
  &lt;li&gt;Ensure that one of:
    &lt;ul&gt;
      &lt;li&gt;The owner of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; type either guarantees no new enumerators will
be added,&lt;/li&gt;
      &lt;li&gt;The owner of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; is willing and able to fix our code when new
enumerators are added,&lt;/li&gt;
      &lt;li&gt;If our code uses exhaustive switch statements and is broken due to an
enumerator being added, the owner of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; is not blocked by this
breakage.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When making an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; type available to other projects, we should either:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Explicitly guarantee that no new enumerators will be added, so that users
can take advantage of exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statements.&lt;/li&gt;
  &lt;li&gt;Explicitly reserve the right to add new enumerators without notice, to
discourage consumers from writing exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statements. One
idiomatic way of doing so is to add a sentinel enumerator clearly not meant
to be used in API consumers’ exhaustive switch statements; e.g.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kNotForUseWithExhaustiveSwitchStatements&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;faq&quot;&gt;FAQ&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Why does the compiler allow omitting a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt; statement after an
exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt;?&lt;/p&gt;

    &lt;p&gt;Omitting a final return &lt;em&gt;can&lt;/em&gt; be safe if additional steps are taken to
ensure that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; variable can only be one of its enumerators. It’s
often better in such cases to still defensively add a final &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The enum I’m switching on already has exhaustive switch statements all over
the place. Since the owners are already effectively prevented from adding
new enumerators, won’t adding my own exhaustive switch statement be
harmless?&lt;/p&gt;

    &lt;p&gt;It’s usually better to get an explicit policy from the owner before further
increasing their maintenance burden.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;What about protobuf enums?&lt;/p&gt;

    &lt;p&gt;For authoritative guidance, see the
&lt;a href=&quot;https://developers.google.com/protocol-buffers/docs/reference/cpp-generated#enum&quot;&gt;protobuf documentation&lt;/a&gt;.&lt;/p&gt;

    &lt;p&gt;Exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statements on proto3 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; types are &lt;strong&gt;not
recommended&lt;/strong&gt;. The parser &lt;em&gt;doesn’t&lt;/em&gt; guarantee that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; fields will have
enumerator values. Additionally, it’s not possible to write an exhaustive
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement over proto3 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; types without referencing special
sentinel enumerators that should be considered internal implementation
details of the protobuf tools.&lt;/p&gt;

    &lt;p&gt;Exhaustive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; statements on proto2 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; types that you own (or whose
owners guarantee will never be moved to proto3 and will never have new
enumerators added) are safe and recommended by the protobuf team. The
protobuf parser guarantees that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; fields will be assigned a
compile-time enumerator, though care should still be taken if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt;
value isn’t guaranteed to have come from the parser (e.g. if it’s part of a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proto&lt;/code&gt; object received as a function parameter).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;What about scoped enumerations (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum class&lt;/code&gt;)?&lt;/p&gt;

    &lt;p&gt;Everything in this tip applies to all enumeration types in C++ at time of
writing (i.e. through at least C++20).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developers.google.com/protocol-buffers/docs/reference/cpp-generated#enum&quot;&gt;Enum handling in protobuf generated code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/enum&quot;&gt;C++ enum specification&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
          <pubDate>2019-09-09T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/147</link>
          <guid isPermaLink="true">https://abseil.io/tips/147</guid>
        </item>
      
    
      
        <item>
          <title>B-tree Ordered Containers</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:ezb@google.com&quot;&gt;Evan Brown&lt;/a&gt;, Engineer&lt;/p&gt;

&lt;p&gt;The Abseil container library now includes B-tree containers that
generally conform to the STL sorted container APIs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::btree_set&lt;/code&gt; (meant to replace usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::set&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::btree_map&lt;/code&gt; (meant to replace usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::map&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::btree_multiset&lt;/code&gt; (meant to replace usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::multiset&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::btree_multimap&lt;/code&gt; (meant to replace usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::multimap&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You use a B-tree container just as you would an STL ordered container:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;absl/container/btree_map.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;btree_map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ducks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;dewey&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;huey&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;louie&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Prints &quot;huey, dewey, louie &quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ducks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;B-trees have a different implementation from STL &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::map&lt;/code&gt; containers, which
require binary trees commonly implemented as &lt;a href=&quot;https://en.wikipedia.org/wiki/Red%E2%80%93black_tree&quot;&gt;red-black trees&lt;/a&gt;.
While a red-black tree is limited to single-element nodes, with precisely two
children, a B-tree may contain multiple values per node (M), with each node
having (M+1) children. Having more values and children per node is more cache
friendly because nodes are generally allocated separately so accessing
additional nodes often results in cache misses.&lt;/p&gt;

&lt;!--break--&gt;

&lt;h2 id=&quot;cache-friendliness&quot;&gt;Cache Friendliness&lt;/h2&gt;

&lt;p&gt;For search, insertion, and deletion, the number of nodes that need to be
accessed in a sorted tree is proportional to the height of the tree. In
balanced trees, this height is ~log&lt;sub&gt;C&lt;/sub&gt;(N), where C is the number
of children per node and N is the number of values in the container;
because b-trees have more children per node than binary trees, their
heights are lower, and searching is faster.&lt;/p&gt;

&lt;p&gt;For iteration, it is most cache efficient to store all values contiguously.
B-trees store values contiguously in each node so it’s also generally more
efficient to iterate through a B-tree than a binary tree.&lt;/p&gt;

&lt;h2 id=&quot;memory-overhead&quot;&gt;Memory Overhead&lt;/h2&gt;

&lt;p&gt;B-trees also use significantly less memory per value in the tree because
overhead is per node, and there are fewer nodes per value in B-trees. There is
also an optimization in Abseil B-tree in which leaf nodes don’t store child
pointers. Since the vast majority of nodes are leaf nodes (because of the
higher branching factor due to more children per non-leaf node), this ends up
saving a significant amount of memory.&lt;/p&gt;

&lt;h2 id=&quot;api-difference-from-stl-sorted-containers&quot;&gt;API Difference from STL Sorted Containers&lt;/h2&gt;

&lt;p&gt;When values are inserted or removed from a B-tree, nodes can be split or merged
and values can be moved within and between nodes (for the purpose of maintaining
tree balance). This means that when values are inserted or removed from a B-tree
container, pointers and iterators to other values in the B-tree can be
invalidated. Abseil B-trees therefore do not provide pointer stability or
iterator stability - this is in contrast to STL sorted containers that do
provide these guarantees.&lt;/p&gt;

&lt;h2 id=&quot;when-to-use-b-trees&quot;&gt;When to Use B-trees&lt;/h2&gt;

&lt;p&gt;B-trees are a good default choice for sorted containers, however, there are
cases in which the STL alternatives may be more appropriate.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_type&lt;/code&gt; is large, fewer values can be stored per node so the
benefits of B-tree are lessened.&lt;/li&gt;
  &lt;li&gt;When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_type&lt;/code&gt; is expensive to move, B-tree may become more expensive than
STL alternatives because B-tree needs to move values within and between nodes
to maintain balance, whereas binary trees can just move pointers instead.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::array&amp;lt;int32_t, 16&amp;gt;&lt;/code&gt; is an example of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_type&lt;/code&gt; for which STL sorted
containers currently outperform B-trees.&lt;/li&gt;
  &lt;li&gt;When pointer stability or iterator stability is required, B-trees aren’t a
viable option (although usually code can be refactored to avoid these
requirements).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information, consult the
&lt;a href=&quot;/docs/cpp/guides/container&quot;&gt;Abseil Container library documentation&lt;/a&gt;. Check out the
&lt;a href=&quot;/about/design/btree&quot;&gt;B-tree Design Note&lt;/a&gt; for information on B-tree’s
implementation.&lt;/p&gt;

</description>
          <pubDate>2019-08-12T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20190812-btree</link>
          <guid isPermaLink="true">https://abseil.io/blog/20190812-btree</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #90: Retired Flags</title>
          <description>&lt;p&gt;Originally posted as TotW #90 on March 19, 2015&lt;/p&gt;

&lt;p&gt;*by &lt;a href=&quot;mailto:titus@google.com&quot;&gt;Titus Winters&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the frustrating things about our (mis)use of command-line flags
is the difficulty in removing a flag from binary and production
servers safely (revisit https://abseil.io/tips/45 for some frustrating
misuses). The trouble? A binary won’t start if you specify a flag that is
no longer defined, and thus removal of flags may require coordination
between C++ code and your job launching scripts and configurations.&lt;/p&gt;

&lt;p&gt;In some cases, this coordination can be quite challenging (conditioning
production code based on a binary version). If only there were a better way!&lt;/p&gt;

&lt;p&gt;There is. A while back we added a new concept to the C++ command-line flags
system called “retired flags” (&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/flags/flag.h#L255&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ABSL_RETIRED_FLAG&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A retired flag creates no symbol in C++ (no more &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FLAGS_some_flag&lt;/code&gt; global
variable to rely upon), does not appear in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--help&lt;/code&gt;, but will be accepted when
specified on the command line (although an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERROR&lt;/code&gt; will be logged). In this way,
flags that are no longer used by the code can be “retired”, separating C++
changes from production configuration changes. Once the configuration changes
are all clear, the retired flag can be removed once and for all.&lt;/p&gt;

&lt;p&gt;Retired flags were designed to be used in many situations (including cases
involving cross-repo non-atomic commit requirements). A step-by-step
for a very simple flag retirement could look like this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Remove uses of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FLAGS_frobber&lt;/code&gt; from code.&lt;/p&gt;

    &lt;p&gt;If you’re following the advice of https://abseil.io/tips/45 and using
flags primarily from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main()&lt;/code&gt; this should be easy to do and to check
for.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Change the definition of the flag to retire it. That is:&lt;/p&gt;

    &lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ABSL_FLAG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Which frobber to use?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;should become:&lt;/p&gt;

    &lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ABSL_RETIRED_FLAG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;retired&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Wait for binary release(s). Once all the jobs in all of your serving cells
are invoking the new binary, you can continue.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Remove the flag from your production configuration. Once searching the
relevant production configs shows no hits for the frobber flag, you can
continue.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Remove the retired flag.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We’ve had success with very complicated flag removals: the motivating example
for this effort was the removal of flags defined in a legacy internal
filesystem, which was more complicated because the flags were defined in a
library (and thus used in numerous binaries). From what we’ve seen, even the
most complicated flag removals can be enabled safely with this system. So,
the next time you’re wondering how to remove a flag safely, consider retiring
it first and taking it step-by-step.&lt;/p&gt;

</description>
          <pubDate>2019-05-10T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/90</link>
          <guid isPermaLink="true">https://abseil.io/tips/90</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #45: Avoid Flags, Especially in Library Code</title>
          <description>&lt;p&gt;Originally posted as TotW #45 on June 3, 2013&lt;/p&gt;

&lt;p&gt;*by &lt;a href=&quot;mailto:titus@google.com&quot;&gt;Titus Winters&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“What I really want is the behavior of my code to be controlled by a global
variable that cannot be statically predicted, whose usage is incompletely
logged, and which can only be removed from my code with great difficulty.” –
Nobody, Ever&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The common use of flags in production code, especially within libraries, is
a mistake. Don’t use flags unless it is truly necessary. There, we said it.&lt;/p&gt;

&lt;p&gt;Flags are global variables, only worse: you can’t know the value of that
variable by reading the code. A flag may not only be set at startup, but could
potentially be changed later through arbitrary means. If you
run a server in your binary, there is usually no guarantee that the value of
your flag will remain unchanged from cycle to cycle, nor any notification if
it were to change, nor any means for looking for such a change.&lt;/p&gt;

&lt;p&gt;If your production environment logs the invocation of every binary directly,
and stores those logs, great. Most environments don’t work that way. For
library code, this uncertainty is especially nefarious: how can you tell
when use of a particular feature is actually dead? The simple answer is:
you can’t.&lt;/p&gt;

&lt;p&gt;Flags also make it challenging to put the final stake in dead code. During
migrations to new backends, you’d &lt;em&gt;think&lt;/em&gt; that removing legacy code would
simply be a matter of removing unnecessary build dependencies and issuing
history’s most satisfying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rm&lt;/code&gt;. You’d be wrong. If your legacy binary
has hundreds of flags defined and referenced by production code,
simply removing the dead code would cause massive problems for your release
engineers: almost no jobs would start up after such a change.&lt;/p&gt;

&lt;p&gt;The worst part of all of this? An analysis that was done at Google during
early 2012 found that the majority of C++ flags had never actually varied,
as far as we can tell within the data retention limits described above.&lt;/p&gt;

&lt;p&gt;Flags are appropriate in certain use cases, however: debugging without
flag-enabled backtraces just wouldn’t be the same. Feature flags, when
handled properly (and cleaned up afterward), are perfectly justified. Knobs
that genuinely need to be tweaked by heroic SREs are a handy safety net.
More broadly, flags used to pass name/value inputs to a binary, and
used only in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main()&lt;/code&gt;, are much more maintainable than positional parameters.&lt;/p&gt;

&lt;p&gt;Even given those caveats, it’s time that we all take a good hard look at our
usage of flags. The next time you’re tempted to add a flag to your library,
spend a while looking for a better way. Pass configuration explicitly: this
is almost always easier to reason about properly, and is certainly easier to
maintain. Consider making numeric flags into compile-time constants. If you
encounter new flags in code reviews, push back. Every flag introduction should
be justified.&lt;/p&gt;
</description>
          <pubDate>2019-05-10T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/45</link>
          <guid isPermaLink="true">https://abseil.io/tips/45</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #103: Flags Are Globals</title>
          <description>&lt;p&gt;&lt;em&gt;by &lt;a href=&quot;mailto:marmstrong@google.com&quot;&gt;Matt Armstrong&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Define flags at global scope in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file. Declare them at most once in a
corresponding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.h&lt;/code&gt; file.&lt;/p&gt;

&lt;h2 id=&quot;why-declare-things-in-header-files&quot;&gt;Why Declare Things In Header Files?&lt;/h2&gt;

&lt;p&gt;Using header files is a reflex for most of us, so we may have forgotten why they
are used:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Declaring something in a header file makes it easy to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#include&lt;/code&gt; elsewhere.
The entire program sees the same declaration.&lt;/li&gt;
  &lt;li&gt;Including this header in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; that defines the same entity ensures the
definition matches declaration.&lt;/li&gt;
  &lt;li&gt;The header file serves as documentation for a package’s public API. Using
anything but a package’s public API is poor form.&lt;/li&gt;
  &lt;li&gt;Including headers, instead of re-declaring entities, helps both tools and
humans perform dependency analysis.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;abseil-flags-are-as-vulnerable-as-any-other-global&quot;&gt;Abseil Flags Are As Vulnerable As Any Other Global&lt;/h2&gt;

&lt;p&gt;You can do this incorrectly with no link-time error. First, place the following
in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Defining --my_flag in a .cc file.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ABSL_FLAG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;My flag is a string.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And the following, erroneous, declaration of the flag in a different &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; file
(perhaps a test):&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Declared in error: type should be std::string.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Flag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLAGS_my_flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The program is ill-formed, and whatever happens is the result of &lt;a href=&quot;http://en.cppreference.com/w/cpp/language/ub&quot;&gt;undefined
behavior&lt;/a&gt;. In my test program,
this code compiled, linked, and crashed when the flag was accessed.&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;p&gt;Design with command line flags as you would global variables.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Avoid flags if you can. See http://abseil.io/tips/45.&lt;/li&gt;
  &lt;li&gt;If you are using a flag to make a test easier to write, with no intent to
ever set it in production, consider adding test-only APIs to your classes.&lt;/li&gt;
  &lt;li&gt;Consider treating flags as private static variables. If other packages need
to access them, wrap them in functions.&lt;/li&gt;
  &lt;li&gt;Define your flags at global scope, not within a namespace, to get link
errors when flag names conflict.&lt;/li&gt;
  &lt;li&gt;If a flag is accessed in multiple files, declare it in one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.h&lt;/code&gt; file
corresponding to its definition.&lt;/li&gt;
  &lt;li&gt;Use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ABSL_FLAG(type, ...)&lt;/code&gt; macro to define flags.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;in-conclusion&quot;&gt;In Conclusion&lt;/h2&gt;

&lt;p&gt;Flags are global variables. Use them judiciously. Use and declare them as you
would any other global variable.&lt;/p&gt;
</description>
          <pubDate>2019-05-10T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/103</link>
          <guid isPermaLink="true">https://abseil.io/tips/103</guid>
        </item>
      
    
      
        <item>
          <title>Abseil Flags</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:rogeeff@google.com&quot;&gt;Gennadiy Rozental&lt;/a&gt;, Abseil Engineer&lt;/p&gt;

&lt;p&gt;Abseil is very happy to announce the release of the Abseil Flags
library. Abseil’s flags library provides a standard, readable way
to pass command-line values to a program.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;absl/flags/flag.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;absl/flags/parse.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ABSL_FLAG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;you&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Name of the person to greet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParseCommandLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetFlag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FLAGS_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;!&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;greet
Hello you!
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;greet &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Alice
Hello Alice!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--break--&gt;

&lt;p&gt;Flag variables of the following types are supported out of the box:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int32_t&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64_t&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint64_t&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;double&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;std::string&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Duration&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Time&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information, consult the
&lt;a href=&quot;/docs/cpp/guides/flags&quot;&gt;Abseil Flags library documentation&lt;/a&gt;.&lt;/p&gt;

</description>
          <pubDate>2019-05-09T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20190509-flags</link>
          <guid isPermaLink="true">https://abseil.io/blog/20190509-flags</guid>
        </item>
      
    
      
        <item>
          <title>Abseil Support for CMake</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:cohenjon@google.com&quot;&gt;Jon Cohen&lt;/a&gt;, Abseil Engineer&lt;/p&gt;

&lt;p&gt;CMake is a popular tool used to build multi-platform C++ projects.
Abseil has had unofficial CMake support for some time, but support
has never been as robust as that for Bazel. We are happy to
announce that Abseil now fully supports the CMake build system.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;Abseil supports CMake through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_subdirectory&lt;/code&gt; command for
full source inclusion, or by &lt;a href=&quot;/docs/cpp/tools/cmake-installs&quot;&gt;local installation&lt;/a&gt;
into your project. Future Abseil LTS releases will be supported
for installation in system-wide locations (such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local&lt;/code&gt;,
CMake’s default install location).&lt;/p&gt;

&lt;p&gt;We hope that this support will make it easier for users to adopt
Abseil and for package managers to successfully and easily
package Abseil.&lt;/p&gt;

&lt;p&gt;For more information on getting Abseil working with CMake, consult
our &lt;a href=&quot;/docs/cpp/quickstart-cmake&quot;&gt;CMake Quickstart&lt;/a&gt;&lt;/p&gt;

</description>
          <pubDate>2019-04-02T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20190402-cmake-support</link>
          <guid isPermaLink="true">https://abseil.io/blog/20190402-cmake-support</guid>
        </item>
      
    
      
        <item>
          <title>Automated Upgrade Tooling for Abseil</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:strel@google.com&quot;&gt;Alex Strelnikov&lt;/a&gt;, Abseil Engineer&lt;/p&gt;

&lt;p&gt;As we promised when we released our &lt;a href=&quot;/about/compatibility&quot;&gt;Compatibility Guidelines&lt;/a&gt;,
we have developed a process for announcing and handling any API-breaking
changes we may need to make within the Abseil code base. Our
&lt;a href=&quot;/docs/cpp/tools/api-upgrades&quot;&gt;C++ Automated Upgrade&lt;/a&gt; guide outlines this process,
which consists of &lt;a href=&quot;http://clang.llvm.org/extra/clang-tidy/&quot;&gt;clang-tidy&lt;/a&gt; tooling and associated
communication regarding the change. A list of all such tools will be
listed on our &lt;a href=&quot;/docs/cpp/tools/upgrades/&quot;&gt;Upgrade Tools&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;At this time, we are also releasing our first such tool: a clang-tidy check
for
&lt;a href=&quot;https://clang.llvm.org/extra/clang-tidy/checks/abseil-upgrade-duration-conversions.html&quot;&gt;removing bug-prone implicit conversions in calls to several
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Duration&lt;/code&gt; functions&lt;/a&gt;.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;As outlined in our upgrade guide, we will always first serve notice of
such a tool via this blog, and will also blog once we’ve officially
removed the deprecated API.&lt;/p&gt;

</description>
          <pubDate>2018-12-20T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/20181221-upgrade-tooling</link>
          <guid isPermaLink="true">https://abseil.io/blog/20181221-upgrade-tooling</guid>
        </item>
      
    
      
        <item>
          <title>CppCon 2018: Modern C++ Design</title>
          <description>&lt;h3 id=&quot;titus-winters-and-modern-c&quot;&gt;Titus Winters and Modern C++&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:shreck@google.com&quot;&gt;Tom Manshreck&lt;/a&gt;, Abseil Tech Writer&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://cppcon.org/cppcon-2018-program/&quot;&gt;CppCon 2018&lt;/a&gt; was held in
Bellevue, WA at the end of September.&lt;/p&gt;

&lt;p&gt;C++ has changed a lot since the transformative introduction of C++11.
It is now all too apparent that C++ API Design itself also needs to
change as the lessons learned about, for example, type design
become more understood.&lt;/p&gt;

&lt;p&gt;Titus Winters reflects on the changes to C++ and how the introduction
of new principles such as move-only types have affected API design
in this two-part talk.&lt;/p&gt;

&lt;p&gt;In the first part, Titus focuses on parameter passing and an API’s
overload set in providing a powerful conceptual framework for API
design. In the second part, we focus on the properties of well-designed
types, and how to think about things like Regularity. We discuss how
Regularity affects the design of non-owning reference types
like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you haven’t already, check out Titus’ original blog post on
&lt;a href=&quot;/blog/20180531-regular-types&quot;&gt;“Revisiting Regular Types”&lt;/a&gt; for more background
information.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=xTdeZ4MxbKo&quot; target=&quot;_blank&quot;&gt;
&lt;img src=&quot;/img/cppcon-modern-cpp-1.png&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=tn7oVNrPM8I&quot; target=&quot;_blank&quot;&gt;
&lt;img src=&quot;/img/cppcon-modern-cpp-2.png&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

</description>
          <pubDate>2018-11-29T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/20181129-moderncpp</link>
          <guid isPermaLink="true">https://abseil.io/blog/20181129-moderncpp</guid>
        </item>
      
    
      
        <item>
          <title>Civil Time in Abseil</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:jgm@google.com&quot;&gt;Greg Miller&lt;/a&gt;, &lt;a href=&quot;mailto:bww@google.com&quot;&gt;Bradley White&lt;/a&gt;,
and &lt;a href=&quot;mailto:shaindel@google.com&quot;&gt;Shaindel Schwartz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Almost every spring and fall there are news headlines about software that
misbehaved during a daylight-saving transition. In much of the world, DST
transitions occur multiple times per year, yet it is still a veritable
minefield of latent bugs due to the complexities inherent in reasoning
about civil-time discontinuities. To avoid these problems, a civil-time
library must present the programmer with a correct — yet simplified — model
that makes expressing the desired intent easy and writing bugs more obvious.&lt;/p&gt;

&lt;p&gt;To that end, we are very pleased to introduce a new feature for the Abseil
time library — civil time support. This update adds a set of constructs and
functions that are used to represent and perform computations with civil
times.&lt;/p&gt;

&lt;!--break--&gt;

&lt;h2 id=&quot;abseil-time-constructs&quot;&gt;Abseil Time Constructs&lt;/h2&gt;

&lt;p&gt;When discussing time, we refer to two representations: absolute time, which
represents a specific instant in time, and civil time, which represents the
year, month, day, hour, minute and second (YYYY-MM-DD hh:mm:ss) of local,
human-scale time. A “date,” for example, is a civil time - the legal, local
name for the time that we are describing. A time zone defines the
relationship between an absolute time and the civil time to which it
corresponds:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/docs/cpp/guides/images/time-concepts.png&quot; style=&quot;margin:5px;&quot; alt=&quot;Absolute and Civil Time Relationships&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The Abseil time library provides six new classes for representing civil times:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::CivilSecond&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::CivilMinute&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::CivilHour&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::CivilDay&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::CivilMonth&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::CivilYear&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are all &lt;a href=&quot;/blog/20180531-regular-types&quot;&gt;“value types”&lt;/a&gt; that enable easy and type-safe
computations with civil times of varying alignment. They give you a clear
vocabulary with which you can easily express your intent to the compiler
and fellow humans.&lt;/p&gt;

&lt;h2 id=&quot;converting-between-absolute-and-civil-times&quot;&gt;Converting Between Absolute and Civil Times&lt;/h2&gt;

&lt;p&gt;The Abseil time library provides a set of functions to convert an absolute
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Time&lt;/code&gt; and an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::TimeZone&lt;/code&gt; to a civil time:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::ToCivilSecond()&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::ToCivilMinute()&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::ToCivilHour()&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::ToCivilDay()&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::ToCivilMonth()&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::ToCivilYear()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TimeZone&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tz&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CivilDay&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ToCivilDay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The Abseil time library also provides the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FromCivil()&lt;/code&gt; function to convert a
civil time of any alignment and an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::TimeZone&lt;/code&gt; to an absolute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Time&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FromCivil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CivilSecond&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TimeZone&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tz&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FromCivil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;more-information&quot;&gt;More Information&lt;/h2&gt;

&lt;p&gt;For more complete information, see the &lt;a href=&quot;/docs/cpp/guides/time&quot;&gt;Abseil time library documentation&lt;/a&gt;.
Complete reference documentation is available within the
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/tree/master/absl/time&quot;&gt;Abseil time library header files&lt;/a&gt;.&lt;/p&gt;

</description>
          <pubDate>2018-10-10T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20181010-civil-time</link>
          <guid isPermaLink="true">https://abseil.io/blog/20181010-civil-time</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #153: Don&apos;t Use using-directives</title>
          <description>&lt;p&gt;Originally posted as TotW #153 on July 17, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:roman.perepelitsa@gmail.com&quot;&gt;Roman Perepelitsa&lt;/a&gt; and &lt;a href=&quot;mailto:ahedberg@google.com&quot;&gt;Ashley Hedberg&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/153&quot;&gt;abseil.io/tips/153&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I view using-directives as time-bombs, both for the parties that deal in them
and the language system.&lt;/strong&gt; – &lt;em&gt;Ashley Hedberg&lt;/em&gt; with apologies to Warren Buffett&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;Using-directives (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using namespace foo&lt;/code&gt;) are dangerous enough to be banned by
the
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Namespaces&quot;&gt;Google style guide&lt;/a&gt;.
Don’t use them in code that will ever need to be upgraded.&lt;/p&gt;

&lt;p&gt;If you wish to shorten a name, you may instead use a namespace alias (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespace
baz = ::foo::bar::baz;&lt;/code&gt;) or a using-declaration (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using ::foo::SomeName&lt;/code&gt;), both
of which are permitted by the style guide in certain contexts (e.g. in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.cc&lt;/code&gt;
files).&lt;/p&gt;

&lt;h2 id=&quot;using-directives-at-function-scope&quot;&gt;Using-directives at Function Scope&lt;/h2&gt;

&lt;p&gt;What do you think this code does?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
namespace totw {
namespace example {
namespace {

TEST(MyTest, UsesUsingDirectives) {
  using namespace ::testing;
  Sequence seq;  // ::testing::Sequence
  WallTimer timer;  // ::WallTimer
  ...
}

}  // namespace
}  // namespace example
}  // namespace totw
&lt;/pre&gt;

&lt;p&gt;The vast majority of C++ users think that the using-directive is injecting names
into the scope where it’s declared. In the example above, that would be the
scope of the function. In reality, the names are injected into the nearest
common ancestor of the target namespace (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::testing&lt;/code&gt;) and the usage namespace
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::totw::example::anonymous&lt;/code&gt;) while the using directive is in scope. In our
example, &lt;strong&gt;that’s the global namespace&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Thus, the code is roughly equivalent to the following:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
using ::testing::Expectation;
using ::testing::Sequence;
using ::testing::UnorderedElementsAre;
...
// many, many more symbols are injected into the global namespace

namespace totw {
namespace example {
namespace {

TEST(MyTest, UsesUsingDirectives) {
  Sequence seq; // ::testing::Sequence
  WallTimer timer; // ::WallTimer
  ...
}

} // namespace
} // namespace example
} // namespace totw
&lt;/pre&gt;

&lt;p&gt;This transformation is not exactly correct, as the names do not actually &lt;em&gt;stay&lt;/em&gt;
visible outside the scope of the using-directive. However, even a temporary
injection into the global scope has some unfortunate consequences.&lt;/p&gt;

&lt;p&gt;Let’s see what kind of changes can break this code:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If anyone defines &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::totw::Sequence&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::totw::example::Sequence&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;seq&lt;/code&gt;
will now refer to that entity instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::testing::Sequence&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;If anyone defines &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::Sequence&lt;/code&gt;, the definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;seq&lt;/code&gt; will fail to
compile, as the reference to the name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sequence&lt;/code&gt; will be ambiguous.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sequence&lt;/code&gt; could mean &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::testing::Sequence&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::Sequence&lt;/code&gt;, and the
compiler doesn’t know which one you wanted.&lt;/li&gt;
  &lt;li&gt;If anyone defines &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::testing::WallTimer&lt;/code&gt;, the definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;timer&lt;/code&gt; will
fail to compile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thus, a single using-directive in a function scope has placed naming
restrictions on symbols in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::testing&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::totw&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::totw::example&lt;/code&gt;, and the
global namespace. &lt;strong&gt;Allowing this using-directive, even if only in function
scope, creates ample opportunities for name clashes in the global and other
namespaces.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If that example doesn’t look fragile enough, consider this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
namespace totw {
namespace example {
namespace {

TEST(MyTest, UsesUsingDirectives) {
  using namespace ::testing;
  EXPECT_THAT(..., proto::Partially(...)); // ::testing::proto::Partially
  ...
}

} // namespace
} // namespace example
} // namespace totw
&lt;/pre&gt;

&lt;p&gt;This using-directive has &lt;strong&gt;introduced a namespace alias&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proto&lt;/code&gt; in the global
namespace, roughly equivalent to the following:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
namespace proto = ::testing::proto;

namespace totw {
namespace example {
namespace {

TEST(MyTest, UsesUsingDirectives) {
  EXPECT_THAT(..., proto::Partially(...)); // ::testing::proto::Partially
  ...
}

} // namespace
} // namespace example
} // namespace totw
&lt;/pre&gt;

&lt;p&gt;The test will keep compiling until a header defining namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::proto&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::totw::proto&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::totw::example::proto&lt;/code&gt; gets included transitively. At that
point in time, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proto::Partially&lt;/code&gt; becomes ambiguous, and the test stops
compiling. This ties into the style guide’s rules on namespace naming: avoid
nested namespaces, and don’t use common names for nested namespaces. (See
&lt;a href=&quot;/tips/130&quot;&gt;Tip #130&lt;/a&gt; and
https://google.github.io/styleguide/cppguide.html#Namespace_Names for more on
this topic.)&lt;/p&gt;

&lt;p&gt;One might think that it’s safe to employ a using-directive for a closed
namespace that has few symbols and guarantees that no more symbols will be ever
added to it. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::placeholders&lt;/code&gt;, which contains symbols &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_1&lt;/code&gt; … &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_9&lt;/code&gt;, is an
example of such a namespace.) However, even that isn’t safe: it precludes any
other namespace from introducing symbols with the same names. In this sense,
using-directives defeat the modularity provided by namespaces.&lt;/p&gt;

&lt;h2 id=&quot;unqualified-using-directives&quot;&gt;Unqualified using-directives&lt;/h2&gt;

&lt;p&gt;We’ve seen how one using-directive can go wrong. What happens if we have many of
them, unqualified, in the same codebase?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
namespace totw {
namespace example {
namespace {

using namespace rpc;
using namespace testing;

TEST(MyTest, UsesUsingDirectives) {
  Sequence seq;  // ::testing::Sequence
  WallTimer timer;  // ::WallTimer
  RPC rpc;  // ...is this ::rpc::RPC or ::RPC?
  ...
}

}  // namespace
}  // namespace example
}  // namespace totw
&lt;/pre&gt;

&lt;p&gt;What could possibly go wrong here? A lot, as it turns out:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;All the problems from our function-level example still exist, but two-fold:
once for namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::testing&lt;/code&gt;, and once for namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::rpc&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;If namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::rpc&lt;/code&gt; and namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::testing&lt;/code&gt; declare symbols with the same
name, this code won’t compile if it does unqualified lookup on one of those
names. This is important, because it demonstrates a terrifying scaling
problem: since the full contents of each namespace is (generally speaking)
injected into the global namespace, &lt;strong&gt;every new using-directive could add
quadratic risk of name collisions and build failures.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;If a sub-namespace such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::rpc::testing&lt;/code&gt; is ever introduced, this code
will stop compiling. (We have actually seen that namespace, so it is
potentially just a matter of time until this snippet and that namespace are
built together. Another reason to
&lt;a href=&quot;/tips/130&quot;&gt;avoid deeply nested namespaces&lt;/a&gt;). The lack of namespace
qualification is important here: this snippet may have compiled if the
using-directives were fully-qualified &lt;em&gt;and&lt;/em&gt; if there were no unqualified
lookups on names common to both namespaces.&lt;/li&gt;
  &lt;li&gt;A newly-introduced symbol in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::totw::example&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::totw&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::testing&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::rpc&lt;/code&gt;, or the global namespace could collide with an existing symbol in
&lt;em&gt;any of those namespaces&lt;/em&gt;. That’s a big matrix of possibilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A brief aside: What namespace do you think &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RPC&lt;/code&gt; lives in? &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rpc&lt;/code&gt; would have been
a perfectly reasonable guess, but it actually lives in the global namespace.
Maintainability issues aside, the using-directives here make this code hard to
read.&lt;/p&gt;

&lt;h2 id=&quot;why-do-we-have-this-feature-then&quot;&gt;Why Do We Have This Feature, Then?&lt;/h2&gt;

&lt;p&gt;There are legitimate uses of using-directives within generic libraries, but they
are so obscure and rare that they don’t deserve a mention here or in the style
guide.&lt;/p&gt;

&lt;h2 id=&quot;parting-words&quot;&gt;Parting Words&lt;/h2&gt;

&lt;p&gt;Using-directives are time-bombs: code that compiles today could easily stop
compiling with the next language version or symbol addition. For external code
that is short-lived and whose dependencies never change, this may be an
acceptable risk. But beware: if you later decide that you want your short-lived
project to continue working &lt;em&gt;over time&lt;/em&gt;, those time-bombs may explode.&lt;/p&gt;
</description>
          <pubDate>2018-09-30T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/153</link>
          <guid isPermaLink="true">https://abseil.io/tips/153</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #152: &lt;code&gt;AbslHashValue&lt;/code&gt; and You</title>
          <description>&lt;p&gt;Originally posted as TotW #152 on June 21, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:kfm@google.com&quot;&gt;Matt Kulukundis&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/152&quot;&gt;abseil.io/tips/152&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I love Mozart, but I often make a terrible hash of it.&lt;/strong&gt; – &lt;em&gt;Simon Rattle&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt; framework [https://abseil.io/docs/cpp/guides/hash] is now the
default hash implementation for the Swisstable family of hash tables
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::{flat,node}_hash_{set,map}&lt;/code&gt;). All types hashable by this framework will
automatically be useable as keys in Swisstables.&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-use-it&quot;&gt;How Do I Use It?&lt;/h2&gt;

&lt;p&gt;Let’s say we have a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Song&lt;/code&gt; struct (let’s agree that a song can be
uniquely identified by these fields):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Song {
  std::string name;
  std::string artist;
  absl::Duration duration;
};
&lt;/pre&gt;

&lt;p&gt;and we want to be able to store an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_set&amp;lt;Song&amp;gt;&lt;/code&gt; or an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&amp;lt;Song, CopyrightOwner&amp;gt;&lt;/code&gt;. All we have to do is add a simple
friend function like:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct Song {
  std::string name;
  std::string artist;
  absl::Duration duration;

  template &amp;lt;typename H&amp;gt;
  friend H AbslHashValue(H h, const Song&amp;amp; s) {
    return H::combine(std::move(h), s.name, s.artist, s.duration);
  }

  // Include your implementation of operator == and != here
};
&lt;/pre&gt;

&lt;p&gt;and everything will work!&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-test-it&quot;&gt;How Do I Test It?&lt;/h2&gt;

&lt;p&gt;We provide &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::VerifyTypeImplementsAbslHashCorrectly&lt;/code&gt; to verify that a type
implements its overload correctly. This function has a few requirements:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The type must implement the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;==&lt;/code&gt; operator correctly.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The caller must provide instances of the type that include any interesting
representations for their type. (For example, a type with a small size
optimization should include equivalent instances that use the small size
optimization and that do not.)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
TEST(MyType, SupportsAbslHash) {
  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
      MyType(),
      MyType(1, 2),
      MyType(2, 3),
      MyType(0, 0),
  }));
}
&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::VerifyTypeImplementsAbslHashCorrectly&lt;/code&gt; also supports testing heterogeneous
lookup and custom equality operators.&lt;/p&gt;

&lt;p&gt;Intrigued and want to know more? Read up at
https://abseil.io/docs/cpp/guides/hash.&lt;/p&gt;
</description>
          <pubDate>2018-09-28T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/152</link>
          <guid isPermaLink="true">https://abseil.io/tips/152</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #144: Heterogeneous Lookup in Associative Containers</title>
          <description>&lt;p&gt;Originally posted as TotW #144 on March 23, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:sbenza@google.com&quot;&gt;Samuel Benzaquen&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/144&quot;&gt;abseil.io/tips/144&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Associative containers associate an element with a key. Inserting into or
looking up an element from the container requires an equivalent key. In general,
containers require the keys to be of a specific type, which can lead to
inefficiencies at call sites that need to convert between near-equivalent types
(like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;To avoid this unnecessary work, some containers provide &lt;em&gt;heterogeneous lookup&lt;/em&gt;.
This feature allows callers to pass keys of any type (as long as the
user-specified comparator functor supports them). See
&lt;a href=&quot;http://en.cppreference.com/w/cpp/container/map/find&quot;&gt;std::map::find&lt;/a&gt; for an
example of this feature in an STL container.&lt;/p&gt;

&lt;h2 id=&quot;transparent-functors&quot;&gt;Transparent Functors&lt;/h2&gt;

&lt;p&gt;A transparent functor is one that accepts more than one particular type. It
&lt;em&gt;must&lt;/em&gt; publicize this fact by providing an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_transparent&lt;/code&gt; inner type. The
actual definition of this inner type is not relevant as it is used merely as a
tag. It is common to use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using&lt;/code&gt; declaration of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_transparent&lt;/code&gt; set to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When a container detects a transparent functor their lookup functions will
forward the user specified value intact instead of converting it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key_type&lt;/code&gt;
first (through implicit or explicit conversion).&lt;/p&gt;

&lt;p&gt;Implicitly supporting heterogeneous lookup can be dangerous, as the relationship
between values might not be maintained after conversions. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.0 &amp;lt;
1.1&lt;/code&gt;, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static_cast&amp;lt;int&amp;gt;(1.0) == static_cast&amp;lt;int&amp;gt;(1.1)&lt;/code&gt;. Thus, using a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;double&lt;/code&gt; to look up a value in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::set&amp;lt;int&amp;gt;&lt;/code&gt; could lead to incorrect
results. These potential bugs are the reason this feature is opt-in.&lt;/p&gt;

&lt;h2 id=&quot;using-heterogeneous-lookup-for-performance&quot;&gt;Using Heterogeneous Lookup For Performance&lt;/h2&gt;

&lt;p&gt;One common reason for using heterogeneous lookup is performance. We could
construct the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key_type&lt;/code&gt;, but doing so requires non-trivial work that we would
rather avoid. For example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
std::map&amp;lt;std::string, int&amp;gt; m = ...;
absl::string_view some_key = ...;
// Construct a temporary `std::string` to do the query.
// The allocation + copy + deallocation might dominate the find() call.
auto it = m.find(std::string(some_key));
&lt;/pre&gt;

&lt;p&gt;Instead, we can use a transparent comparator like so:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct StringCmp {
  using is_transparent = void;
  bool operator()(absl::string_view a, absl::string_view b) const {
    return a &amp;lt; b;
  }
};

std::map&amp;lt;std::string, int, StringCmp&amp;gt; m = ...;
absl::string_view some_key = ...;
// The comparator `StringCmp` will accept any type that is implicitly
// convertible to `absl::string_view` and says so by declaring the
// `is_transparent` tag.
// We can pass `some_key` to `find()` without converting it first to
// `std::string`. In this case, that avoids the unnecessary memory allocation
// required to construct the `std::string` instance.
auto it = m.find(some_key);
&lt;/pre&gt;

&lt;h2 id=&quot;what-else-is-it-good-for&quot;&gt;What Else Is It Good For?&lt;/h2&gt;

&lt;p&gt;Cases exist where it is impossible or inconvenient to create a valid &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key_type&lt;/code&gt;
object just to do a lookup. In those cases, we might want to use an alternative
type that is much easier to produce, but contains the necessary information for
the lookup. For example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
struct ThreadCmp {
  using is_transparent = void;
  // Regular overload.
  bool operator()(const std::thread&amp;amp; a, const std::thread&amp;amp; b) const {
    return a.get_id() &amp;lt; b.get_id();
  }
  // Transparent overloads
  bool operator()(const std::thread&amp;amp; a, std::thread::id b) const {
    return a.get_id() &amp;lt; b;
  }
  bool operator()(std::thread::id a, const std::thread&amp;amp; b) const {
    return a &amp;lt; b.get_id();
  }
  bool operator()(std::thread::id a, std::thread::id b) const {
    return a &amp;lt; b;
  }
};

std::set&amp;lt;std::thread, ThreadCmp&amp;gt; threads = ...;
// Can&apos;t construct an instance of `std::thread` with the same id, just to do the lookup.
// But we can look up by id instead.
std::thread::id id = ...;
auto it = threads.find(id);

&lt;/pre&gt;

&lt;h2 id=&quot;stl-container-support-and-alternatives&quot;&gt;STL Container Support and Alternatives&lt;/h2&gt;

&lt;p&gt;The standard ordered containers (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::{map,set,multimap,multiset}&lt;/code&gt;) support
heterogeneous lookup. The standard &lt;em&gt;unordered&lt;/em&gt; containers
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_{map,set,multimap,multiset}&lt;/code&gt;) do not support heterogeneous
lookup until &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C++20&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The new family of &lt;a href=&quot;https://abseil.io/docs/cpp/guides/container&quot;&gt;Swiss Tables&lt;/a&gt;, however, support heterogeneous
lookup for both string-like types (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;, etc.) and
smart pointers (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T*&lt;/code&gt;,&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::shared_ptr&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;). They require both
the hasher and the equality function to be tagged as transparent. All other key
types require explicit opt-in from the user.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://abseil.io/docs/cpp/guides/container&quot;&gt;B-Tree&lt;/a&gt; containers (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::btree_{set,map,multiset,multimap}&lt;/code&gt;) also
support heterogeneous lookup.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;protobuf&quot;&gt;Protocol Buffers’&lt;/a&gt; associative map’s implementation,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;google::protobuf::Map&lt;/code&gt;, supports heterogeneous lookup when the map is keyed
with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; using string-like keys (any type that is convertible to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;).&lt;/p&gt;

</description>
          <pubDate>2018-09-28T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/144</link>
          <guid isPermaLink="true">https://abseil.io/tips/144</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #136: Unordered Containers</title>
          <description>&lt;p&gt;Originally posted as TotW #136 on June 23, 2017&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:kfm@google.com&quot;&gt;Matt Kulukundis&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/136&quot;&gt;abseil.io/tips/136&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Sometimes, when the material is really good, you put expectations on yourself
to make it the best possible show. You’re not just serving up the regular hash
and doing your job and going home.”&lt;/em&gt; — Peter Dinklage&lt;/p&gt;

&lt;p&gt;TL;DR: See https://abseil.io/docs/cpp/guides/container for official and
up-to-date recommendations. This tip &lt;em&gt;introduced&lt;/em&gt; the new types, but is not the
canonical reference.&lt;/p&gt;

&lt;h2 id=&quot;introducing-absl_hash_map&quot;&gt;Introducing &lt;code&gt;absl::*_hash_map&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;There is a new family of associative containers in town. They boast improvements
to efficiency and provide early access to APIs from C++17. They also provide
developers with direct control over their implementation and default hash
functions, which is important for the long term evolution of a code base. New
code should prefer these types over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt; . All of the maps and
sets in this family have APIs that are nearly identical to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt;,
so transitioning to them is easy.&lt;/p&gt;

&lt;p&gt;For every &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::*_hash_map&lt;/code&gt; there is also an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::*_hash_set&lt;/code&gt;; however, the
diagrams will only depict the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; case and we will often refer to just the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;abslflat_hash_map-and-abslflat_hash_set&quot;&gt;&lt;code&gt;absl::flat_hash_map&lt;/code&gt; and &lt;code&gt;absl::flat_hash_set&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/img/flat_hash_map.svg&quot; style=&quot;margin:5px;width:50%&quot; alt=&quot;Flat Hash Map Memory Layout&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These should be your default choice. They store their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_type&lt;/code&gt; inside the
main array. Because they move data when they rehash, elements don’t get pointer
stability. If you need pointer stability or your values are large, consider
using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_map&lt;/code&gt; instead, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&amp;lt;Key,
std::unique_ptr&amp;lt;Value&amp;gt;&amp;gt;&lt;/code&gt;, possibly.&lt;/p&gt;

&lt;p&gt;Warning: Because of pointer instability after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rehash()&lt;/code&gt; code like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map[&quot;a&quot;] =
map[&quot;b&quot;]&lt;/code&gt; will access invalidated memory.&lt;/p&gt;

&lt;h3 id=&quot;abslnode_hash_map-and-abslnode_hash_set&quot;&gt;&lt;code&gt;absl::node_hash_map&lt;/code&gt; and &lt;code&gt;absl::node_hash_set&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/img/node_hash_map.svg&quot; style=&quot;margin:5px;width:50%&quot; alt=&quot;Node Hash Map Memory L ayout&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These allocate their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_type&lt;/code&gt; in nodes outside of the main array (like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt;). Because of the separate allocation, they provide pointer
stability (the address of objects stored in the map does not change) for the
stored data and empty slots only require 8 bytes. Additionally, they can store
things that are neither moveable nor copyable.&lt;/p&gt;

&lt;p&gt;We generally recommend that you use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&amp;lt;K, std::unique_ptr&amp;lt;V&amp;gt;&amp;gt;&lt;/code&gt;
instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_map&amp;lt;K, V&amp;gt;&lt;/code&gt;, and similarly for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;node_hash_set&lt;/code&gt;.&lt;/p&gt;
</description>
          <pubDate>2018-09-28T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/136</link>
          <guid isPermaLink="true">https://abseil.io/tips/136</guid>
        </item>
      
    
      
        <item>
          <title>Swiss Tables and &lt;code&gt;absl::Hash&lt;/code&gt;</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:sbenza@google.com&quot;&gt;Sam Benzaquen&lt;/a&gt;,
&lt;a href=&quot;mailto:alkis@google.com&quot;&gt;Alkis Evlogimenos&lt;/a&gt;,
&lt;a href=&quot;mailto:kfm@google.com&quot;&gt;Matt Kulukundis&lt;/a&gt;, and
&lt;a href=&quot;mailto:roman.perepelitsa@gmail.com&quot;&gt;Roman Perepelitsa&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are extremely pleased to announce the availability of the new “Swiss Table” 
family of hashtables in Abseil and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt; hashing framework that 
allows easy extensibility for user defined types.&lt;/p&gt;

&lt;p&gt;Last year at CppCon, We presented a &lt;a href=&quot;https://www.youtube.com/watch?v=ncHmEUmJZf4&amp;amp;t=3s&quot;&gt;talk&lt;/a&gt; on a new hashtable that
we were rolling out across Google’s codebase. When asked about its release 
date, we may have been a touch optimistic. But hopefully it will have been 
worth the wait. As an added bonus, this release also comes with an entirely new 
framework for hashing your types. As with all things of this size, this is the 
work of a great many people.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;Swiss Tables boast improvements to efficiency and provide C++11 codebases early
access to APIs from C++17 and C++20.&lt;/p&gt;

&lt;p&gt;These hash tables live within the &lt;a href=&quot;https://github.com/abseil/abseil-cpp/tree/master/absl/container&quot;&gt;Abseil &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;container&lt;/code&gt; library&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;abslflat_hash_map-and-abslflat_hash_set&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_set&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/img/flat_hash_map.svg&quot; style=&quot;margin:5px;width:30%&quot; alt=&quot;Flat Hash Map Memory Layout&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The “flat” Swiss tables should be your default choice. They store their 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_type&lt;/code&gt; inside the container’s main array to avoid memory indirections. 
Because they move data when they rehash, elements do not get pointer stability. 
If you require pointer stability or your values are large, consider using an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_map&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_set&lt;/code&gt; (or an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&amp;lt;Key, std::unique_ptr&amp;lt;Value&amp;gt;&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;h3 id=&quot;abslnode_hash_map-and-abslnode_hash_set&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_map&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_set&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/img/node_hash_map.svg&quot; style=&quot;margin:5px;width:30%&quot; alt=&quot;Node Hash Map Memory Layout&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The “node” Swiss tables allocate their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_type&lt;/code&gt; in nodes outside of the 
main array (as in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&lt;/code&gt;). Because of the separate allocation,
they provide pointer stability (the address of objects stored in the map does
not change). As well, the stored data and empty slots only require 8 bytes. 
Additionally, they can store things that are neither moveable nor copyable.&lt;/p&gt;

&lt;p&gt;We generally recommend that you use
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::flat_hash_map&amp;lt;K, std::unique_ptr&amp;lt;V&amp;gt;&amp;gt;&lt;/code&gt; instead of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::node_hash_map&amp;lt;K, V&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For more information about Swiss tables, see the
&lt;a href=&quot;http://abseil.io/docs/cpp/guides/container&quot;&gt;Abseil &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;container&lt;/code&gt; library documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-abslhash-hashing-framework&quot;&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt; hashing framework&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/abseil/abseil-cpp/tree/master/absl/hash&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt; library&lt;/a&gt; consists of two parts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&amp;lt;T&amp;gt;&lt;/code&gt;, a concrete hash functor object, which you can use out of 
the box&lt;/li&gt;
  &lt;li&gt;A generic hashing framework for specializing hashing behavior and making user-defined types hashable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This library is designed to be used as a replacement for 
&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/hash&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::hash&lt;/code&gt;&lt;/a&gt; and the various other hash functors. It provides
several advantages over them:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It can hash objects of almost any standard type, including &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair&lt;/code&gt;, 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::tuple&lt;/code&gt;, and most standard containers.&lt;/li&gt;
  &lt;li&gt;It can be extended to support user-defined types. Our goal is that if it 
makes sense to hash an object of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&amp;lt;Foo&amp;gt;&lt;/code&gt; will 
just work. These extensions are easy to write and efficient to execute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Importantly, the underlying hash algorithm can be changed without modifying
user code, which allows us to improve both it and types which utilize 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt; over time. For example, we might wish to change the hashing 
algorithm within a container to improve performance and to defend against some
hash-flooding attacks.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Hash&lt;/code&gt; framework is the default hash implementation for the Swiss 
tables and does not need to be explicitly specified when working with that 
library.&lt;/p&gt;

&lt;p&gt;For more information, see the &lt;a href=&quot;http://abseil.io/docs/cpp/guides/hash&quot;&gt;Abseil &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hash&lt;/code&gt; library documentation&lt;/a&gt;.&lt;/p&gt;

</description>
          <pubDate>2018-09-27T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20180927-swisstables</link>
          <guid isPermaLink="true">https://abseil.io/blog/20180927-swisstables</guid>
        </item>
      
    
      
        <item>
          <title>Abseil Python Docs are Here!</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:junjay@junjaytan.com&quot;&gt;Junjay Tan&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Abseil Python now includes a documentation set on abseil.io!&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;Abseil Python provides various libraries for building Python applications. This
code is collected from Google’s internal Python code base and has been
extensively tested and used in production. They provide features for application
startup, distributed command line flags, custom logging, and testing.&lt;/p&gt;

&lt;p&gt;Until now, the only documentation for Abseil Python has been in the source code.
This was comprehensive but did not always provide information for new users in 
an easy-to-read format.&lt;/p&gt;

&lt;p&gt;We’re happy to announce an Abseil
&lt;a href=&quot;/docs/python/quickstart&quot;&gt;Python Quickstart Guide&lt;/a&gt; and module-specific
&lt;a href=&quot;/docs/python/guides/&quot;&gt;programming guides&lt;/a&gt;  similar to those for Abseil C++.
These guides are patterned after those used internally at Google to onboard new
Googlers (nooglers), and we hope they will be similarly helpful to you!&lt;/p&gt;
</description>
          <pubDate>2018-08-31T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20180831-python-docs</link>
          <guid isPermaLink="true">https://abseil.io/blog/20180831-python-docs</guid>
        </item>
      
    
      
        <item>
          <title>Clang-Tidy Checks for Abseil</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:garciadeannam5@gmail.com&quot;&gt;Deanna Garcia&lt;/a&gt; and
&lt;a href=&quot;mailto:hugogonzalez810@gmail.com&quot;&gt;Hugo Gonzalez&lt;/a&gt;, Abseil Interns&lt;/p&gt;

&lt;p&gt;Abseil wants to help developers avoid common mistakes unique to our collection
of libraries. Therefore, we have developed a set of clang-tidy checks for
Abseil, allowing you to catch these errors early on before they become
bigger problems.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;&lt;a href=&quot;http://clang.llvm.org/extra/clang-tidy/&quot;&gt;Clang-Tidy&lt;/a&gt;) is a useful tool to help
developers write C++ code in a correct and efficient manner. Clang-Tidy now
supports a set of Abseil checks designed to diagnose and fix typical programming
errors specific to Abseil including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Compatibility guideline violations&lt;/li&gt;
  &lt;li&gt;Style violations&lt;/li&gt;
  &lt;li&gt;Interface misuse&lt;/li&gt;
  &lt;li&gt;Bugs that can be deduced via static analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We hope that these checks will help projects that depend on Abseil have high
standards of code quality.&lt;/p&gt;

&lt;p&gt;Our checks can be found on llvm’s &lt;strong&gt;clang-tools-extra&lt;/strong&gt; repository, in the
&lt;a href=&quot;https://github.com/llvm-mirror/clang-tools-extra/tree/master/clang-tidy/abseil&quot;&gt;&lt;strong&gt;clang-tidy/abseil&lt;/strong&gt; directory&lt;/a&gt;.
The following checks have been released:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Duration Division Check&lt;/li&gt;
  &lt;li&gt;Faster StrSplit Delimiter Check&lt;/li&gt;
  &lt;li&gt;No Internal Dependencies Check&lt;/li&gt;
  &lt;li&gt;No Namespace Check&lt;/li&gt;
  &lt;li&gt;Redundant StrCat Calls Check&lt;/li&gt;
  &lt;li&gt;StrCat-Append Check&lt;/li&gt;
  &lt;li&gt;String Find Starts with Check&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information, consult Abseil’s &lt;a href=&quot;/docs/cpp/tools/clang-tidy&quot;&gt;Clang-Tidy Check Guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also write your own checks and share them with the Abseil community. For more
information on clang-tidy, and if you are interested in learning more to get involved
in writing your own Abseil clang-tidy checks, consult the
&lt;a href=&quot;http://clang.llvm.org/extra/clang-tidy/&quot;&gt;Clang-Tidy documentation&lt;/a&gt;.&lt;/p&gt;
</description>
          <pubDate>2018-08-30T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20180830-clang-tidy</link>
          <guid isPermaLink="true">https://abseil.io/blog/20180830-clang-tidy</guid>
        </item>
      
    
      
        <item>
          <title>Coroutine Types</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:titus@google.com&quot;&gt;Titus Winters&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first hint of standard library design that takes advantage of coroutines
(&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1056r0.html&quot;&gt;P1056&lt;/a&gt;) 
came through the Library Evolution Working Group (LEWG, responsible for design 
for the C++ standard library) during the Rapperswil meeting this summer. It was
… surprising. As much as I want coroutines in the language, the design smell
here was disconcerting. I want to point out what LEWG saw before we commit to
this direction irrevocably - coroutine types as currently designed are baffling.&lt;/p&gt;

&lt;!--break--&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;Coroutines are an important new language feature for C++, but also a very old 
idea.  In its current incarnation, the major force behind Coroutines in C++ is 
Gor Nishanov (whom I absolutely love working with).  If you aren’t familiar 
with the history, or want a refresher on how Coroutines are a generalization of 
subroutines (function calls), try watching Gor’s talk from CppCon 2015:
“&lt;a href=&quot;https://www.youtube.com/watch?v=_fu0gx-xseY&quot;&gt;C++ Coroutines, a negative overhead abstraction.&lt;/a&gt;”&lt;/p&gt;

&lt;p&gt;In a function call/subroutine world, the caller invokes some function, the 
function runs, and then the function returns execution control to the caller. 
We’re all familiar with this. In an asynchronous programming model we often 
have a logically-related sequence of operations we want to execute (for 
instance, kicking off a sequence of async operations one by one) but cannot 
express as a single function, because we need to jump in and out of that flow 
of control. As a result, all necessary state gets bundled up and passed around 
as a “continuation,” to be invoked at some point in the future. This is
generally known as
&lt;a href=&quot;https://en.wikipedia.org/wiki/Continuation-passing_style&quot;&gt;continuation passing&lt;/a&gt;
and you see it in languages/libraries/frameworks that are very 
functional-style, very asynchronous, or very callback-driven. It’s powerful,
but not nearly as clear as direct style programming.&lt;/p&gt;

&lt;p&gt;Coroutines are an attempt to provide a language-level ability to write in a 
direct style and execute in a continuation-passing style. For example, consider
an example from &lt;a href=&quot;http://wg21.link/P1056&quot;&gt;P1056&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;save_record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modify_record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;co_await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Look, ma, no blocking!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;co_await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;save_record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this snippet we’re imagining a to-be-specified type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::task&amp;lt;T&amp;gt;&lt;/code&gt; that is 
in many ways a lighter-weight &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::future&amp;lt;T&amp;gt;&lt;/code&gt;. It isn’t promising anything to 
do with concurrency or synchronization, and has no allocation or shared state. 
Functions that return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::task&lt;/code&gt; are coroutines - they can suspend (by calling 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_await&lt;/code&gt;) and return execution to the caller - leaving any variables local to 
the coroutine’s stack intact.&lt;/p&gt;

&lt;p&gt;A caller can invoke &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modify_record()&lt;/code&gt; as a coroutine, allowing the caller to be 
part of the continuation chain.  This requires returning a coroutine-enabled 
type like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::task&amp;lt;&amp;gt;&lt;/code&gt; - but note that the types don’t have to line up.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;About to modify&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;co_await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modify_record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Done modifying&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In such an invocation, the two log statements will happen in order, but all 
sorts of computation may happen in the caller of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f()&lt;/code&gt; between the two log 
outputs, because execution is yielded at the point of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_await&lt;/code&gt; “call” to 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modify_record()&lt;/code&gt;. (This is expected: that is the whole point of coroutines.)&lt;/p&gt;

&lt;p&gt;Note that because any function that uses the new coroutine keywords is now by 
definition a coroutine, there are some potential surprises. For example, if we 
were to invoke &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f()&lt;/code&gt; directly:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;invoke_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This (maybe) compiles, but generates none of the logging output because the 
body of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f()&lt;/code&gt; is not executed at all until something invokes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_await&lt;/code&gt; on the 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&lt;/code&gt; returned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f()&lt;/code&gt; - which we just ignored.  Many/most coroutine types 
are thus expected to be marked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[[nodiscard]]&lt;/code&gt; - there is no point in calling a 
function that returns a type like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::task&amp;lt;&amp;gt;&lt;/code&gt; without operating on the task. 
(Remember: pay attention to those &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[[nodiscard]]&lt;/code&gt; warnings!)&lt;/p&gt;

&lt;p&gt;The current specification provides no way for an ordinary (non-coroutine) 
function to usefully invoke a coroutine that returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&amp;lt;T&amp;gt;&lt;/code&gt; nor to obtain 
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; that it wraps. In order to invoke &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f()&lt;/code&gt; like a function we would need 
some special coroutine-execution machinery - the
&lt;a href=&quot;https://github.com/lewissbaker/cppcoro&quot;&gt;cppcoro repository&lt;/a&gt; provides this in 
the form of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sync_wait()&lt;/code&gt; function. The specification of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sync_wait()&lt;/code&gt; has 
not yet been produced, but there will eventually be one overarching 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sync_wait()&lt;/code&gt; that works with anything satisfying the Awaitable concept.&lt;/p&gt;

&lt;p&gt;There are a host of other interesting points and gotchas in coroutines, and 
also a competing proposal produced by my Google colleagues 
(&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1063r0.pdf&quot;&gt;P1063&lt;/a&gt;). 
All of that additional background is interesting and worth getting into, but is 
separate from the point of this post.&lt;/p&gt;

&lt;h2 id=&quot;the-task-api&quot;&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&amp;lt;&amp;gt;&lt;/code&gt; API&lt;/h2&gt;

&lt;p&gt;The main question here is “What does &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::task&amp;lt;&amp;gt;&lt;/code&gt; look like?” Given that 
coroutines are inherently slicing apart something as fundamental as “what is a 
function call,” we’re likely going to see something interesting/exotic in the 
best case.  Whether those exotic results are acceptable in trade for this very 
powerful feature is clearly a matter of taste, and what I want to bring to the 
attention of the community.&lt;/p&gt;

&lt;p&gt;That said, here is the complete callable API for the proposed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::task&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nodiscard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;noexcept&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;co_await&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// exposition only&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;   
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Take a close look at that.&lt;/p&gt;

&lt;p&gt;This is a type that wraps a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; … but has no interfaces that mention that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;. 
This is a type that can be move-constructed, and destroyed. Per the “exposition 
only” comment, it can be used via the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_await&lt;/code&gt; keyword. That’s it. 
Strictly speaking, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_await&lt;/code&gt; doesn’t even return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;, it returns a bunch of 
customization machinery that configures coroutine machinery so that you can get 
a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;. The only way for a user to know that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_await&lt;/code&gt; yields a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is to see
it in use, or read the comments. The user-facing API for coroutine types like
this do not actually show you what you expect to see.&lt;/p&gt;

&lt;p&gt;This would represent an unusual step for type design - producing types whose 
interface does not (and arguably cannot) describe its expected usage. IDEs are 
going to choke on this, autocompleters are useless, 
&lt;a href=&quot;http://cppreference.com&quot;&gt;cppreference.com&lt;/a&gt; documentation will be novel at best.&lt;/p&gt;

&lt;p&gt;The
&lt;a href=&quot;https://wandbox.org/permlink/Xb1Lu7DMmm1NVkNC&quot;&gt;simplest current implementation of task&amp;lt;&amp;gt;&lt;/a&gt;
(thanks Gor!) runs about 40 lines and is illustrative - most of the body of 
such a type is detailing its interaction with the coroutine machinery and 
definition of its related promise type.&lt;/p&gt;

&lt;p&gt;It’s well worth spending a few minutes reading through
&lt;a href=&quot;http://wg21.link/P1056r0&quot;&gt;P1056&lt;/a&gt; and the above implementation link. It is
certainly possible that coroutines require this complexity and subtlety - it is
a fundamental extension to basic programming concepts. But we should be sure
that this is well understood including its impact on the language, library,
documentation, and the rest of the ecosystem. We should also be sure that we
have found the right abstraction boundaries, not just something that works.&lt;/p&gt;

&lt;h2 id=&quot;coroutine-type-design&quot;&gt;Coroutine Type Design&lt;/h2&gt;

&lt;p&gt;Since the earliest days of the Coroutines proposals it’s been clear that 
implementing coroutine types is not something that we expect most developers to 
do: this is specialist work, and libraries like Abseil, Boost, and the standard 
library will probably do the heavy lifting for most developers. Considering the 
results that we’ve been able to see with the coroutines Technical Specification 
and coroutine demos, that’s probably fine - this is powerful, and the resulting 
user code is pretty reasonable.&lt;/p&gt;

&lt;p&gt;That said, if this is the style of specification and user-facing API for 
coroutine types, I have concerns.  The user-facing APIs produced using this 
machinery are nonsensical and impossible to understand with normal patterns 
(like “reading the API”) - all of their details are literally hidden in the 
coroutine customization machinery. It’s technically correct and functional, of 
course, but something smells wrong.&lt;/p&gt;

&lt;p&gt;On the other hand, some coroutine-backed designs seem basically OK. A 
&lt;a href=&quot;https://godbolt.org/g/mCKfnr&quot;&gt;generator demonstration&lt;/a&gt; uses iterators as the 
user-facing portion of the coroutine API, and the iterator certainly tells me 
that I get a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; when I dereference &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generator&amp;lt;T&amp;gt;::begin()&lt;/code&gt;. Perhaps this is 
nothing more than “asynchrony is complicated” which should come as little 
surprise.&lt;/p&gt;

&lt;p&gt;Looking at both the &lt;a href=&quot;https://godbolt.org/g/mCKfnr&quot;&gt;generator example&lt;/a&gt; and 
&lt;a href=&quot;https://wandbox.org/permlink/Xb1Lu7DMmm1NVkNC&quot;&gt;task&amp;lt;&amp;gt; example&lt;/a&gt; (both graciously provided by 
Gor), perhaps the real question is this: how confident are we (the committee 
and the community) that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;promise_type&lt;/code&gt; and the other coroutine customization 
points are the right design?  Clearly they are a correct and functional design 
; as always, I’m terribly impressed with the end result of the code that uses 
all of this. I’m less convinced that all of these apparent knobs are proveably 
the right set of basic operations and customization.&lt;/p&gt;

&lt;p&gt;I’m not sure what the better answer is, and I have largely been uninvolved in my
colleagues’ proposal (&lt;a href=&quot;http://wg21.link/p1063&quot;&gt;P1063&lt;/a&gt;) - I’m not sure that such
a proposal would produce clearer types or customization points that I was more
confident in. But even absent a better proposal, I want the community to look at
this and pause. Is anyone else uncomfortable with designs like these? Are we
sure we want to rush to include coroutines in the next C++ release, even with
these design smells?&lt;/p&gt;

&lt;p&gt;As is often the case, I urge the committee and community to take the time to be 
sure. If we proceed as-is, we’re likely stuck with these designs for a long 
time to come.&lt;/p&gt;
</description>
          <pubDate>2018-07-13T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20180713-coroutine-types</link>
          <guid isPermaLink="true">https://abseil.io/blog/20180713-coroutine-types</guid>
        </item>
      
    
      
        <item>
          <title>The Abseil str_format Library</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:jueminyang@google.com&quot;&gt;Juemin Yang&lt;/a&gt;, Abseil Engineer&lt;/p&gt;

&lt;p&gt;Abseil now includes a type-safe string formatting library: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_format&lt;/code&gt;.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_format&lt;/code&gt; library is a typesafe replacement for the family of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf()&lt;/code&gt; string formatting routines within the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;cstdio&amp;gt;&lt;/code&gt; standard
library header. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str_format&lt;/code&gt; library provides most of the functionality
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf()&lt;/code&gt; type string formatting and a number of additional benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Type safety, including native support for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Reliable behavior independent of standard libraries&lt;/li&gt;
  &lt;li&gt;Support for the POSIX positional extensions&lt;/li&gt;
  &lt;li&gt;Much faster (generally 2 to 3 times faster) than native &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf&lt;/code&gt; functions&lt;/li&gt;
  &lt;li&gt;Streamable to a variety of existing sinks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information, consult Abseil’s &lt;a href=&quot;/docs/cpp/guides/format&quot;&gt;StrFormat Guide&lt;/a&gt;
If you are interested in the design of this library,
check out our &lt;a href=&quot;/about/design/strformat&quot;&gt;StrFormat Design Notes&lt;/a&gt;.&lt;/p&gt;

</description>
          <pubDate>2018-06-22T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20180622-format</link>
          <guid isPermaLink="true">https://abseil.io/blog/20180622-format</guid>
        </item>
      
    
      
        <item>
          <title>Long-Term Support (LTS) Branches</title>
          <description>&lt;p&gt;By &lt;a href=&quot;mailto:shreck@google.com&quot;&gt;Tom Manshreck&lt;/a&gt;, Abseil Tech Writer&lt;/p&gt;

&lt;p&gt;Abseil encourages developers to “live at head” but we understand that
philosophy may not work for everyone. We are therefore providing snapshots
of the Abseil codebase. These snapshots are available as “Long Term
Support” (LTS) branches of Abseil, and we intend to provide a new
snapshot every 6 months or so.&lt;/p&gt;

&lt;p&gt;We pledge to support these LTS snapshots for at least 2 years. If
critical bug fixes, such as security issues, require us to change Abseil,
we will also change them within any supported LTS snapshot.&lt;/p&gt;

&lt;p&gt;NOTE: we don’t want you to think of these snapshots as “versions.” They
are simply a snapshot of the codebase at a specific point in time. If
you cannot build from source or otherwise live at head, prefer to use
the latest LTS branch of Abseil instead.&lt;/p&gt;

&lt;p&gt;For more information, consult Abseil’s
&lt;a href=&quot;/about/releases&quot;&gt;Release Management&lt;/a&gt; guide.&lt;/p&gt;

</description>
          <pubDate>2018-06-18T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20180618-lts-branches</link>
          <guid isPermaLink="true">https://abseil.io/blog/20180618-lts-branches</guid>
        </item>
      
    
      
        <item>
          <title>Revisiting Regular Types</title>
          <description>&lt;p&gt;&lt;em&gt;Good types are all alike; every poorly designed type is poorly defined in its
own way.&lt;/em&gt; - Adapted with apologies to Leo Tolstoy&lt;/p&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:titus@google.com&quot;&gt;Titus Winters&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;abstract&quot;&gt;Abstract&lt;/h3&gt;

&lt;p&gt;With 20 years of experience, we know that Regular type design is a good
pattern - we should model user-defined types based on the syntax and semantics
of built-in types where possible. However, common formulations of Regular type
semantics only apply to values, and for performance reasons we commonly pass by
reference in C++. In order to use such a reference as if it were its underlying
Regular type we need some structural knowledge of the program to guarantee that
the type isn’t being concurrently accessed. Using similar structural knowledge,
we can treat some non-Regular types as if they were Regular, including reference
types which don’t own their data. Under such an analysis, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; indeed
behaves as if it were Regular when applied to common usage (as a parameter).
However, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; does not, and further it is (currently) impossible to have
shallow copy, deep compare, and Regular const semantics in the same type in C++.&lt;/p&gt;

&lt;p&gt;This analysis provides us some basis to evaluate non-owning reference parameters
types (like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;) in a practical fashion, without discarding
Regular design.&lt;/p&gt;

&lt;!--break--&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;What are Regular types? In the space of type design, “Regular” is a term
introduced by Alexander Stepanov. (The online/reduced form is &lt;a href=&quot;http://stepanovpapers.com/DeSt98.pdf&quot;&gt;Fundamentals of
Generic Programming&lt;/a&gt; which I will cite in
this essay. You’re encouraged to read the full book “Elements of Programming”
for a more complete treatment.) By and large, the term Regular is meant to
describe the syntax and semantics of built-in types in a fashion that allows
user-defined types to behave sensibly.&lt;/p&gt;

&lt;p&gt;“The C++ programming language allows the use of built-in type operator syntax
for user-defined types. This allows us, as programmers, to make our user-defined
types look like built-in types. Since we wish to extend semantics as well as
syntax from built-in types to user types, we introduce the idea of a Regular
type, which matches the built-in type semantics, thereby making our user-defined
types behave like built-in types as well.”&lt;/p&gt;

&lt;p&gt;A vastly-simplified summary, that has become popular in C++ design in later
years, is “do as the ints do.” Generally speaking, for a snippet of generic code
operating on some type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;, if it works properly on ints and also works properly
for your new type (similarly bug-free/comprehensible/etc.), you’ve designed a
reasonable type.&lt;/p&gt;

&lt;h2 id=&quot;definitions-of-regular&quot;&gt;Definitions of Regular&lt;/h2&gt;

&lt;p&gt;In fact, this evaluation of generic code is inherent in the (somewhat flexible)
definitions for Regular; Stepanov defines certain properties for Regular, but
different formulations may include a slightly different set of requirements. In
particular, proposal &lt;a href=&quot;http://wg21.link/p0898&quot;&gt;P0898&lt;/a&gt; aims to define Concepts for
use in the C++ standard library; the requirements for Regular as presented in
P0898 are somewhat reduced from Stepanov’s definition (ordering is not
required). The crux of this difference seems to be that Stepanov’s definition
stems from the requirements of a type with respect to the full set of C++98-era
standard algorithms, while P0898 focuses primarily on the requirements to be
used in a more modern library (specifically, the Ranges library as specified in
Range v3 and/or the Ranges TS).&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Stepanov&apos;s Regular Requirements&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;P0898 Concept Requirements for Regular&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Default constructor&lt;/td&gt;
&lt;td&gt;DefaultConstructible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy constructor&lt;/td&gt;
&lt;td&gt;CopyConstructible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Destructor&lt;/td&gt;
&lt;td&gt;Destructible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Movable?&lt;/td&gt;
&lt;td&gt;Movable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Swappable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assignment&lt;/td&gt;
&lt;td&gt;Assignable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Equality&lt;/td&gt;
&lt;td&gt;EqualityComparable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inequality&lt;/td&gt;
&lt;td&gt;EqualityComparable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total Ordering&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Note: it’s generally assumed that Move construction would be included in
Stepanov’s formulation, although move semantics were not present in C++ of that
era. This is true even though &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; doesn’t have a move constructor: it is
still move constructible (can be constructed from a temporary), and this is
even the proper design for the type. Move+copy should be considered an overload
set for optimization purposes. For more information, see
&lt;a href=&quot;/tips/148&quot;&gt;TotW 148&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;In either case, it’s important to bear a few (related) ideas in mind:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The various definitions of a Regular type are more alike than they are
different.&lt;/li&gt;
  &lt;li&gt;After 20 years of experience, we’re confident that the definition of a
Regular type is a useful abstraction, and approximates the right “default
semantics” for user-defined types.&lt;/li&gt;
  &lt;li&gt;The definitions for a Regular type come from use in generic contexts. The
essential aim is to define the syntax and semantics of a value type that
mimics the behavior of a built-in type. The semantics of Regular allow us to
reason about the use of the type within an algorithm, and hence define what
the algorithm does.&lt;/li&gt;
  &lt;li&gt;The reasoning about code is much easier if the code consists of Regular
types, instead of non-Regular ones, using the existing understanding of how
built-in types work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both definitions focus heavily on &lt;strong&gt;semantics&lt;/strong&gt; not just &lt;strong&gt;syntax&lt;/strong&gt;. It is from
these basic semantic properties of types that we find design invariants like the
idea that copy, comparison, and const-ness are related. For instance, consider
four of the most basic semantic requirements on Regular types from Stepanov’s
early paper:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// comparison follows from copy&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// copy and assignment are the same&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// copy/assignment is by value, not reference&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// zap always mutates, unmutated values are untouched&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above are enough to define copy and assignment semantics: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; has
copy/assignment that operate by value, not by reference. However, all of this is
assuming we have an ability to define equality. Stepanov points out that
defining equality is a little squishy.&lt;/p&gt;

&lt;p&gt;“Logicians might define equality via the following equivalence:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;x == y ⇔ ∀ predicate P, P(x) == P(y)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That is, two values are equal if and only if no matter what predicate one
applies to them, one gets the same result. This appeals to our intuition, but it
turns out to have significant practical problems. One direction of the
equivalence:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;x == y ⇒ ∀ predicate P, P(x) == P(y)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;is useful, provided that we understand the predicates P for which it holds. We
shall return to this question later. The other direction, however:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;∀ predicate P, P(x) == P(y) ⇒ x == y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;is useless, even if P is restricted to well behaved predicates, for the simple
reason that there are far too many predicates P to make this a useful basis for
deciding equality.”&lt;/p&gt;

&lt;p&gt;Programming languages inherently contain predicates that don’t exist in pure
math, because the execution on computing hardware is a somewhat leaky
abstraction. Consider: the question of “Are x and y aliases for the same memory
location?” This is an easy predicate to write in C++, but nonsense for a
traditional logician. In general, we focus on predicates that observe “the
value” rather than the identity of the instance.&lt;/p&gt;

&lt;p&gt;Stepanov goes on to describe the built-in notion of equality for most types:
bitwise equality for ints and pointers. Floating point values are glossed over a
bit via “although there are sometimes minor deviations like distinct positive
and negative zero representations.” From this as a basis, we can begin to build
up a definition of equality for aggregates, but immediately get into trouble
because of heap allocations. “… objects which are naturally variable sized
must be constructed in C++ out of multiple simple structs, connected by
pointers. In such cases, we say that the object has &lt;strong&gt;remote&lt;/strong&gt; parts. For such
objects, the equality operator must compare the remote parts …”&lt;/p&gt;

&lt;p&gt;This reasoning continues, including some discussion about the physical state vs.
logical state of a type (for instance: the capacity of a vector does not figure
into its equality comparison, nor does the use of SSO affect equality comparison
for string).&lt;/p&gt;

&lt;p&gt;Ultimately, Stepanov proposes the following definition, “although it still
leaves room for judgement”:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Definition&lt;/strong&gt;: two objects are equal if their corresponding parts are equal
(applied recursively), including remote parts (but not comparing their
addresses), excluding inessential components, and excluding components which
identify related objects.”&lt;/p&gt;

&lt;p&gt;If we have a solid understanding of how to compare two instances of our type (by
value, focusing on the logical state, not comparing by identity/memory
location), and if our type implements all the syntactic/semantic requirements
for Regular then we have implemented a Regular type. That should always be our
starting point when designing a value type.&lt;/p&gt;

&lt;h2 id=&quot;modern-regular-types-and-const&quot;&gt;Modern Regular Types and const&lt;/h2&gt;

&lt;p&gt;With an agreed-upon understanding of Regular, we can start to examine the ways
that Regular is used. We can reasonably assume that a Regular type can be fed
through standard algorithms, since that’s a primary motivation for defining
Regularity (or, conversely, the implied requirement for the algorithms, although
the legacy algorithms are rarely specified in terms of semantic requirements).&lt;/p&gt;

&lt;p&gt;So we can certainly express that this is safe and correct for Regular types,
yes?&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// May be any valid C++&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Note: we&apos;re assuming the semantics of ==&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This seems straightforward: we have two const values. If they are equal, it
doesn’t matter what operation we perform on one of them, they will remain equal.
It also doesn’t matter if we modify any other global state. It does imply one
additional requirement beyond being Regular: the normal semantics of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; 
must be enforced - a const object must not change values. Consider the
following type and body for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoSomething&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Rotten&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Rotten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Rotten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rotten&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Rotten&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rotten&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rotten&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;mutable&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rotten&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rotten&lt;/code&gt; type meets the syntactic requirements for P0898 Regular: it is
DefaultConstructible, CopyConstructible, Movable, Swappable, Assignable,
EqualityComparable, and it has the semantics for all of those operations. Where
it &lt;em&gt;fails&lt;/em&gt; is in the General front-matter for standard library concepts.
Consider, from P0898r2: “except where otherwise specified, an expression operand
that is a non-constant lvalue or rvalue may be modified. Operands that are
constant lvalues or rvalues must not be modified.”&lt;/p&gt;

&lt;p&gt;This restriction (while being a little squishy about “modified”), plus the basic
ideas of “equality” are enough to see that for at least the &lt;strong&gt;logical&lt;/strong&gt; state of
a type, const must mean const. Since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rotten&lt;/code&gt; goes out of its way to break that,
the P0898 formulation of Regular rightly spots that bad type design and forbids
it.&lt;/p&gt;

&lt;p&gt;Since the original Stepanov paper never discusses const, but const is tied
deeply to modern type design, I’ll primarily focus the remainder of the
discussion on P0898 for simplicity and clarity.&lt;/p&gt;

&lt;h2 id=&quot;data-races-and-thread-safety-properties&quot;&gt;Data Races and Thread Safety Properties&lt;/h2&gt;

&lt;p&gt;Let us digress a little to discuss something that is unrelated on the surface,
but critical to the ensuing discussion: data races and the thread safety
properties of types.&lt;/p&gt;

&lt;p&gt;Very significant essays and presentations can (and should) be produced on the
topics of data races in C++ and the thread safety properties of types. The
following is at most a surface treatment. If you are unfamiliar with this
domain, please find a good in-depth tutorial/refresher rather than relying on
only this brief summary.&lt;/p&gt;

&lt;p&gt;More or less: a data race occurs when at least one memory location is written by
one thread and accessed (read or write) by another thread without
synchronization between those operations. Any number of threads may read
concurrently, but if any thread is writing, you must synchronize those
operations. That synchronization can take many forms, ranging from the use of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::atomic&lt;/code&gt; up to a mutex or higher-level synchronization primitive. But no
matter what you think you know about how execution works on your processor, on
the C++ abstract machine there is no such thing as a safe data race. The C++
standard specifically calls this out: data races are undefined behavior. No
correct program has undefined behavior. There is no wiggle room.&lt;/p&gt;

&lt;p&gt;At a slightly higher level: how do we tell the difference between a read
operation and a write operation for a type? For user-defined types we look at
the API documentation, where the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; qualifier nicely summarizes the
read/write semantics of the API. For the vast majority of types (i.e. those that
have the same thread-safety behavior that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; does), concurrent
(non-synchronized) calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; methods are allowed, but if any concurrent
call is made to a non-&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; method, there is the chance for a data race.&lt;/p&gt;

&lt;p&gt;For instance: if you have an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&amp;lt;int&amp;gt;&lt;/code&gt; shared among many threads, those
threads may all ask &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_value()&lt;/code&gt; or read from the contained &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;, so long as
none of them overwrites the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;. Such a store would take place via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator=&lt;/code&gt;
(non-const) or assigning to the reference returned by the non-const overloads of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It has become common practice to classify types as either “thread-safe”,
“thread-compatible”, or “thread-unsafe”, based on the conditions under which use
of its API may result in a data race.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Thread-safe&lt;/strong&gt;: No concurrent call to any API of this type causes a data
race. This is useful for things like a Mutex. Generally speaking,
thread-safe types are easiest to work with, but you pay for some of that
usability in performance or API restrictions or both.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Thread-compatible&lt;/strong&gt;: No concurrent call to any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; operation on this
type causes a data race. Any call to a non-&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; API means that instance
must be used with external synchronization. C++ guarantees that standard
library types are at least thread-compatible. This follows from the general
pattern of Regular design, and “do as the ints do” as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; is
thread-compatible. In most cases, this is in-line with the philosophy of
C++ - you do not pay for what you do not use. If you operate on an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&amp;lt;int&amp;gt;&lt;/code&gt;, you can be sure that it isn’t grabbing a mutex. On the
other hand, thread-compatible may have overhead in some cases:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shared_ptr&amp;lt;&amp;gt;&lt;/code&gt; is unnecessarily expensive in cases where there is no sharing
between threads, because of the use of atomics to synchronize the reference
count.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Thread-unsafe&lt;/strong&gt;: Even concurrent calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; APIs on this type may
cause data races - use of an instance of such a type requires external
synchronization or knowledge of some form to be used safely. These are
generally either used with a mutex or are used with knowledge like “I know
that this instance is only accessed from this thread” or “I know that my
whole program is only single threaded.” Types like this may be because of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutable&lt;/code&gt; members, or because of non-thread-safe data that is shared between
instances.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is worth mentioning that “const means const” is &lt;em&gt;almost&lt;/em&gt; enough to ensure
that a type is thread-compatible. It is possible to have members in your type
that are not part of the logical state (for example: a reference count) but are
mutable (either via the mutable keyword or through something like a
const-pointer-to-non-const) and thus cause data races even when only const APIs
are invoked. There’s a strong conceptual overlap between const-ness
(conceptually, including both syntax and semantics) and thread-compatibility,
and that overlap is actually equivalence in the case that there are no such
mutable members.&lt;/p&gt;

&lt;p&gt;Now considering thread-safety and const-ness, we can consider whether either the
Stepanov or P0898 definitions of Regular say everything we want. If we’re
following the model of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; or the good standard library types, Regular types
have a powerful property: if you have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&lt;/code&gt;, and pass that instance as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt; to some function that function can do nothing that can make your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;
change value (that isn’t inherently UB), become invalid, or otherwise become
harder to use. In order to hold that property, your Regular type needs to be
thread-compatible, or you need to constrain the function (promise to not share
this instance among threads, for instance). Both approaches are useful.&lt;/p&gt;

&lt;h2 id=&quot;dependent-preconditions&quot;&gt;Dependent Preconditions&lt;/h2&gt;

&lt;p&gt;One property of Regular that never seems entirely satisfying in less formal
design conversations is that both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; are equivalently
Regular, although any programmer will tell you that there is a lot more to worry
about when working with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt;: there are preconditions when using an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt;
that are harder to ensure than any precondition when using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For instance, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string::operator[]&lt;/code&gt; has a precondition roughly of the form,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;index &amp;lt; size()&lt;/code&gt;. In fact, the only APIs on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; that have
preconditions of any form fall into two clear categories:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;They are requirements that can be checked using other methods from the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; API. For instance, the above precondition on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator[]&lt;/code&gt; can be
checked by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size()&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;They are requirements entirely focused on the data being passed in, not on
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; itself. For instance, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; constructor (non-NULL,
valid allocation, nul-terminated), or the iterator-range
construction/assignment operations (valid range).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For comparison, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt; has at least one precondition of a fundamentally
different flavor:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator*&lt;/code&gt; - Requires that the pointer holds the address of a live &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;
object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This cannot be checked via any operation on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt;, nor can it even be checked
portably in any fashion given an arbitrary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt;. Invoking this operation
safely &lt;strong&gt;requires&lt;/strong&gt; structural knowledge of the program. A type that has
&lt;strong&gt;dependent preconditions&lt;/strong&gt; has one or more such APIs; these are often (but not
always) about properties of non-owned objects/external memory/etc.&lt;/p&gt;

&lt;p&gt;APIs that have dependent preconditions are more complicated to use - they
fundamentally require knowledge about the rest of the program in order to use
safely. Types that have no such APIs are easier to use, and it is no surprise or
coincidence that the majority of types that we consider “good” avoid this
property. Or, put another way, types with dependent preconditions have a weaker
form of the property we want from Regular: when passing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt; to a
function, that function may be able to invalidate the preconditions on some API
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; through mechanisms that are outside of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;. It isn’t enough to say that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is thread-compatible - we must know that nothing in the program is going to
invalidate the dependent preconditions.&lt;/p&gt;

&lt;p&gt;Let’s consider &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt; in the context of our Regular-code usage snippet:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Is it really the case that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoSomething()&lt;/code&gt; can do anything we want and leave
this snippet intact? For an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt;, it definitely isn’t - certainly not to the
same extent as it is for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;. (There is perhaps some overlap between this and
Lisa Lippincott’s recent work &lt;a href=&quot;https://www.youtube.com/watch?v=s70b2P3A3lg&quot;&gt;What is The Basic
Interface&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;For instance, if we dereference the pointer, we may have introduced a data race:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt; is only thread-compatible if never dereferenced, but we do not have
knowledge that nothing else is modifying the underlying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;. Or worse, if we
dereference and &lt;strong&gt;write&lt;/strong&gt; to the pointer, we make it a race if any thread is
even reading the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;P0898r2 gets at some of this in [concepts.lib.general.equality] p3: “Expressions
required by this specification to be equality preserving are further required to
be stable: two evaluations of such an expression with the same input objects
must have equal outputs absent any explicit intervening modification of those
input objects. [ Note: This requirement allows generic code to reason about the
current values of objects based on knowledge of the prior values as observed via
equality preserving expressions. &lt;strong&gt;It effectively forbids spontaneous changes to
an object, changes to an object from another thread of execution, changes to an
object as side effects of non-modifying expressions, and changes to an object as
side effects of modifying a distinct object if those changes could be observable
to a library function via an equality preserving expression that is required to
be valid for that object&lt;/strong&gt;. — end note ]”&lt;/p&gt;

&lt;p&gt;In order to reason about a type that has dependent preconditions (like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt;),
to use it in standard algorithms, or to do much of anything with the type, we
must have additional knowledge: why do we know that a given instance is being
used in a race-free fashion?&lt;/p&gt;

&lt;p&gt;The same is implicitly true for traditional Regular types. When handed a
newly-constructed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;, you know everything you need to know in order
to operate on that object safely, even in the face of data races. If you don’t
pass it to another thread, it isn’t shared. You are data race free purely by
virtue of having the object and knowing there are no additional (mutable)
references to it anywhere. If we instead only hand you a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&amp;amp;&lt;/code&gt; (as is
the case for basically all usage of standard algorithms), we don’t actually have
that knowledge. Without knowledge that it is unshared, you cannot compare it or
copy it in a race free fashion.&lt;/p&gt;

&lt;p&gt;This requirement is unstated, and pervasive. Everything in the Stepanov-era
standard library implicitly assumes it. In the Ranges/Concepts era, we get text
like P0898, rightly forbidding spontaneous changes to an object. But in the
general case, the standard already says this, because of the language rules on
data races, and the library rules that require most library types
are effectively thread-compatible.&lt;/p&gt;

&lt;p&gt;Put another way: what do you need to know when invoking a standard algorithm on
some user-defined type? You need to know the syntax and semantics of its basic
API - it needs to be Regular. But you also need to know that invocation of the
algorithm on that instance is race free. A few types give you that by being
thread-safe. The rest of the time, you have to know something about the
structure of your program and how your instance interacts with the program in
order to guarantee race-free.&lt;/p&gt;

&lt;p&gt;Interestingly, it isn’t only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator*&lt;/code&gt; on a pointer that has dependent
preconditions: it is implementation-defined behavior to invoke &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator==&lt;/code&gt; on a
pointer after the underlying object has been deleted. According to Richard
Smith, it is “as-if we scribble over every pointer in the program that points to
the object at the time of deletion.” So if we have&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;we are already off in the realm of non-portable programs. And while
implementation-defined is less bad than undefined, this does further demonstrate
that even &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator==&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt; has preconditions that are impossible to
check - we have to rely on structural knowledge of the program to use pointers
correctly.&lt;/p&gt;

&lt;p&gt;Which, luckily, clarifies most people’s intuition: pointers are more complicated
than the other types we talk about as Regular. There’s room for expansion in our
definition / usage / discussion of Regular. I believe that the missing piece for
Regular is “thread compatible” in the general case (although there are other
valid options), and existing design precedent in the library already follows
that direction. Builtins and our vocabulary types are both Regular and
thread-compatible.&lt;/p&gt;

&lt;h2 id=&quot;flavors-of-race-free-plus-regular&quot;&gt;Flavors of Race-Free, plus Regular&lt;/h2&gt;

&lt;p&gt;While Regular+thread-compatible is the most common (and most like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;)
combination that actually describes good/built-in-like types, other options may
work in some situations. These options correspond roughly to the answers for
“How do you know that operations on this instance do not cause data races?”&lt;/p&gt;

&lt;p&gt;For any given instance of a type, you might know one of several possible things
that allow you to operate on it race-free.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Thread-compatible&lt;/strong&gt; and not shared with other threads for writing. If
you’ve been handed a (non-racing) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt; you can operate on this in
const fashion. If necessary, you can copy it to ensure there are no lurking
references and perform any computation / mutation safely (but
inefficiently). With minor knowledge (the instance isn’t shared), a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&amp;amp;&lt;/code&gt; can
be used safely as if it were &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;It has &lt;strong&gt;dependent-preconditions&lt;/strong&gt;, but for a particular instance + any
dependent data, the program structure guarantees safe usage.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Single-threaded usage&lt;/strong&gt; - There is only one thread in the program and thus
all instances of the type are safe to use, or a given instance is known to
not be shared among threads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;P0898r2’s [concepts.lib.general.equality] p3, cited above, would fix the
standard library’s stance on Regular to be entirely the first option … at the
cost of pointers not being considered Regular because of semantic requirements
and implementation-defined behavior on comparison. (If deletion is “as-if all
other pointers to this object are scribbled over” that certainly violates the
restriction on the value of the object changing out from under us.)&lt;/p&gt;

&lt;p&gt;All three of these options provide points in the type design space that are
useful in conjunction with the existing definitions for Regular.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Thread-compatible&lt;/strong&gt; + Regular is what we really want for user-defined
types that mimic built-ins. This lets us reason about an instance in the
expected fashion and use it efficiently in conjunction with generic
algorithms. Types that have mutable data may have some overhead to support
this.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dependent-preconditions&lt;/strong&gt; with knowledge that an instance + its dependent
data are safe to use. This is the common usage for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; when we use
it as a non-owning parameter type: the underlying buffer will outlive the
function call and is immutable for the duration of the call. Given that
external knowledge of that underlying buffer, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; behaves as if it
were Regular. This makes sense, given that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; was designed to be
a drop-in replacement for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string&amp;amp;&lt;/code&gt;, and although references are not
Regular types, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; types are.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Single-threaded usage&lt;/strong&gt; - This is easy to misuse, but can be an important
area for optimization. Consider the discussions to provide a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shared_ptr&lt;/code&gt;
analogue that does not synchronize its reference count - if we know
something about program structure, or can guarantee particular usage for an
instance, we can design a more efficient type in this fashion. Given that
knowledge, such a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shared_ptr&lt;/code&gt; can still behave as if it were Regular.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given a type and one of the above options to explain why it is safe to use a
given instance, we can see that our nice property for Regular types still holds.
Given a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&lt;/code&gt; (and some program knowledge), we can perform any operation
(that conforms to that program knowledge) on that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&lt;/code&gt; without invalidating
it or any of its API preconditions. Regular+thread-compatible types allow us
this invariant with no constraints on the program or that operation. Lesser
invariants require more knowledge - in return we tend to get lower-overhead,
which is a very C++ style of tradeoff.&lt;/p&gt;

&lt;h2 id=&quot;evaluating-string_view&quot;&gt;Evaluating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;If we know that the underlying buffer exists and is not being mutated,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; behaves as if it were Regular: it is DefaultConstructible,
CopyConstructible, Movable, Swappable, Assignable, EqualityComparable. If the
underlying buffer is immutable for the life of our instance, the General Matter
rules in P0898 don’t kick in: the value won’t magically change out from under
us.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Assume SomeT() is providing a&lt;/span&gt;
                      &lt;span class=&quot;c1&quot;&gt;// long-lived and stable buffer.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	
  &lt;span class=&quot;c1&quot;&gt;// Won&apos;t modify the buffer, provided our assumption on SomeT() is correct.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can go back to Stepanov’s axioms about assignment and comparison.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So long as the values we are assigning to represent buffers that outlive the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; and remain immutable, these axioms are held. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zap()&lt;/code&gt; has to
actually change its parameter so that pre/post calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zap&lt;/code&gt; are not equal -
but remember that equality is about value not identity)&lt;/p&gt;

&lt;p&gt;If we do &lt;strong&gt;not&lt;/strong&gt; know that the underlying buffer exists and is not being
mutated, we cannot evaluate any of these snippets. Even executing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator==&lt;/code&gt;
runs the risk of undefined behavior either from use-after-free (if the buffer
has disappeared) or data race (if the buffer is mutated).&lt;/p&gt;

&lt;p&gt;Remember that this is a lot to ask: this knowledge of the underlying buffer is a
lot more than the knowledge required when operating on something Regular like a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;. I’ve probably seen hundreds of bugs stemming from people getting the
object lifetimes wrong with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; and its underlying buffer.&lt;/p&gt;

&lt;p&gt;Without that external knowledge, it’s easy to see how we fail with all of
Stepanov’s axioms (assign these &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;s to temporaries). Similarly,
without that knowledge, we fail at P0898r2’s [concepts.lib.general.equality]
p3 - the value can change out from under us. We get (countless) examples like
this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SomeT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Give out references to different global strings&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// modify an unrelated global&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sv1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sv2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sv1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// equal&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sv1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// No program structure constraints, can modify a global.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sv1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// failure: &quot;aello&quot; != &quot;hello&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Side note: At some level I think this is a bogus example. Having participated
for many years in mailing list discussions about the Google-internal type that
inspired &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;, the way that people mishandle &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; has nothing
to do with mutability of the underlying data, and everything to do with the
underlying data being unowned and going out of scope. I estimate the prevalence
of lifetime-requirement failure vs. underyling-mutability failure to be at least
50:1 - the risks of a type like this are almost entirely based around lifetime,
not remote-mutation. It’s also much easier to construct an example for this
snippet that fails because of insufficient buffer lifetime.&lt;/p&gt;

&lt;p&gt;So no, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; isn’t quite Regular. Given particular very constrained
usage, it behaves as if it were Regular. That usage is very nearly &lt;strong&gt;required&lt;/strong&gt;
by the rest of the standard - you can’t even compare a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; without
undefined behavior unless you have knowledge about the program structure to
guarantee that operation is safe. However, with that knowledge, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;
still behaves as if it were Regular.&lt;/p&gt;

&lt;h2 id=&quot;non-owning-reference-parameters&quot;&gt;Non-owning Reference Parameters&lt;/h2&gt;

&lt;p&gt;C++ is a language that is very concerned with 2 things: types, and efficiency.
The type system for C++ is more complex than most other languages by a
significant margin: this is the only mainstream language that I can imagine
where it’s reasonable to envision a proposal for an infinite family of Null
types (P0196).&lt;/p&gt;

&lt;p&gt;At the same time, C++ focuses a great deal of effort on “do not pay for what you
do not use”. We have a preponderance of non-Regular types in the core language:
references are not Regular, but they are &lt;em&gt;efficient&lt;/em&gt;. Passing by reference is
basic - when invoking a function we don’t necessarily want to &lt;em&gt;copy&lt;/em&gt; anything,
we merely give a reference for the duration of the function call. An increasing
amount of modern design is about providing flexibility when it comes to the
specific types that are accepted - we overload on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
string&amp;amp;&lt;/code&gt;, or we just accept &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;. Other user-defined types that have a
contiguous buffer of characters can join in our overload set by providing a
conversion to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is, in some respects, one of the big areas for design work in C++ these
days: building an increasing set of generic/type-erased types that accept a
broad selection of related types and provide a uniform interface. Consider
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function_ref&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;, from recent standards
discussion. In Google’s codebase I’m starting to see types like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AnySpan&lt;/code&gt; which
behave like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; but further abstract &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; away from the underlying type
(allowing non-null &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unique_ptr&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T*&lt;/code&gt;, for instance).&lt;/p&gt;

&lt;p&gt;From a usability perspective, we have to decide whether we are continuing down
the path of building types that represent our duck-typing overload sets, or
whether we are asking users to implement those overload sets inconsistently on
an ad-hoc basis. I’m fairly sure that most of us will conclude that there is
value in using these non-owning reference parameter types - if we can agree on
how to design them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When used as a parameter&lt;/strong&gt;, we always know that the underlying data continues
to exist and is as safe to access as making a copy of the data would have been.
(That is, if the underlying data is a reference itself, and we don’t know if
anything is mutating it, we’re already in trouble.)&lt;/p&gt;

&lt;p&gt;Restated: the arguments against &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; and other reference types are that
they are not Regular. And that’s true, they aren’t when evaluated in a vacuum.
But if you have any structural knowledge about the program, they behave as if
they are Regular in their most common usage - as parameters.&lt;/p&gt;

&lt;p&gt;So since we’re probably going to keep building non-owning reference parameter
types, can we stop arguing about them being bad because they aren’t Regular?
They may be Regular enough for the use case they are designed for, and if a C++
programmer chooses to use them for more, they’ll still usually be Regular given
knowledge of the lifetime of their referent. (Or the lifetimes won’t match up
and we’ll be cursed for being a hard language, but that’s unavoidable.)&lt;/p&gt;

&lt;p&gt;Taking into account APIs with dependent preconditions and implementation-defined
behavior on deleted pointer comparison, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; is no worse than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt;,
after all.&lt;/p&gt;

&lt;h2 id=&quot;evaluating-span&quot;&gt;Evaluating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;When discussing reference types in the standard, the two common points of
reference are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; (already voted in with C++17) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; (heading to
the working draft for C++20). Although there are numerous syntactic differences
in the APIs of these two, semantically the major difference is in the mutability
of the underlying data. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; is either a lightweight reference to a
string that it will not mutate, or a non-owning pointer+length to a buffer it
will not mutate (depending on whose conceptualization you follow), but in either
case it does not mutate the underlying buffer. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string_view&lt;/code&gt; is only
interesting in that it cannot be trimmed nor reassigned.&lt;/p&gt;

&lt;p&gt;On the other hand, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&amp;lt;T&amp;gt;&lt;/code&gt; allows non-const operations on the underlying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;.
If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; were a container like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; we would know that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const span&lt;/code&gt; would
imply only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; access to the underlying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;. In this sense, when comparing
to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; we have no precedent to draw upon.&lt;/p&gt;

&lt;p&gt;Let’s apply the idea that we want &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; to be as close to Regular as possible.
What would it take for us to operate on an instance as if it were Regular? Keep
in mind that we are already assuming that the program structure forbids mutation
of the buffers except via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; directly and thus &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoSomething()&lt;/code&gt; cannot
modify &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a1&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a2&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We know that can only use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; as if it were Regular if we know that the
underlying buffer isn’t being mutated by anything else. But that isn’t enough
here: it’s easy to imagine a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoSomething&lt;/code&gt; that modifies a value through the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const span&lt;/code&gt; and then breaks our assertion.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Having a const span&amp;lt;T&amp;gt; doesn&apos;t make the underlying T const&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Perhaps what we want is for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; to only provide const access to the buffer
when the span is const? We could make the const overload of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span::operator[]&lt;/code&gt;
provide &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt;. Unfortunately, this isn’t enough for a copyable type.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Copying drops const but leaves the referent&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Can modify through the copy&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We have to treat the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; and its dependent data as one, and that treatment
must include const propagation. Unfortunately, we cannot get shallow copy (copy
by pointer), const propagation (const reference implies const referent), and
deep equality (compare by pointee) in the same type. You can, however, get close
enough to const propagation by disallowing mutation of the underlying buffer.&lt;/p&gt;

&lt;p&gt;For non-owning reference parameters like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;, merely
knowing the underlying buffer isn’t being mutated externally isn’t enough for it
to be used as if it were Regular. We need to make one further choice:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The data cannot be mutated through the reference type, a la &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Equality is shallow: the logical state of the type is tied to the value of
the pointer, rather than the value of what it points to&lt;/li&gt;
  &lt;li&gt;The reference type is designed in a clever fashion so that once you have a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const Reference&amp;lt;T&amp;gt;&lt;/code&gt;, copies become at most &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reference&amp;lt;const T&amp;gt;&lt;/code&gt;. (I suspect
this is impossible in the language currently, and even if it isn’t it is
likely to be awkward to work with, but I’m intrigued at the possibility).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stated aims of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; (to replace easily-mishandled instances of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T*, len&lt;/code&gt;)
cannot be met while having both Regular semantics and deep equality - the
logical state of the type must be only the pointer+length, not the underlying
unowned data. When given the choice, we should prefer to be more like Regular
and change to shallow equality. It’s still arguable whether it will be Regular
(dependent preconditions on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator[]&lt;/code&gt;, and implementation-defined behavior
for comparison on a deleted pointer), but it will be much closer.&lt;/p&gt;

&lt;p&gt;With such a change to its comparison, and knowledge that the underlying buffer
isn’t being modified, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; will behave as if it were Regular. Given a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
span&lt;/code&gt; and the required knowledge about its buffer, nothing we do to it can make
its value change or invalidate any of its API preconditions.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;If you have got the option, make your value types Regular and thread-compatible
with no mutable or shared state. Do not take any of the above as justification
to break that commandment lightly.&lt;/p&gt;

&lt;p&gt;That said, Regular as everyone describes it does gloss over some things - we
operate on Regular types by reference in standard algorithms constantly, and
those operations aren’t safe without some form of structural knowledge of the
program. Usually that knowledge is of the form “this instance isn’t shared to
any other thread.” The best Regular types, those that model built-ins most
closely, are thread-compatible and have no dependent preconditions. Types like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; are easier to work with than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When it comes to non-owning reference types like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;, the
required structural knowledge is more complex: it isn’t only that the instance
isn’t shared, it’s that the instance plus its underlying data isn’t shared in a
way that will cause data races. When operating on a type arbitrarily, that is
hard to prove. But in the very common (and very relevant to C++ design
priorities) case of building cheap non-owning reference parameters, we have that
knowledge because of how parameter passing and function invocation work.&lt;/p&gt;

&lt;p&gt;If knowledge that the underlying data isn’t shared is enough to make usage of an
instance passed as a parameter behave like Regular, that is good. These types
like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; will have more sharp corners and take some getting used to,
but in practice most of the problems come from underlying buffers going out of
scope when used not as a parameter. Critically, such types must not allow
mutation of their unowned underlying data.&lt;/p&gt;

&lt;p&gt;For types where we want reference semantics but must allow for mutation of the
underlying data, we must yield something. It is currently impossible to have a
type that has shallow-copy, deep-compare, and Regular behavior when propagating
const-ness: one or more of those properties must be given up. The expected usage
of every type is different, so it is hard to provide one-size-fits-all guidance,
but consider the following options:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;shallow compare&lt;/strong&gt; - Make the type compare based on what it points at by
identity (pointer value) rather than dereferencing the underlying data.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SemiRegular&lt;/strong&gt; - P0898 specifically defines the concept &lt;em&gt;SemiRegular&lt;/em&gt; to
denote types that are Regular except for a lack of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator==&lt;/code&gt;. These are
still perfectly suitable for storing in many types of containers. Dropping
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator==&lt;/code&gt; will leave no users confused at runtime when equality semantics
do not match their expectation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If equality isn’t the culprit for your type being irregular (even given
knowledge of program structure), cut or rename the offending operations until it
is a strict subset of Regular - it is better for your type to not reuse common
syntax for operations that have non-Regular semantics.&lt;/p&gt;

&lt;p&gt;As a satisfying side-note: classifying types based on the form of structural
knowledge they need in order to operate on them safely provides us a way to
separate types like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt;. It has long been unsatisfying that
pointers and values were both considered Regular in exactly the same fashion.&lt;/p&gt;

&lt;p&gt;Accounting for this variation in “how much information do we need when working
on an instance of this type safely”, we can look at reference types when their
underlying data is extant and constant and determine whether the rest of their
usage still looks Regular. Pleasantly, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; works fine. We do find some
weaknesses in the current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; proposal, particularly when it comes to shallow
vs. deep const.&lt;/p&gt;
</description>
          <pubDate>2018-05-31T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20180531-regular-types</link>
          <guid isPermaLink="true">https://abseil.io/blog/20180531-regular-types</guid>
        </item>
      
    
      
        <item>
          <title>Abseil No Longer Depends on CCTZ</title>
          <description>&lt;h3 id=&quot;an-update-on-our-dependencies&quot;&gt;An Update On Our Dependencies&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:shaindel@google.com&quot;&gt;Shaindel Schwartz&lt;/a&gt;, Abseil Engineer&lt;/p&gt;

&lt;p&gt;As of the April 23 update, 
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/commit/af7882601aad93ada881486eeaabc562f1733961&quot;&gt;af78826&lt;/a&gt;
, Abseil no longer requires an external dependency on CCTZ. If you have
included the CCTZ project solely to satisfy the Abseil dependency, you can now
safely remove it from your project’s setup.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;We are in the process of adding some updates to our Time library. As a
transitional step in this set of planned updates, we have added an internal
fork of the CCTZ types and dropped the dependency on the external CCTZ project.
To avoid potential name conflicts with a project’s independent use of the CCTZ
library, our internal copy lives in a unique, internal absl namespace. The
internal copy is intended solely as an implementation detail underpinning our
provided Time APIs. As with all internal types, users should not depend on or
use them directly.&lt;/p&gt;

&lt;p&gt;Note that if your project has its Abseil dependency pinned at a specific
commit, you may still need the dependency on CCTZ. (For a commit earlier than
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/commit/af7882601aad93ada881486eeaabc562f1733961&quot;&gt;af78826&lt;/a&gt;
, the dependency on CCTZ is still required.) We encourage you to live at head.&lt;/p&gt;
</description>
          <pubDate>2018-05-11T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20180511-cctz-removal</link>
          <guid isPermaLink="true">https://abseil.io/blog/20180511-cctz-removal</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #149: Object Lifetimes vs. &lt;code&gt;= delete&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #149 on May 3, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:titus@cs.ucr.edu&quot;&gt;Titus Winters&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/149&quot;&gt;abseil.io/tips/149&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Into the blue again after the money’s gone&amp;lt;br/&amp;gt; Once in a lifetime, water
flowing underground –David Byrne&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;delete-for-lifetimes&quot;&gt;&lt;code&gt;=delete&lt;/code&gt; for Lifetimes&lt;/h2&gt;

&lt;p&gt;Imagine you have an API that requires a reference to some long-lived object, but
doesn’t take ownership of it.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Request {
  ...

  // The provided Context must live as long as the current Request.
  void SetContext(const Context&amp;amp; context);
};
&lt;/pre&gt;

&lt;p&gt;You think to yourself, “Hey, what happens if someone passes a temporary? That’s
going to be a bug. But this is modern C++, I can prevent that!” So you rig
together a change in the API, adding a deleted overload.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Request {
  ...

  // The provided Context must live as long as the current Request.
  void SetContext(const Context&amp;amp; context);
  void SetContext(Context&amp;amp;&amp;amp; context) = delete;
};
&lt;/pre&gt;

&lt;p&gt;Pleased with your work, you think “Hey, now the API says everything, the comment
isn’t necessary.”&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Request {
  ...

  void SetContext(const Context&amp;amp; context);
  void SetContext(Context&amp;amp;&amp;amp; context) = delete;
};
&lt;/pre&gt;

&lt;p&gt;Was this a good idea? Why or why not?&lt;/p&gt;

&lt;h2 id=&quot;dont-design-in-a-vacuum&quot;&gt;Don’t Design In a Vacuum&lt;/h2&gt;

&lt;p&gt;As presented, you might think that this is a good idea. However, as in many
cases of API design it is &lt;em&gt;tempting&lt;/em&gt; to look at the definition of the API, but
more &lt;em&gt;useful&lt;/em&gt; to look at how the API is used. So lets replay this scenario,
taking into account usage.&lt;/p&gt;

&lt;p&gt;A user attempting to use the original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetContext()&lt;/code&gt;, trying to get something
simple to build and not knowing where to find the right &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Context&lt;/code&gt; object, just
makes the suggested call.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
request.SetContext(Context());
&lt;/pre&gt;

&lt;p&gt;Without your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt; change, this builds, but fails at runtime (probably in a
mysterious fashion). When looking at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetContext&lt;/code&gt; API, the lifetime
requirement is documented, and the code is changed to comply.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
request.SetContext(request2.context());
&lt;/pre&gt;

&lt;p&gt;A user attempting to use the “improved” &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetContext()&lt;/code&gt; with your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt;
change and no comment, on the other hand, first encounters the build break:&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
error: call to deleted member function &apos;SetContext&apos;

  request.SetContext(Context());
  ~~~~~~~~^~~~~~~~~~

&lt;source /&gt;:4:8: note: candidate function has been explicitly deleted
  void SetContext(Context&amp;amp;&amp;amp; context) = delete;
&lt;/pre&gt;

&lt;p&gt;The user then thinks “Well, I can’t pass a temporary”, but having no information
about the actual requirement, what is the most likely fix?&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
Context context;
request.SetContext(context);
&lt;/pre&gt;

&lt;p&gt;Now, the crux of the matter: How likely is it that the scope of the new
automatic variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;context&lt;/code&gt; is the right lifetime for this call? If your answer
is anything less than 100%, the lifetime requirement comment is still necessary.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Request {
  ...

  // The provided Context must live as long as the current Request.
  void SetContext(const Context&amp;amp; context);
  void SetContext(Context&amp;amp;&amp;amp; context) = delete;
};
&lt;/pre&gt;

&lt;p&gt;Deleting a member of an overload set in this fashion is at best a half-measure.
Yes, you avoid one class of bugs, but you also complicate the API. Relying on
such a design is a sure-fire way to get a false sense of security: the C++ type
system is simply not capable of encoding the necessary details about lifespan
requirements for parameters.&lt;/p&gt;

&lt;p&gt;Since the type system can’t actually get this right, we recommend you not
complicate things with half-measures. Keep it simple - don’t try to rely on this
pattern to disallow temporaries, it doesn’t work well enough to help.&lt;/p&gt;

&lt;h2 id=&quot;delete-for-optimization&quot;&gt;&lt;code&gt;=delete&lt;/code&gt; for “Optimization”&lt;/h2&gt;

&lt;p&gt;Let’s flip the situation around: perhaps it isn’t that you want to prevent
temporaries, maybe you want to prevent copies.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
future&amp;lt;bool&amp;gt; DnaScan(Config c, const std::string&amp;amp; sequence) = delete;
future&amp;lt;bool&amp;gt; DnaScan(Config c, std::string&amp;amp;&amp;amp; sequence);
&lt;/pre&gt;

&lt;p&gt;How likely is it that a caller of your API will never need to keep their value?
If you cannot be 100% sure that you know exactly how your API will be used, this
is a recipe for annoying your users. Consider making copies and invoking such an
API given normal (non-deleted) design:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
Config c1 = GetConfig();
Config c2 = GetConfig();
std::string s = GetDna();

// Kick off scans for both configs.
auto scan1 = DnaScan(c1, s);
auto scan2 = DnaScan(c2, std::move(s));
&lt;/pre&gt;

&lt;p&gt;Since we see that the second scan is the last use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt;, we can just
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move&lt;/code&gt; into the value-consuming call. With the “cleverly optimized”
version, the code gets more sloppy looking.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
Config c1 = GetConfig();
Config c2 = GetConfig();
std::string s = GetDna();
std::string s2 = s;

// Kick off scans for both configs.
auto scan1 = DnaScan(c1, std::move(s));
auto scan2 = DnaScan(c2, std::move(s2));
&lt;/pre&gt;

&lt;p&gt;APIs are provided as building blocks and abstractions - the ecosystem of APIs is
a platform to be assembled together in new and surprising ways that are more
than what the provider of any single API might predict. Believing that you know
certainly that nobody should ever make a copy runs counter to that. Further, the
problem of inefficiency and copying when moving would suffice is far broader
than any single API, and likely better solved with some combination of
profiling, training, code review, and static analysis.&lt;/p&gt;

&lt;p&gt;In the rare case when you &lt;em&gt;can&lt;/em&gt; know for sure that an API has to be used in a
particular fashion: you probably should encode that in the types in question.
Don’t operate on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; as your representation of a DNA sequence; write a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dna&lt;/code&gt; class and make it move-only with an explicit (easy to scan for) way to do
the expensive copy operation. Put another way: properties of types should be
expressed in those types, not in the APIs that operate on them.&lt;/p&gt;

&lt;h3 id=&quot;ref-qualification&quot;&gt;Ref-qualification&lt;/h3&gt;

&lt;p&gt;As a side note: it’s possible to apply the same reasoning for ref-qualifiers on
destructive accessors. Consider a class like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::stringbuf&lt;/code&gt; - in C++20 it
gained an accessor to consume the contained string, presented as an overload set
with the existing accessor:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
const std::string&amp;amp; str() const &amp;amp;;
std::string str() &amp;amp;&amp;amp;;
&lt;/pre&gt;

&lt;p&gt;(See &lt;a href=&quot;/tips/148&quot;&gt;Tip #148&lt;/a&gt; for more info on reference-qualified methods and
overload sets). Looking at existing usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::stringbuf&lt;/code&gt;, nearly every use
has a single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stringbuf&lt;/code&gt; that is used to produce one string. Ignoring the legacy
code, would it not be best to enforce that, and provide &lt;em&gt;only&lt;/em&gt; the “efficient”
ref-qualified destructive member?&lt;/p&gt;

&lt;p&gt;Of course not, for similar reasons to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DnaScan&lt;/code&gt; example above: you cannot
know certainly that nobody needs it, and it’s not &lt;em&gt;unsafe&lt;/em&gt; to provide the const
overload. Use ref-qualifiers only as an overload set for optimization, or when
the ref-qualifiers are necessary to enforce semantic correctness.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;It is tempting to try to use rvalue-references or reference qualifiers in
conjunction with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt; to provide a more “user friendly” API, enforcing
lifetimes or preventing optimization problems. In practice, those are usually
bad temptations. Lifetime requirements are much more complicated than the C++
type system can express. API providers can rarely predict every future valid
usage of their API. Avoiding these types of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt; tricks keeps things
simple.&lt;/p&gt;
</description>
          <pubDate>2018-05-03T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/149</link>
          <guid isPermaLink="true">https://abseil.io/tips/149</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #148: Overload Sets</title>
          <description>&lt;p&gt;Originally posted as TotW #148 on May 3, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:titus@cs.ucr.edu&quot;&gt;Titus Winters&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/148&quot;&gt;abseil.io/tips/148&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One of the effects of living with electric information is that we live
habitually in a state of information overload. There’s always more than you can
cope with. –Marshall McLuhan&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In my opinion, one of the most powerful and insightful sentences in the C++
style guide is this: “Use overloaded functions (including constructors) only if
a reader looking at a call site can get a good idea of what is happening without
having to first figure out exactly which overload is being called.”&lt;/p&gt;

&lt;p&gt;On the surface, this is a pretty straightforward rule: overload only when it
won’t cause confusion to a reader. However, the ramifications of this are
actually fairly significant and touch on some interesting issues in modern API
design. First let’s define the term “overload set”, and then let’s look at some
examples.&lt;/p&gt;

&lt;h2 id=&quot;what-is-an-overload-set&quot;&gt;What is an Overload Set?&lt;/h2&gt;

&lt;p&gt;Informally, an overload set is a set of functions with the same name that differ
in the number, type and/or qualifiers of their parameters. (See
&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/overload_resolution&quot;&gt;Overload Resolution&lt;/a&gt;
for all the gory details.) You may not overload on the return type from a
function - the compiler must be able to tell which member of the overload set to
call based on the invocation of the function, regardless of return type.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
int Add(int a, int b);
int Add(int a, int b, int c);  // Number of parameters may vary

// Return type may vary, as long as the selected overload is uniquely
// identifiable from only its parameters (types and counts).
float Add(float a, float b);

// But if two return types have the same parameter signature, they can&apos;t form a
// proper overload set; the following won&apos;t compile with the above overloads.
int Add(float a, float b);    // BAD - can&apos;t overload on return type
&lt;/pre&gt;

&lt;h2 id=&quot;string-ish-parameters&quot;&gt;String-ish Parameters&lt;/h2&gt;

&lt;p&gt;Thinking back on my earliest experiences with C++ at Google, I’m almost positive
that the first overloads I encountered were of the form:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void Process(const std::string&amp;amp; s) { Process(s.c_str()); }
void Process(const char*);
&lt;/pre&gt;

&lt;p&gt;The wonderful thing about overloads of this form is that they meet the letter
and the spirit of the rule, in a very obvious fashion. There is no behavioral
difference here: in both cases, we’re accepting some form of string-ish data,
and the inline forwarding function makes it perfectly clear that the behavior of
every member of the overload set is identical.&lt;/p&gt;

&lt;p&gt;That turns out to be critical, and easy to overlook, since the
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Function_Overloading&quot;&gt;Google C++ style guide&lt;/a&gt;
doesn’t phrase it explicitly: if the documented behavior of the members of an
overload set varies, then a user implicitly has to know which function is
actually being called. The only way to ensure that they have a “good idea what
is happening” without figuring which overload is being called is if the
semantics of each entry in the overload set are identical.&lt;/p&gt;

&lt;p&gt;So, the string-ish examples above work because they have identical semantics.
Borrowing an example from the
&lt;a href=&quot;https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c163-overload-only-for-operations-that-are-roughly-equivalent&quot;&gt;C++ Core Guidelines&lt;/a&gt;
, we would not want to see something like:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
// remove obstacle from garage exit lane
void open(Gate&amp;amp; g);

// open file
void open(const char* name, const char* mode =&quot;r&quot;);
&lt;/pre&gt;

&lt;p&gt;Hopefully, namespace differences suffice to disambiguate functions like these
from actually forming an overload set. Fundamentally, this would be a bad design
specifically because APIs should be understood and documented at the level of
the overload set, not the individual functions that make it up.&lt;/p&gt;

&lt;h2 id=&quot;strcat&quot;&gt;StrCat&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrCat()&lt;/code&gt; is one of the most common Abseil examples for demonstrating that
overload sets are often the right granularity for API design. Over the years,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrCat()&lt;/code&gt; has changed the number of parameters it accepts, and the form that it
uses to express that parameter count. Years ago, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrCat()&lt;/code&gt; was a set of
functions with varying arity. Now, it is conceptually a variadic template
function … although for optimization reasons small-count arities are still
provided as overloads. It has never actually been a single function - we just
treat it conceptually as one entity.&lt;/p&gt;

&lt;p&gt;This is a good use of overload sets - it would be annoying and redundant to
encode the parameter count in the function name, and conceptually it doesn’t
matter how many things are passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrCat()&lt;/code&gt; - it will always be the “convert
to string and concatenate” tool.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;parameter_sinks&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;parameter-sinks&quot;&gt;Parameter Sinks&lt;/h2&gt;

&lt;p&gt;Another technique that the standard uses and that comes up in a lot of generic
code is to overload on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&amp;amp;&amp;amp;&lt;/code&gt; when passing a value that will be
stored: a value sink. Consider &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector::push_back()&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void push_back(const T&amp;amp;);
void push_back(T&amp;amp;&amp;amp;);
&lt;/pre&gt;

&lt;p&gt;It’s worth considering the origin of this overload set: when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt;
API first appeared, it contained &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back(const T&amp;amp;)&lt;/code&gt; which served as a cheap
(and safe) parameter to pass. With C++11 the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back(T&amp;amp;&amp;amp;)&lt;/code&gt; overload was added
as an optimization for cases where the value is a temporary, or the caller has
promised not to interfere with the parameter by writing out &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt;. Even
though the moved-from object may be left in a different state, these still
provide the same semantics for the user of the vector, so we consider them a
well-designed overload set.&lt;/p&gt;

&lt;p&gt;Put another way, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; qualifiers denote whether that overload is
available for lvalue or rvalue expressions; if you have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;var&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;var&amp;amp;&lt;/code&gt;
argument, you will get the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt; overload, but if you have a temporary or have
performed a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt; on your expression, you will get the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; overload.
(See &lt;a href=&quot;/tips/77&quot;&gt;Tip #77&lt;/a&gt; for more on move-semantics.)&lt;/p&gt;

&lt;p&gt;Interestingly, these overloads are semantically the same as a single method –
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back(T)&lt;/code&gt; – but in some cases may be slightly more efficient. Such
efficiency mostly matters when the body of the function is cheap compared to the
cost of invoking the move constructor for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; – possible for containers and
generics, but unlikely in many other contexts. We generally recommend that if
you need to sink a value (store in an object, mutate a parameter, etc) you just
provide the single function accepting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt;) for simplicity and
maintainability. Only if you are writing very high-performance generic code is
the difference likely to be relevant. See &lt;a href=&quot;/tips/77&quot;&gt;Tip #77&lt;/a&gt; and
&lt;a href=&quot;/tips/117&quot;&gt;Tip #117&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;overloaded-accessors&quot;&gt;Overloaded Accessors&lt;/h2&gt;

&lt;p&gt;For methods on a class (especially a container or a wrapper), it is sometimes
valuable to provide an overload set for accessors. Standard library types
provide many great examples here - we’ll consider just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector::operator[]&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional::value()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector::operator[]&lt;/code&gt;, two overloads exist: one const and one
non-const, which accordingly return a const or non-const reference,
respectively. This matches our definition nicely; a user doesn’t need to know
which thing is invoked. The semantics are the same, differing only in
constness – if you have a non-const &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; you get a non-const reference, and
if you have a const &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; you get a const reference. Put another way: the
overload set is purely forwarding the const-ness of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt;, but the API is
consistent – it just gives you the indicated element.&lt;/p&gt;

&lt;p&gt;In C++17 we added &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;T&amp;gt;&lt;/code&gt;, a wrapper for at most one value of an
underlying type. Just like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector::operator[]&lt;/code&gt;, when accessing
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional::value()&lt;/code&gt; both const and non-const overloads exist. However,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&lt;/code&gt; goes one step further and provides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value()&lt;/code&gt; overloads based on
“value category” (roughly speaking, whether the object is a temporary). So the
full pairwise combination of const and value category looks like:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
T&amp;amp; value() &amp;amp;;
const T &amp;amp; value() const &amp;amp;;
T&amp;amp;&amp;amp; value() &amp;amp;&amp;amp;;
const T&amp;amp;&amp;amp; value() const &amp;amp;&amp;amp;;
&lt;/pre&gt;

&lt;p&gt;The trailing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; apply to the implicit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*this&lt;/code&gt; parameter, just in the
same way const qualifying a method does, and indicate acceptance of lvalue or
rvalue arguments as noted in &lt;a href=&quot;#parameter_sinks&quot;&gt;Parameter Sinks&lt;/a&gt; above.
Importantly, however, you don’t actually need to understand move semantics to
understand &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional::value()&lt;/code&gt; in this case. If you ask for the value out of a
temporary, you get the value as if it were a temporary itself. If you ask for
the value out of a const ref, you get a const-ref of the value. And so on.&lt;/p&gt;

&lt;h2 id=&quot;copy-vs-move&quot;&gt;Copy vs. Move&lt;/h2&gt;

&lt;p&gt;The most important overload sets for types are often their set of constructors,
especially the copy and move constructors. Copy and move, done right, form an
overload set in all senses of the term: the reader should not need to know which
of those overloads is chosen, because the semantics of the newly-constructed
object should be the same in either case (assuming both constructors exist). The
standard library is becoming more explicit about this: move is assumed to be an
optimization of copy, and you should not depend on the particulars of how many
moves or copies are made in any given operation.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Overload sets are a simple idea conceptually, but prone to abuse when not well
understood - don’t produce overloads where anyone might need to know which
function was chosen. But when used well, overload sets provide a powerful
conceptual framework for API design. Understanding the subtleties of the style
guide’s description of overload sets is well worth your time when thinking about
API design.&lt;/p&gt;
</description>
          <pubDate>2018-05-03T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/148</link>
          <guid isPermaLink="true">https://abseil.io/tips/148</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #117: Copy Elision and Pass-by-value</title>
          <description>&lt;p&gt;Originally posted as TotW #117 on June 8, 2016&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Geoff Romer, &lt;a href=&quot;mailto:gromer@gmail.com&quot;&gt;(gromer@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Everything is so far away, a copy of a copy of a copy. The insomnia distance
of everything, you can’t touch anything and nothing can touch you.” — Chuck
Palahniuk&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Suppose you have a class like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Widget&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;

 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;How would you write its constructor? For years, the answer has been to do it
like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// First constructor version&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;explicit&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Widget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, there is an alternative approach which is becoming more common:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Second constructor version&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;explicit&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Widget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(If you’re not familiar with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt;, see &lt;a href=&quot;/tips/77&quot;&gt;TotW #77&lt;/a&gt;, or
pretend I used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::swap&lt;/code&gt; instead; the same principles apply). What’s going
on here? Isn’t it horribly expensive to pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; by copy? It turns
out that no, sometimes passing by value (as we’ll see, it’s not really “by
copy”) can be much more efficient than passing by reference.&lt;/p&gt;

&lt;p&gt;To understand why, consider what happens when the callsite looks like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Widget&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;widget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrCat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With the first version of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget&lt;/code&gt; constructor, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt; produces
a temporary string containing the concatenated string values, which is
passed by reference into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget()&lt;/code&gt;, and then the string is copied into
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name_&lt;/code&gt;. With the second version of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget&lt;/code&gt; constructor, the temporary
string is passed into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget()&lt;/code&gt; by value, which you might think would cause
the string to be copied, but this is where the magic happens. When the
compiler sees a temporary being used to copy-construct an object, the
compiler will&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; simply use the same storage for both the temporary and
the new object, so that copying from the one to the other is literally free;
this is called &lt;em&gt;copy elision&lt;/em&gt;. Thanks to this optimization, the string is
never copied, but only moved once, which is a cheap constant-time operation.&lt;/p&gt;

&lt;p&gt;Consider what happens when the argument isn’t a temporary:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Widget&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;widget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case, both versions of the code make a copy of the string, but the
second version also moves the string. That, again, is a cheap constant-time
operation, whereas copying is a linear-time operation, so in many cases that
will be a price well worth paying.&lt;/p&gt;

&lt;p&gt;The key property of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; parameter that makes this technique work is that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; has to be copied. Indeed, the essence of this technique is to try to make
the copy operation happen on the function call boundary, where it can be elided,
rather than in the interior of the function. This need not necessarily involve
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt;; for example, if the function needs to mutate the copy rather than
store it, it may just be mutated in place.&lt;/p&gt;

&lt;h2 id=&quot;when-to-use-copy-elision&quot;&gt;When to Use Copy Elision&lt;/h2&gt;

&lt;p&gt;Passing parameters by value has several drawbacks which should be borne in mind.
First of all, it makes the function body more complex, which creates a
maintenance and readability burden. For example, in the code above, we’ve added
a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt; call, which creates a risk of accidentally accessing a moved-from
value. In this function that risk is pretty minimal, but if the function were
more complex, the risk would be higher.&lt;/p&gt;

&lt;p&gt;Second, it can degrade performance, sometimes in surprising ways. It can
sometimes be difficult to tell whether it’s a net performance win without
profiling a specific workload.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;As stated above, this technique applies only to parameters that need to be
copied; it will be useless at best and harmful at worst when applied to
parameters that don’t need to be copied, or only need to be copied
conditionally.&lt;/li&gt;
  &lt;li&gt;This technique often involves some amount of extra work in the function
body, such as the move assignment in the example above. If that extra work
imposes too much overhead, the slowdown in the cases where the copy can’t be
elided may not be worth the speedup in the cases where the copy can be
elided. Note that this determination can depend on the particulars of your
use case. For example, if the arguments to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget()&lt;/code&gt; are almost always very
short, or are almost never temporaries, this technique may be harmful on
balance. As always when considering optimization tradeoffs, when in doubt,
measure.&lt;/li&gt;
  &lt;li&gt;When the copy in question is a copy &lt;em&gt;assignment&lt;/em&gt; (for example if we wanted
to add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_name()&lt;/code&gt; method to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget&lt;/code&gt;), the pass-by-reference version can
sometimes avoid memory allocation by reusing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name_&lt;/code&gt;’s existing buffer, in
cases where the pass-by-value version would allocate new memory. In
addition, the fact that pass-by-value always replaces &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name_&lt;/code&gt;’s allocation
can lead to worse allocation behavior down the line: if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name_&lt;/code&gt; field
tends to grow over time after it is set, that growth will require further
new allocations in the pass-by-value case, whereas in the pass-by-reference
case we only reallocate when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name_&lt;/code&gt; field exceeds its historical
maximum size.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generally speaking, you should prefer simpler, safer, more readable code, and
only go for something more complex if you have concrete evidence that the
complex version performs better and that the difference matters. That principle
certainly applies to this technique: passing by const reference is simpler and
safer, so it’s still a good default choice. However, if you’re working in an
area that’s known to be performance-sensitive, or your benchmarks show that
you’re spending too much time copying function parameters, passing by value can
be a very useful tool to have in your toolbox.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Strictly speaking the compiler is not &lt;em&gt;required&lt;/em&gt; to perform copy elision,
but it is such a powerful and vitally important optimization that it is
extremely unlikely that you will ever encounter a compiler that doesn’t do
it. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
          <pubDate>2018-05-03T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/117</link>
          <guid isPermaLink="true">https://abseil.io/tips/117</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #24: Copies, Abbrv.</title>
          <description>&lt;p&gt;Originally posted as TotW #24 on Nov 26, 2012&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Titus Winters, &lt;a href=&quot;mailto:titus@gmail.com&quot;&gt;(titus@google.com)&lt;/a&gt; and
Chandler Carruth &lt;a href=&quot;mailto:chandlerc@google.com&quot;&gt;(chandlerc@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“To copy others is necessary, but to copy oneself is pathetic.” - Pablo
Picasso&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Note: see also &lt;a href=&quot;/tips/55&quot;&gt;TotW #55&lt;/a&gt; and &lt;a href=&quot;/tips/77&quot;&gt;TotW #77&lt;/a&gt; for guidance
on name counting and copies vs. moves.&lt;/p&gt;

&lt;h2 id=&quot;one-name-no-copy-two-names-two-copies&quot;&gt;One Name, No Copy; Two Names, Two Copies&lt;/h2&gt;

&lt;p&gt;When evaluating whether copies get made within any given scope (including cases
triggering RVO), check how many names your data refers to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You will have two copies of the data at any point where you have two live
names for those copies.&lt;/strong&gt; To a good first approximation, the compiler will (and
often must) elide copies in all other cases.&lt;/p&gt;

&lt;p&gt;Between the move semantics of STL containers (introduced automatically with
the switch to C++11) and copy constructor elision by the compiler, we are
rapidly converging on this rule providing not merely a lower bound on the number
of copies, but a guarantee. If your benchmarks show that more copies are being
made, it is &lt;strong&gt;likely a compiler bug&lt;/strong&gt;; your compiler probably needs a fix.&lt;/p&gt;

&lt;p&gt;So if your code is structured such that there are two names for the data at some
point during the execution, you should expect a copy. If you avoid introducing a
name which could possibly refer to the data, you’ll help ensure the compiler can
remove the copy.&lt;/p&gt;

&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;/h2&gt;

&lt;p&gt;Let’s look at some examples of how this works in practice:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// no copying here, only one name for the data “arg”.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// only 1 instance -- only 1 name&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// no copying, a reference won’t incur a copy&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_ref&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// one copy operation, there are now two named collections of data.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Most of the time, none of this matters. It is far more important to ensure that
your code is readable and consistent, rather than worrying about copies and
performance. As always: profile before you optimize. But, if you find yourself
writing code from scratch – and can provide a clean and consistent API that
returns its values – don’t discount code that seems like it would make copies:
everything you learned about copies in C++ a decade ago is wrong.&lt;/p&gt;
</description>
          <pubDate>2018-04-20T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/24</link>
          <guid isPermaLink="true">https://abseil.io/tips/24</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #120: Return Values are Untouchable</title>
          <description>&lt;p&gt;Originally posted as TotW #120 on August 16, 2012&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Samuel Benzaquen, &lt;a href=&quot;mailto:sbenza@google.com&quot;&gt;(sbenza@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s suppose you have this code snippet, which seems to be working as expected:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cleanup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_on_error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LOG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ERROR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A refactor changes the last line from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return status;&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return
absl::OkStatus();&lt;/code&gt; and suddenly the code stopped logging the errors.&lt;/p&gt;

&lt;p&gt;What is going on?&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Never access (read or write) the return variable after the return statement has
run. Unless you take great care to do it correctly, the behavior is unspecified.&lt;/p&gt;

&lt;p&gt;Return variables are implicitly accessed by destructors after they have been
copied or moved ([stmt.return]), which is how this unexpected access occurs, but
the copy/move may be elided, which is why behavior is unspecified.&lt;/p&gt;

&lt;p&gt;This tip only applies when you are returning a non-reference local variable.
Returning any other expression will not trigger this problem.&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;

&lt;p&gt;There are 2 different optimizations on return statements that can modify the
behavior of that code snippet: the named return value optimization (NRVO) and
implicit moves.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;before&lt;/em&gt; code was working because NRVO is being performed and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt;
statement is not actually doing any work. The variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;status&lt;/code&gt; is already
constructed in the return address and the cleanup object is seeing this unique
instance of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; object &lt;em&gt;after&lt;/em&gt; the return statement.&lt;/p&gt;

&lt;p&gt;In the &lt;em&gt;after&lt;/em&gt; code, NRVO is not being performed and the returned variable is
being moved into the return value. The cleanup object is being run after the
move operation is done and it is seeing a moved-from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that the &lt;em&gt;before&lt;/em&gt; code was not correct either, as it relies on NRVO for
correctness. We encourage you to rely on NRVO for performance (See TotW #24),
but not correctness. After all, NRVO is an &lt;em&gt;optional&lt;/em&gt; optimization and compiler
options or quality of implementation of the compiler can affect whether or not
it happens.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;p&gt;Do not touch the return variable after the return statement. Be careful of
destructors of local variables doing so implicitly.&lt;/p&gt;

&lt;p&gt;The simplest solution is to separate the function in two. One that does all the
processing, and one that calls the first one and does the post-processing (ie
logging on error). Eg:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoSomethingAndLog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LOG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ERROR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you are only reading the value, you could also make sure to disable the
optimizations instead. That would force a copy to be made all the time and the
post-processing will not see a moved-from value. Eg:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status_no_nrvo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// &apos;status&apos; is a reference so NRVO and all associated optimizations&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// will be disabled.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// The &apos;return status;&apos; statements will always copy the object and Logger&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// will always see the correct value.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status_no_nrvo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cleanup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_on_error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LOG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ERROR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;another-real-life-example&quot;&gt;Another Real Life Example&lt;/h2&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;EncodeVarInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;proto2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StringOutputStream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;proto2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodedOutputStream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coded_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;coded_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WriteVarint32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CodedOutputStream&lt;/code&gt; does some work on the destructor to trim unused trailing
bytes. This function can leave garbage bytes on the string if NRVO does not
happen.&lt;/p&gt;

&lt;p&gt;Note that in this case you can’t force NRVO to happen and the trick to disable
it won’t help. We must modify the return value before the return statement runs.&lt;/p&gt;

&lt;p&gt;A good solution is to add a block and restrict the function to only return after
the block is finished. Like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;EncodeVarInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;proto2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StringOutputStream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;proto2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodedOutputStream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coded_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;coded_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WriteVarint32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// At this point the streams are destroyed and they already flushed.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// We can safely return &apos;out&apos;.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Don’t hold on to references to variables that are being returned.&lt;/p&gt;

&lt;p&gt;You can’t control whether NRVO happens or not. Compiler versions and options can
change this from underneath you. Do not depend on it for correctness.&lt;/p&gt;

&lt;p&gt;You can’t control whether returning a local variable triggers an implicit move
or not. The type you use might be updated in the future to support move
operations. Moreover, future language standards will apply implicit moves on
even more situations so you can’t assume that just because it is not happening
now it won’t happen in the future.&lt;/p&gt;
</description>
          <pubDate>2018-04-20T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/120</link>
          <guid isPermaLink="true">https://abseil.io/tips/120</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #11: Return Policy</title>
          <description>&lt;p&gt;Originally posted as TotW #11 on August 16, 2012&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Paul S. R. Chisholm &lt;a href=&quot;mailto:p.s.r.chisholm@gmail.com&quot;&gt;(p.s.r.chisholm@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Frodo: There’ll be none left for the return journey.&lt;/em&gt; &lt;em&gt;Sam: I don’t think there
will be a return journey, Mr. Frodo.&lt;/em&gt; – The Lord of the Rings: The Return of
the King (novel by J.R.R. Tolkien, screenplay by Fran Walsh, Philippa Boyens, &amp;amp;
Peter Jackson)&lt;/p&gt;

&lt;p&gt;Note: this tip, though still relevant, preceded the introduction of move
semantics in C++11. Please read this tip with the advice from
&lt;a href=&quot;/tips/77&quot;&gt;TotW #77&lt;/a&gt; also in mind.&lt;/p&gt;

&lt;p&gt;Many older C++ codebases show patterns that are somewhat fearful of copying
objects. Happily, we can “copy” without copying, thanks to something called
&lt;a href=&quot;http://en.wikipedia.org/wiki/Return_value_optimization&quot;&gt;“return value optimization”&lt;/a&gt;
(RVO).&lt;/p&gt;

&lt;p&gt;RVO is a long-standing feature of almost all C++ compilers. Consider the
following C++98 code, which has a copy constructor and an assignment operator.
These functions are so expensive, the developer had them print a message every
time they’re used:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Expensive copy …&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Expensive assignment …&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(Note that we’re intentionally avoiding discussion of move operations here.
See &lt;a href=&quot;/tips/77&quot;&gt;TotW #77&lt;/a&gt; for more information.)&lt;/p&gt;

&lt;p&gt;Would you recoil in horror if this class had a factory method such as the
following?&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SomeBigObjectFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looks inefficient, doesn’t it? What happens if we run the following?&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObjectFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Simple answer: You probably expect there to be at least two objects created:
the object returned from the called function, and the object in the calling
function. Both are copies, so the program prints two messages about expensive
operations. Real-world answer: No message is printed – because the copy
constructor and assignment operator were never called!&lt;/p&gt;

&lt;p&gt;How’d that happen? A lot of C++ programmers write “efficient code” that creates
an object and passes that object’s address to a function, which uses that
pointer or reference to operate on the original object. Well, under the
circumstances described below, the compiler can transform such “an inefficient
copy” into that “efficient code”!&lt;/p&gt;

&lt;p&gt;When the compiler sees a variable in the calling function (that will be
constructed from the return value), and a variable in the called function (that
will be returned), it realizes it doesn’t need both variables. Under the covers,
the compiler passes the address of the calling function’s variable to the called
function.&lt;/p&gt;

&lt;p&gt;To quote the C++98 standard, “Whenever a temporary class object is copied using
a copy constructor … an implementation is permitted to treat the original and
the copy as two different ways of referring to the same object and not perform a
copy at all, even if the class copy constructor or destructor have side effects.
For a function with a class return type, if the expression in the return
statement is the name of a local object … an implementation is permitted to omit
creating the temporary object to hold the function return value …” (Section 12.8
[class.copy], paragraph 15 of the C++98 standard. The C++11 standard has similar
language in section 12.8, paragraph 31, but it’s more complicated.)&lt;/p&gt;

&lt;p&gt;Worried that “permitted” isn’t a very strong promise? Fortunately, all modern C++
compilers perform RVO by default, even in debug builds, even for non-inlined
functions.&lt;/p&gt;

&lt;h2 id=&quot;how-can-you-ensure-the-compiler-performs-rvo&quot;&gt;How Can You Ensure the Compiler Performs RVO?&lt;/h2&gt;

&lt;p&gt;The called function should define a single variable for the return value:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObjectFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The calling function should assign the returned value to a new variable:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// No message about expensive operations:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObjectFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it!&lt;/p&gt;

&lt;p&gt;The compiler can’t do RVO if the calling function reuses an existing variable to
store the return value (though move semantics would apply for move-enabled types
in this case):&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// RVO won’t happen here; prints message &quot;Expensive assignment ...&quot;:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObjectFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The compiler also can’t do RVO if the called function uses more than one
variable for the return value:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// RVO won’t happen here:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;NonRvoFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;object1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DoSomethingWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;object2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DoSomethingWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But it’s okay if the called function uses one variable and returns it in
multiple places:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// RVO will happen here:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(...)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DoSomethingWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DoSomethingWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s probably all you &lt;strong&gt;need&lt;/strong&gt; to know about RVO.&lt;/p&gt;

&lt;h2 id=&quot;one-more-thing-temporaries&quot;&gt;One More Thing: Temporaries&lt;/h2&gt;

&lt;p&gt;RVO works with temporary objects, not just named variables. You
can benefit from RVO when the called function returns a temporary object:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// RVO works here:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReturnsTempFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObjectFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also benefit from RVO when the calling function immediately uses the
returned value (which is stored in a temporary object):&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// No message about expensive operations:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EXPECT_EQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeBigObjectFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A final note: If your code needs to make copies, then make copies, whether or
not the copies can be optimized away. Don’t trade correctness for efficiency.&lt;/p&gt;
</description>
          <pubDate>2018-04-20T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/11</link>
          <guid isPermaLink="true">https://abseil.io/tips/11</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #143: C++11 Deleted Functions (&lt;code&gt;= delete&lt;/code&gt;)</title>
          <description>&lt;p&gt;Originally posted as TotW #143 on March 2, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:mosescu@google.com&quot;&gt;Leonard Mosescu&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/143&quot;&gt;abseil.io/tips/143&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Interfaces, in a general sense, normally define the set of operations which can
be invoked. Yet sometimes we may want to express the opposite: explicitly define
a set of operations which should &lt;em&gt;not&lt;/em&gt; be used. For example, disabling the copy
constructor and copy assignment operator is a common way to restrict copy
semantics for a particular type.&lt;/p&gt;

&lt;p&gt;The language offers multiple options to effect such restrictions (and we’ll
explore each one shortly):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Provide a dummy definition consisting solely of a &lt;em&gt;runtime&lt;/em&gt; check.&lt;/li&gt;
  &lt;li&gt;Use accessibility controls (protected/private) to make the function
inaccessible.&lt;/li&gt;
  &lt;li&gt;Declare the function, but intentionally omit the definition.&lt;/li&gt;
  &lt;li&gt;Since C++11: Explicitly define the function as “deleted”.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The pre-C++11 techniques range from runtime checks (#1) to compile-time (#2) or
link time (#3) diagnostics. While battle-proven, these techniques are far from
perfect: a runtime check is not ideal for the majority of situations where the
constraint is static, and the link-time check delays the diagnostic to very late
in the build process. Moreover, link time diagnostics are not guaranteed
(missing a definition for an ODR-used function is an ODR violation) and the
actual diagnostic messages are rarely developer-friendly.&lt;/p&gt;

&lt;p&gt;A compile time check is better, but still flawed. It only works for member
functions and is based on accessibility constraints, which are verbose,
error-prone and susceptible to loopholes. Moreover, the errors that result from
referencing such functions can be misleading, referring as they do to access
restrictions rather than interface misuse.&lt;/p&gt;

&lt;p&gt;The application of #2 and #3 to disable copying would look like this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class MyType {
 private:
  MyType(const MyType&amp;amp;);  // Not defined anywhere.
  MyType&amp;amp; operator=(const MyType&amp;amp;);  // Not defined anywhere.
  // ...
};
&lt;/pre&gt;

&lt;p&gt;Manually applying this for every class gets old really fast, so developers
commonly package them in one of these ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The “mixin” approach&lt;/strong&gt; (&lt;a href=&quot;http://www.boost.org/doc/libs/master/libs/core/doc/html/core/noncopyable.html&quot;&gt;boost::noncopyable&lt;/a&gt;,
&lt;a href=&quot;https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-copyable_Mixin&quot;&gt;non-copyable mixin&lt;/a&gt;)&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class MyType : private NoCopySemantics {
  ...
};
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;The macros approach&lt;/strong&gt;&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class MyType {
 private:
  DISALLOW_COPY_AND_ASSIGN(MyType);
};
&lt;/pre&gt;

&lt;h2 id=&quot;c11-deleted-definitions&quot;&gt;C++11 Deleted Definitions&lt;/h2&gt;

&lt;p&gt;C++11 addressed the need for a better solution through a new language feature:
deleted definitions [&lt;em&gt;dcl.fct.def.delete&lt;/em&gt;]. (See “deleted definitions” in the
&lt;a href=&quot;http://eel.is/c++draft/dcl.fct.def.delete&quot;&gt;C++ standard draft&lt;/a&gt;.) Any function can be explicitly &lt;em&gt;defined as
deleted:&lt;/em&gt;&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void foo() = delete;
&lt;/pre&gt;

&lt;p&gt;The syntax is straightforward, resembling &lt;a href=&quot;131&quot;&gt;defaulted functions&lt;/a&gt;, although
with a couple of notable differences:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Any function can be deleted, including non-member functions (in contrast to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt;, which works only with special member functions).&lt;/li&gt;
  &lt;li&gt;Functions must be deleted on the first declaration only (unlike &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The key thing to keep in mind is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt; is a function &lt;em&gt;definition&lt;/em&gt; (it
does not remove or hide the declaration). The deleted function is thus defined
and participates in name lookup and overload resolution as any other function.
It’s a special kind of &lt;em&gt;“radioactive”&lt;/em&gt; definition which says &lt;em&gt;“don’t touch!”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Attempts to use a deleted function result in a &lt;em&gt;compile time&lt;/em&gt; error with a clear
diagnostic, which is one of the key benefits over the pre-C++11 techniques.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class MyType {
 public:
  // Disable default constructor.
  MyType() = delete;

  // Disable copy (and move) semantics.
  MyType(const MyType&amp;amp;) = delete;
  MyType&amp;amp; operator=(const MyType&amp;amp;) = delete;

  //...
};
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// error: call to deleted constructor of &apos;MyType&apos;
// note: &apos;MyType&apos; has been explicitly marked deleted here
//   MyType() = delete;
MyType x;

void foo(const MyType&amp;amp; val) {
  // error: call to deleted constructor of &apos;MyType&apos;
  // note: &apos;MyType&apos; has been explicitly marked deleted here
  //   MyType(const MyType&amp;amp;) = delete;
  MyType copy = val;
}
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: by explicitly defining the copy operations as deleted we also suppress
the move operations (having user-declared copy operations inhibits the implicit
declaration of the move operations). If the intention is to define a move-only
type using the implicit move operations, &lt;a href=&quot;131&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt;&lt;/a&gt; can be used to “bring
them back”, for example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
MyType(MyType&amp;amp;&amp;amp;) = default;
MyType&amp;amp; operator=(MyType&amp;amp;&amp;amp;) = default;
&lt;/pre&gt;

&lt;h2 id=&quot;other-uses&quot;&gt;Other Uses&lt;/h2&gt;

&lt;p&gt;While the examples above are centered on copy semantics (which is likely the
most common case), any function (member or not) can be deleted.&lt;/p&gt;

&lt;p&gt;Since deleted functions participate in overload resolution they can help catch
unintended uses. Let’s say we have the following overloaded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print&lt;/code&gt; function:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void print(int value);
void print(absl::string_view str);
&lt;/pre&gt;

&lt;p&gt;Calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print(&apos;x&apos;)&lt;/code&gt; will print the integer value of ‘x’, when the developer
likely intended &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print(&quot;x&quot;)&lt;/code&gt;. We can catch this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void print(int value);
void print(const char* str);
// Use string literals &quot;:&quot; instead of character literals &apos;:&apos;.
void print(char) = delete;
&lt;/pre&gt;

&lt;p&gt;Note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt; doesn’t affect just function calls. Attempting to take the
address of a deleted function will also result in a compilation error:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void (*pfn1)(int) = &amp;print;  // ok
void (*pfn2)(char) = &amp;print; // error: attempt to use a deleted function
&lt;/pre&gt;

&lt;p&gt;This example is extracted from a real world application:
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/092ed9793a1ad0e7e418f32c057bf3159a71cd04/absl/strings/str_cat.h#L257&quot;&gt;absl::StrCat()&lt;/a&gt;. Deleted functions are valuable any time a particular
part of an interface must be restricted.&lt;/p&gt;

&lt;p&gt;Defining destructors as deleted is stricter than making them private (although
this is a big hammer and it may introduce more limitations than intended)&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// A _very_ limited type:
//   1. Dynamic storage only.
//   2. Lives forever (can&apos;t be destructed).
//   3. Can&apos;t be a member or base class.
class ImmortalHeap {
 public:
  ~ImmortalHeap() = delete;
  //...
};
&lt;/pre&gt;

&lt;p&gt;Yet another example, this time we want to only allow the allocation of non-array
objects ([real world example][crashpad]):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Don&apos;t allow new T[].
class NoHeapArraysPlease {
 public:
  void* operator new[](std::size_t) = delete;
  void operator delete[](void*) = delete;
};

auto p = new NoHeapArraysPlease;  // OK

// error: call to deleted function &apos;operator new[]&apos;
// note: candidate function has been explicitly deleted
//   void* operator new[](std::size_t) = delete;
auto pa = new NoHeapArraysPlease[10];
&lt;/pre&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt; offers an explicit way to express parts of an interface which should
not be referenced, also enabling better diagnostics than the pre-C++11 idioms.
No piece of code, including compiler generated code, can reference a deleted
function. For nuanced access control, the access specifiers or more elaborate
techniques (for example, the passkey idiom as discussed in &lt;a href=&quot;134&quot;&gt;Tip #134&lt;/a&gt;) are
more appropriate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Since the deleted definitions are part of the interface they
should have the same access specifier as the other parts of the interface.
Concretely, this means they should usually be public. In practice this also
results in the best diagnostics (private and =delete doesn’t make much sense).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credits&lt;/strong&gt;: This tip includes key contributions and feedback from many people,
special thanks to: Mark Mentovai, James Dennett, Bruce Dawson and Yitzhak
Mandelbaum.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;131&quot;&gt;TotW #131: Special member functions and =default&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;134&quot;&gt;TotW #134: make_unique and private constructors&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/function#Deleted_functions&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delete&lt;/code&gt;d functions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/access&quot;&gt;access specifiers&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c81-use-delete-when-you-want-to-disable-default-behavior-without-wanting-an-alternative&quot;&gt;C++ Core Guidelines: C.81&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Copyable_Movable_Types&quot;&gt;Google C++ style guide: Copyable and Movable Types&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
          <pubDate>2018-03-15T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/143</link>
          <guid isPermaLink="true">https://abseil.io/tips/143</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #141: Beware Implicit Conversions to &lt;code&gt;bool&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #141 on January 19, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:sfreilich@google.com&quot;&gt;Samuel Freilich&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/141&quot;&gt;abseil.io/tips/141&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;two-kinds-of-null-pointer-checks&quot;&gt;Two Kinds of Null Pointer Checks&lt;/h2&gt;

&lt;p&gt;Checking a pointer for null before dereferencing is important to avoid crashes
and bugs. This can be done in two ways:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
if (foo) {
  DoSomething(*foo);
}
&lt;/pre&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
if (foo != nullptr) {
  DoSomething(*foo);
}
&lt;/pre&gt;

&lt;p&gt;Both of these conditionals have the same semantics given that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; is a
pointer, but the type-checking on the latter is a little tighter. Many types in
C++ can be implicitly converted to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;, and additional caution is required
when the pointed-to type can itself be converted to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Consider the following code which could have two very different meanings:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
bool* is_migrated = ...;

// Is this checking that `is_migrated` is not null, or was the actual
// intent to verify that `*is_migrated` is true?
if (is_migrated) {
  ...
}
&lt;/pre&gt;

&lt;p&gt;This code is clearer:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// Looks like a null-pointer check for a bool*
if (is_migrated != nullptr) {
  ...
}
&lt;/pre&gt;

&lt;p&gt;Both styles are acceptable in Google C++ code. So when the underlying type is
not implicitly convertible to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;, follow the style of surrounding code. If
the value in question is a “smart pointer” like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;, the semantics
and tradeoffs are the same.&lt;/p&gt;

&lt;h2 id=&quot;optional-values-and-scoped-assignments&quot;&gt;Optional Values and Scoped Assignments&lt;/h2&gt;

&lt;p&gt;What about optional (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt;) values? They deserve more careful
consideration.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
std::optional&amp;lt;bool&amp;gt; b = MaybeBool();
if (b) { ... }  // What happens when the function returns std::optional(false)?
&lt;/pre&gt;

&lt;p&gt;Putting the variable declaration in the conditional of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; statement
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Local_Variables&quot;&gt;limits the scope&lt;/a&gt;
of the variable, but the value is implicitly&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; converted to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;, so it
may not be explicit which boolean property is tested.&lt;/p&gt;

&lt;p&gt;The intent of the following code is clearer:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
std::optional&amp;lt;bool&amp;gt; b = MaybeBool();
if (b.has_value()) { ... }
&lt;/pre&gt;

&lt;p&gt;Note that, in fact, the code snippets above are equivalent: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&lt;/code&gt;’s
conversion to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt; only looks at whether the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&lt;/code&gt; is full, not at its
contents. A reader may find it counterintuitive that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional(false)&lt;/code&gt; is
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt;, but it’s immediately clear that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional(false)&lt;/code&gt; has a value. Again,
it’s worth extra caution when the underlying type is implicitly convertible to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One pattern for optional return values is to put a variable declaration in the
conditional of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; statement. This
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html/#Local_Variables&quot;&gt;limits the scope&lt;/a&gt;
of the variable, but involves an implicit conversion to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
if (std::optional&amp;lt;Foo&amp;gt; foo = MaybeFoo()) {
  DoSomething(*foo);
}
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In C++17, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; statements can contain an initializer, so the scope of
the declaration can be limited while avoiding the implicit conversion:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
if (std::optional&amp;lt;Foo&amp;gt; foo = MaybeFoo(); foo.has_value()) {
  DoSomething(*foo);
}
&lt;/pre&gt;

&lt;h2 id=&quot;boolean-like-enums&quot;&gt;“Boolean-like” Enums&lt;/h2&gt;

&lt;p&gt;Let’s say you’ve taken the advice of &lt;a href=&quot;/tips/94&quot;&gt;Tip #94&lt;/a&gt; and decided to use an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; in your function signature instead of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt; for better readability at
the call sites. This kind of refactoring might introduce an implicit conversion
in the function definition:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
void ParseCommandLineFlags(
    const char* usage, int* argc, char*** argv,
    StripFlagsMode strip_flags_mode) {
  if (strip_flags_mode) {  // Wait, which value was true again?
    ...
  }
}
&lt;/pre&gt;

&lt;p&gt;You can gain additional clarity by replacing the implicit conversion with an
explicit comparison:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void ParseCommandLineFlags(
    const char* usage, int* argc, char*** argv,
    StripFlagsMode strip_flags_mode) {
  if (strip_flags_mode == kPreserveFlags) {
    ...
  }
}
&lt;/pre&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;In summary, be aware that implicit conversions to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt; can be unclear, so
consider writing more explicit code:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Compare pointer types to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nullptr&lt;/code&gt; (especially if the pointed-at type is
implicitly convertible to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Test container emptiness with boolean functions like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::optional&amp;lt;T&amp;gt;::has_value()&lt;/code&gt; (especially if the contained type is
implicitly convertible to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;). Use the optional initializer form for
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; to limit the scope of variables (&lt;a href=&quot;/tips/165&quot;&gt;Tip #165&lt;/a&gt;). Remember
call-only interfaces though, and don’t take the address of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value()&lt;/code&gt; or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_value()&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;testing::Optional&lt;/code&gt; matcher can help in tests.&lt;/li&gt;
  &lt;li&gt;Compare enums to specific values.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;More specifically, it’s a
&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/implicit_conversion#Contextual_conversions&quot;&gt;“contextual conversion”&lt;/a&gt;. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
          <pubDate>2018-03-15T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/141</link>
          <guid isPermaLink="true">https://abseil.io/tips/141</guid>
        </item>
      
    
      
        <item>
          <title>What Should Go Into the C++ Standard Library</title>
          <description>&lt;p&gt;By Titus Winters (titus@google.com), @TitusWinters&lt;/p&gt;

&lt;p&gt;&lt;i&gt;&lt;b&gt;About the Author - &lt;/b&gt; Titus holds a PhD in Computer Science Education
from UC Riverside. He created most of Google’s internal C++ coursework, and
plays an active role in the C++ mentoring program that serves several thousand
Google C++ engineers.  He has been deeply involved in C++ library infrastructure
since 2011, through the Google C++ Library Team and now Abseil.  He chairs the
Library Evolution Working Group (LEWG) - the sub-committee of the C++ Standard
that focuses on the design of the C++ standard library.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;A few interesting pieces on the direction and design for C++ have circulated
recently.  First off, I strongly recommend everyone read through 
&lt;a href=&quot;http://wg21.link/P0939r0&quot;&gt;Direction for ISO C++&lt;/a&gt; ; it provides a lot of 
excellent detail and suggestions, as well as some much-needed guidance on how
the language should evolve.  In particular, I think it’s really important to
note “No language can be everything for everybody,” the technical “pillars” upon
which C++ rests, and the call to remind everyone to go read “The Design and
Evolution of C++”. The Direction Group is very rightly showing concern about the
breadth of things being proposed for the standard, as well as how to maintain
velocity and stability as we continue to move forward at an ever more rapid
pace.&lt;/p&gt;

&lt;!--break--&gt;

&lt;h3 id=&quot;batteries-included&quot;&gt;Batteries Included?&lt;/h3&gt;

&lt;p&gt;An &lt;a href=&quot;https://hatcat.com/?p=16&quot;&gt;interesting piece&lt;/a&gt; by Guy Davidson also
specifically focuses on what should be included in the C++ Standard Library,
with emphasis on a proposed 
&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0267r7.pdf&quot;&gt;Graphics library.&lt;/a&gt;
Guy (again, rightly) is concerned with what can and cannot be done with C++
easily and out of the box.  Guy argues we should aim for “batteries included,” a
much more all-inclusive approach than what is currently standardized. Especially
when you compare C++ to other languages, there’s a pretty strong argument to be
made for a more inclusive and even all-encompassing standard library - look at
the richness of the standard libraries for Java or Python.&lt;/p&gt;

&lt;p&gt;Interestingly, the Graphics library proposal is mentioned specifically in both
of these pieces. In the Direction Group’s paper, Graphics is forwarded as a way
to make C++ more accessible for beginners. In Guy’s piece, it’s an exemplar of
the “batteries included” philosophy, drawing comparisons from other languages
and trying to make C++ feel more fully-featured out of the box.&lt;/p&gt;

&lt;p&gt;I don’t agree with either of those conclusions.  But the reasoning behind this
objection requires a little bit of a detour. Please bear with me.&lt;/p&gt;

&lt;h3 id=&quot;literate-and-algorithmic-thinking&quot;&gt;Literate and Algorithmic Thinking&lt;/h3&gt;

&lt;p&gt;I’ve done studies on what undergraduate CS1 students know and think about CS
when they show up, day 1.  If you ask such students what it means to program on
day 1, in a majority of cases they have basically no idea. The popular vision of
programmers and hackers comes from movies like The Matrix, Hackers, and
Swordfish, or the “It’s a UNIX system” scene from Jurassic Park.  Programming is
like magic and the act of programming in popular culture has more to do with
portrayals of magic than opening up a text editor. A skilled programmer, like
Harry Potter as much as Neo, can do anything - and will probably be surrounded
by some impressive visual effects in the process.&lt;/p&gt;

&lt;p&gt;Then, we introduce them to “Hello World”.  Java gives me a great punching bag
here: “public static void main string bracket-bracket args, system dot out dot
println, quote Hello World”.  Yes, you can draw comparison between the
boilerplate necessary there with the incantations within magic, but if we are
being honest we turn off CS1 students from that very first program if we aren’t
careful.  “Don’t worry about all of this stuff” is not a great way to inspire
curiosity and a desire to learn. Boilerplate is the enemy for intro
programmers. For a day 1 use-case, I love Python. You must explain “Print
doesn’t mean to the printer, it just means to the screen. And quotes are just
like in prose - saying exactly this thing in quotes.”  For kick-starting some
simple demonstrations without boilerplate, that’s pretty hard to beat.  C++
falls somewhere between the two - if we stick to Hello World and iostreams, it’s
not too bad.  The well-travelled path is pretty narrow (explaining strings
vs. char*s, namespaces, ADL, operators, etc), but it’s certainly not as bad as
Java.&lt;/p&gt;

&lt;p&gt;Once we get past the first day, we need to start thinking about what it means to
become a programmer. By “programmer”, I don’t mean an expert in any given
language - most anyone that can call themselves a programmer knows that the
syntax and details in a specific language is a largely separable thing from the
effort to learn to be an algorithmic / programmatic thinker. That transition
into algorithmic thinking transcends any particular language. It’s a cognitive
shift, thinking in abstractions and control flow, more than learning the syntax
and edge cases for any particular language.&lt;/p&gt;

&lt;p&gt;For comparison, there’s a book called Orality and Literacy by Walter Ong that
goes into great detail on the differences between oral and literate people and
cultures, pointing out the significant cultural and cognitive shifts that happen
when you transition to a world that relies on the written word and the ability
to communicate ideas without being face to face.  I cannot prove it, but I
firmly and fundamentally believe that a shift of equal magnitude happens when
you transition from a literate mindset to an algorithmic one.&lt;/p&gt;

&lt;p&gt;Assuming that the magnitude of the shift to an algorithmic mindset comparable to
becoming literate, consider how hard is it to become literate. How much effort
do we put into making that transition easy, with cardboard books and whole
genres devoted to helping learners make that transition?  Why would we think
that shifting from literate to algorithmic is any less difficult?  Bringing this
back to C++: why would we assume that the right tool for a high-performance
super-professional domain can also satisfy an “easy reader” in the process of
becoming an algorithmic thinker? To me, and certainly to most people I know, C++
isn’t a kid-friendly Goodnight Moon - it’s more of a Finnegan’s Wake. Simply
put: developing an algorithmic mindset is hard on its own, even in a language
that is designed to hold your hand. C++ is not well-suited for being a starter
language - come to us when you’ve gotten over those first hurdles.&lt;/p&gt;

&lt;p&gt;Approaching it from another angle: according to
&lt;a href=&quot;http://wg21.link/P0939r0&quot;&gt;P0939&lt;/a&gt;, C++ cannot afford to be all things to all
people.  Hopefully nobody disagrees when I say that C++ is a language that
prioritizes efficiency and performance above pretty much everything else -
including user-friendliness, ease of use, etc.  Citing
&lt;a href=&quot;http://wg21.link/P0939r0&quot;&gt;P0939&lt;/a&gt; and &lt;a href=&quot;http://wg21.link/P0684r2&quot;&gt;P0684&lt;/a&gt; - one of
the few perspectives I expect everyone on the Committee to agree with is that
“C++ leaves no room for another language between itself and the hardware”, and
that you don’t pay for what you don’t use.  Protections against programmer error
can be costly, and are thus not a priority for C++.  That’s all perfectly fine,
so long as we keep that in mind and stay true to that philosophy. In many
respects this is what makes C++ the important language it is: when efficiency
counts, this is the language you go to. We will not make you pay for having your
hand held.&lt;/p&gt;

&lt;p&gt;If we know that we cannot be the one language for all tasks, and we know that we
are focused on performance above all else - why are we thinking that a Graphics
library to make it easy to visualize things for novices is a good fit?&lt;/p&gt;

&lt;p&gt;As an educator, I don’t buy it.&lt;/p&gt;

&lt;h3 id=&quot;what-makes-c-special&quot;&gt;What Makes C++ Special?&lt;/h3&gt;

&lt;p&gt;There’s a separate chain of reasoning that concerns me with Guy’s “Batteries
Included” approach. Some of this was presented in 
&lt;a href=&quot;https://hackernoon.com/a-cake-for-your-cherry-what-should-go-in-the-c-standard-library-804fcecccef8&quot;&gt;Corentin’s reply&lt;/a&gt;
to Guy’s article, but I’ve got a bit of a different approach and experience with
it.&lt;/p&gt;

&lt;p&gt;One of the other things that C++ has been good at, historically, is
stability. In many respects I think we take that too far - I regularly leave
standards meetings frustrated at our inability to fix mistakes, but I do also
see the value that stability provides the community.  At the committee level we
pay pretty close attention to what will break user code (well, at least
well-behaved user code, see &lt;a href=&quot;http://wg21.link/p0921r0&quot;&gt;P0921&lt;/a&gt;), up to and
including support for pre-compiled code depending on an ever-changing standard
library.  That is, we provide not just API (source level) compatibility over
time, we almost always provide ABI (binary level) compatibility. And that means
that a huge number of possible changes are infeasible: if it involves how a type
is represented in memory, it will not change for decades.&lt;/p&gt;

&lt;p&gt;My friend Matt Kulukundis 
&lt;a href=&quot;https://www.youtube.com/watch?v=ncHmEUmJZf4&quot;&gt;spoke at CPPCon&lt;/a&gt; about work that
Google has been doing on hashing - a huge amount of performance and memory
savings is available beyond what is provided by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map.&lt;/code&gt;  However,
the standard can never realize those savings: even a change to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::hash&lt;/code&gt; is
infeasible because we have to maintain binary compatibility with code compiled
years ago with a sub-par approach to hashing. The implementation for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::hash&lt;/code&gt;
as it stands leaves little room for important things like hash-flood mitigation.
As a community, we’re paying in both resources and safety because of our
addiction to binary compatibility.&lt;/p&gt;

&lt;p&gt;Even ignoring binary compatibility, the standard is very reticent to make
changes that might break existing code.  As an example (one of many, I assure
you), numerous proposals to resolve issues with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::function &lt;/code&gt;have circulated
in the past few years. One of my favorite gripes is that it is the only type
(AFAIK) in the standard library that is not thread-compatible: calls to const
methods from multiple threads can still cause race conditions. This
inconsistency is because the specification of the call operator is slightly
bogus: even when called in a const context, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::function&lt;/code&gt; is perfectly willing
to call non-const call operators, potentially mutating the contained
callable. This defect was pointed out years ago, and it was pointed out that the
only code that would be broken by fixing this would be code that is not thread
safe and likely buggy. The committee was unwilling to break existing code - even
at that early date.&lt;/p&gt;

&lt;p&gt;Given this demonstration of prioritizing efficiency and stability, why would
something as high-level and changeable as Graphics be a good fit for the
standard?  I often legitimately question whether hashed associative containers
are a good fit for C++, given the potential for advancement that we’ve seen in
the last few years.  Anything complex enough that research tasks on how to
optimize it are still ongoing should probably not be in the C++ standard. At
least, not until we figure out how to deal with change a little more
aggressively.&lt;/p&gt;

&lt;h3 id=&quot;dependency-management-not-standardization&quot;&gt;Dependency Management, not Standardization&lt;/h3&gt;

&lt;p&gt;The section of Guy’s “Batteries Included” piece that resonates with me is this:
it isn’t that the &lt;strong&gt;standard&lt;/strong&gt; has to provide these things, but that there needs
to be &lt;strong&gt;some&lt;/strong&gt; mechanism to readily distribute libraries and dependencies in the
C++ community.  It is far past time that we as a community find an answer that
is somewhere between “this is chaos” and “this is in the standard”.  This is
particularly hard in C++, where the preponderance of build flags, preprocessor
directives, build systems, compilers, standard library variants makes true
portability challenging (to say the least).  But I know it can be done.  It will
require library providers to be more clear about what compatibility they
promise, and library consumers to understand what they are asking, but it can be
done.&lt;/p&gt;

&lt;p&gt;So, what should go in the standard library?  Fundamentals. Things that can only
be done with compiler support, or compile-time things that are so subtle that
only the standard should be trusted to get it right. Vocabulary.  Time, vector,
string. Concurrency.  Mutex, future, executors.  The wide array of “sometimes
useful data structure” and “random metaprogramming” could and should be shuffled
off into a semi-standard repository of available but distinct utility libraries.
Those may themselves have different design and stability philosophies, like
Boost or Abseil - the principles that make the standard what it is are not
necessarily universal even if they are good for the standard.  Graphics is too
much - many won’t want it, and those that think they do may not understand what
they are asking for.&lt;/p&gt;

&lt;p&gt;Graphics won’t make C++ a teaching language - learning to be an algorithmic
thinker should be done in a language that has fewer sharp edges.  C++ won’t make
Graphics easy, and tying any sort of Graphics API to the legacy constraints of
C++ won’t make for a great API in that space. But using the Graphics API as a
high-value seed for a centralized repository of C++ dependencies … that would go
a long way toward solving some very real problems.&lt;/p&gt;
</description>
          <pubDate>2018-02-27T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/20180227-what-should-go-stdlib</link>
          <guid isPermaLink="true">https://abseil.io/blog/20180227-what-should-go-stdlib</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #93: using absl::Span</title>
          <description>&lt;p&gt;Originally posted as TotW #93 on April 23, 2015&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:sbenza@google.com&quot;&gt;Samuel Benzaquen&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2023-05-08&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/93&quot;&gt;abseil.io/tips/93&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At Google we are accustomed to using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; as function parameters and
return types when we want to deal with unowned strings. It can make the API more
flexible and it can improve performance by avoiding unneeded conversions to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;. (&lt;a href=&quot;/tips/1&quot;&gt;Tip #1&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; has a more generic cousin called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Span&lt;/code&gt;
(google3/third_party/absl/types/span.h). Note that though &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Span&lt;/code&gt; is
similar in utility to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::span&lt;/code&gt;, available in C++ 20, the two types are not
exchangeable.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&amp;lt;const T&amp;gt;&lt;/code&gt; is to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;T&amp;gt;&lt;/code&gt; what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; is to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;. It
provides a read-only interface to the elements of the vector, but it can also be
constructed from non-vector types (like arrays and initializer lists) without
incurring the cost of copying the elements.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; can be dropped, so where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&amp;lt;const T&amp;gt;&lt;/code&gt; is a view into an array
whose elements can’t be mutated, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt; allows non-const access to the
elements. Unlike spans of const, however, these require explicit construction.&lt;/p&gt;

&lt;h2 id=&quot;as-function-parameters&quot;&gt;As Function Parameters&lt;/h2&gt;

&lt;p&gt;Some of the benefits of using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&lt;/code&gt; as a function parameter are similar to
those of using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The caller can pass a slice of the original vector, or pass a plain array. It is
also compatible with other array-like containers, like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::InlinedVector&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::FixedArray&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;google::protobuf::RepeatedField&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;As with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;, it is usually better to pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&lt;/code&gt; by value when used as
a function parameter - this form is slightly faster, and produces smaller code.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void TakesVector(const std::vector&amp;lt;int&amp;gt;&amp;amp; ints);
void TakesSpan(absl::Span&amp;lt;const int&amp;gt; ints);

void PassOnlyFirst3Elements() {
  std::vector&amp;lt;int&amp;gt; ints = MakeInts();
  // We need to create a temporary vector, and incur an allocation and a copy.
  TakesVector(std::vector&amp;lt;int&amp;gt;(ints.begin(), ints.begin() + 3));
  // No copy or allocations are made when using Span.
  TakesSpan(absl::Span&amp;lt;const int&amp;gt;(ints.data(), 3));
}

void PassALiteral() {
  // This creates a temporary std::vector&amp;lt;int&amp;gt;.
  TakesVector({1, 2, 3});
  // Span does not need a temporary allocation and copy, so it is faster.
  TakesSpan({1, 2, 3});
}
void IHaveAnArray() {
  int values[10] = ...;
  // Once more, a temporary std::vector&amp;lt;int&amp;gt; is created.
  TakesVector(std::vector&amp;lt;int&amp;gt;(std::begin(values), std::end(values)));
  // Just pass the array. Span detects the size automatically.
  // No copy was made.
  TakesSpan(values);
}
&lt;/pre&gt;

&lt;h2 id=&quot;const-correctness-for-vector-of-pointers&quot;&gt;Const Correctness for Vector of Pointers&lt;/h2&gt;

&lt;p&gt;A big problem with passing around &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;T*&amp;gt;&lt;/code&gt; is that you can’t make the
pointees const without changing the type of the container.&lt;/p&gt;

&lt;p&gt;Any function taking a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::vector&amp;lt;T*&amp;gt;&amp;amp;&lt;/code&gt; will not be able to modify the
vector, but it can modify the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;s. This also applies to accessors that return a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::vector&amp;lt;T*&amp;gt;&amp;amp;&lt;/code&gt;. You can’t prevent the caller from modifying the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;Common “solutions” include copying or casting the vector into the right type.
These solutions are slow (for the copy) or undefined behavior (for the cast) and
should be avoided. Instead, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;example-function-parameter&quot;&gt;Example: Function Parameter&lt;/h3&gt;

&lt;p&gt;Consider these &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frob&lt;/code&gt; variants:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void FrobFastWeak(const std::vector&amp;lt;Foo*&amp;gt;&amp;amp; v);
void FrobSlowStrong(const std::vector&amp;lt;const Foo*&amp;gt;&amp;amp; v);
void FrobFastStrong(absl::Span&amp;lt;const Foo* const&amp;gt; v);
&lt;/pre&gt;

&lt;p&gt;Starting with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::vector&amp;lt;Foo*&amp;gt;&amp;amp; v&lt;/code&gt; that needs frobbing, you have two
imperfect options and one good one.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// fast and easy to type but not const-safe
FrobFastWeak(v);
// slow and noisy, but safe.
FrobSlowStrong(std::vector&amp;lt;const Foo*&amp;gt;(v.begin(), v.end()));
// fast, safe, and clear!
FrobFastStrong(v);
&lt;/pre&gt;

&lt;h3 id=&quot;example-accessor&quot;&gt;Example: Accessor&lt;/h3&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class MyClass {
 public:
  // This is supposed to be const.
  // Don’t modify my Foos, pretty please.
  const std::vector&amp;lt;Foo*&amp;gt;&amp;amp; shallow_foos() const { return foos_; }
  // Really deep const.
  absl::Span&amp;lt;const Foo* const&amp;gt; deep_foos() const { return foos_; }

 private:
  std::vector&amp;lt;Foo*&amp;gt; foos_;
};
void Caller(const MyClass* my_class) {
  // Accidental violation of MyClass::shallow_foos() contract.
  my_class-&amp;gt;shallow_foos()[0]-&amp;gt;SomeNonConstOp();
  // This one doesn&apos;t compile.
  // my_class-&amp;gt;deep_foos()[0]-&amp;gt;SomeNonConstOp();
}
&lt;/pre&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;When used appropriately, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Span&lt;/code&gt; can provide decoupling, const correctness
and a performance benefit.&lt;/p&gt;

&lt;p&gt;It is important to note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&lt;/code&gt; behaves much like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; by being a
reference to some externally owned data. All the same warnings apply. In
particular, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&lt;/code&gt; must not outlive the data it refers to.&lt;/p&gt;
</description>
          <pubDate>2018-02-22T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/93</link>
          <guid isPermaLink="true">https://abseil.io/tips/93</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #61: Default Member Initializers</title>
          <description>&lt;p&gt;Originally posted as Totw #61 on Nov 12, 2013&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Michael Chastain &lt;a href=&quot;mailto:mec.desktop@gmail.com&quot;&gt;(mec.desktop@gmail.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated October, 2016&lt;/p&gt;

&lt;h2 id=&quot;declaring-default-member-initialization&quot;&gt;Declaring Default Member Initialization&lt;/h2&gt;

&lt;p&gt;A default member initializer declares a default value for a member upon
construction and looks like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Client&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunks_in_flight_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This default initializer propagates into all constructors for that class, even
constructors that C++ synthesizes. Initializing members in this way is useful
for classes with lots of data members, especially for types such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;double&lt;/code&gt;, and raw pointers. Non-static data members of these fundamental
types often slip through the cracks and end up uninitialized. Non-static data
members of any type may have initializers, though.&lt;/p&gt;

&lt;p&gt;Default member initializers are also useful for declarations of simple structs
with no user-written constructor:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;use_loas&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_pii&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout_ms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout_backoff_ms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;member-initialization-overrides&quot;&gt;Member Initialization Overrides&lt;/h2&gt;

&lt;p&gt;If a class constructor initializes a data member that already has a default
initializer, the initializer in the constructor supersedes the default:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Frobber&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// length_ has a non-static class member initializer&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code is equivalent to the older code:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Frobber&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that the first and second &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frobber&lt;/code&gt; constructors have initializers for
their non-static variables; these two constructors will not use the default
initializer for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length_&lt;/code&gt;. The third &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frobber&lt;/code&gt; constructor, however, does
not have an initializer for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length_&lt;/code&gt; so this constructor will use the default
initializer for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length_&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As always in C++, all non-static variables are initialized in the order of their
declaration.&lt;/p&gt;

&lt;p&gt;In the first 2 of the 3 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frobber&lt;/code&gt; constructors, the constructor provides an
initializer for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length_&lt;/code&gt;. The constructor initializer supersedes the default
member initializer – the non-static class member initializer does not
contribute to code generation for these constructors.&lt;/p&gt;

&lt;p&gt;Note: Older documentation may refer to default member initializers as non-static
data member initializers, abbreviated to NSDMIs.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Default member initializers won’t make your program any faster. They will help
reduce bugs from omissions, especially when someone adds a new constructor or a
new data member.&lt;/p&gt;

&lt;p&gt;Be careful not to confuse a non-static class member initializer with a static
class member initializer:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Alpha&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counter_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is an older feature. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;counter_&lt;/code&gt; is static and this is a static declaration
with an initializer. This is different from a non-static class member
initializer, just as static member variables are different from non-static
member variables.&lt;/p&gt;
</description>
          <pubDate>2018-02-22T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/61</link>
          <guid isPermaLink="true">https://abseil.io/tips/61</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #134: &lt;code&gt;make_unique&lt;/code&gt; and &lt;code&gt;private&lt;/code&gt; Constructors.</title>
          <description>&lt;p&gt;Originally posted as TotW #134 on May 10, 2017&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Yitzhak Mandelbaum, Google Engineer&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/134&quot;&gt;abseil.io/tips/134&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, you read &lt;a href=&quot;/tips/126&quot;&gt;Tip #126&lt;/a&gt; and are ready to leave &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt; behind.
Everything’s going fine until you try to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&lt;/code&gt; to construct an
object with a private constructor, and it fails to compile. Let’s take a look at
a concrete example of this problem to understand what went wrong. Then, we can
discuss some solutions.&lt;/p&gt;

&lt;h2 id=&quot;example-manufacturing-widgets&quot;&gt;Example: Manufacturing Widgets&lt;/h2&gt;

&lt;p&gt;You’re defining a class to represent widgets. Each widget has an identifier and
those identifiers are subject to certain constraints. To ensure those
constraints are always met, you declare the constructor of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget&lt;/code&gt; class
private and provide users with a factory function, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Make&lt;/code&gt;, for generating
widgets with proper identifiers. (See &lt;a href=&quot;/tips/42&quot;&gt;Tip #42&lt;/a&gt; for advice on why
factory functions are preferable to initializer methods.)&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
class Widget {
 public:
  static std::unique_ptr&amp;lt;Widget&amp;gt; Make() {
    return std::make_unique&amp;lt;Widget&amp;gt;(GenerateId());
  }

 private:
  Widget(int id) : id_(id) {}
  static int GenerateId();

  int id_;
}
&lt;/pre&gt;

&lt;p&gt;When you try to compile, you get an error like this:&lt;/p&gt;

&lt;pre class=&quot;prettyprint code&quot;&gt;
error: calling a private constructor of class &apos;Widget&apos;
    { return unique_ptr&amp;lt;_Tp&amp;gt;(new _Tp(std::forward&amp;lt;_Args&amp;gt;(__args)...)); }
                                 ^
note: in instantiation of function template specialization
&apos;std::make_unique&amp;lt;Widget, int&amp;gt;&apos; requested here
    return std::make_unique&amp;lt;Widget&amp;gt;(GenerateId());
                ^
note: declared private here
  Widget(int id) : id_(id) {}
  ^
&lt;/pre&gt;

&lt;p&gt;While &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Make&lt;/code&gt; has access to the private constructor, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&lt;/code&gt; does not!
Note that this issue can also arise with friends. For example, a friend of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget&lt;/code&gt; would have the same problem using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&lt;/code&gt; to construct a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;p&gt;We recommend either of these alternatives:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique&lt;/code&gt;, but explain your choice. For example,&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
    // Using `new` to access a non-public constructor.
    return absl::WrapUnique(new Widget(...));
&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;Consider whether the constructor may be safely exposed publicly. If so, make
it public and document when direct construction is appropriate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In many cases, marking a constructor private is over-engineering. In those
cases, the best solution is to mark your constructors public and document their
proper use. However, if your constructor needs to be private (say, to ensure
class invariants), then use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WrapUnique&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;why-cant-i-just-friend-stdmake_unique-or-abslmake_unique&quot;&gt;Why Can’t I Just Friend &lt;code&gt;std::make_unique&lt;/code&gt; (or &lt;code&gt;absl::make_unique&lt;/code&gt;)?&lt;/h2&gt;

&lt;p&gt;You might be tempted to friend &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&lt;/code&gt; (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique&lt;/code&gt;),
which would give it access to your private constructors. &lt;em&gt;This is a bad idea&lt;/em&gt;,
for a few reasons.&lt;/p&gt;

&lt;p&gt;First, while a full discussion of friending practices is beyond the scope of
this tip, a good rule of thumb is “no long-distance friendships”. Otherwise,
you’re creating a competing declaration of the friend, one not maintained by the
owner. See also the
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Friends&quot;&gt;style guide’s advice&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Second, notice that you are depending on an implementation detail of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make_unique&lt;/code&gt;, namely that it directly calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt;. If it is refactored so that
it indirectly calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt; – for example, in build modes using C++14 and later
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique&lt;/code&gt; is an alias for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&lt;/code&gt;, and the friend
declaration is useless.&lt;/p&gt;

&lt;p&gt;Finally, by friending &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make_unique&lt;/code&gt;, you’ve allowed &lt;em&gt;anyone&lt;/em&gt; to create your
objects that way, so why not just declare your constructors public and avoid the
problem altogether?&lt;/p&gt;

&lt;h2 id=&quot;what-about-stdshared_ptr&quot;&gt;What About &lt;code&gt;std::shared_ptr&lt;/code&gt;?&lt;/h2&gt;

&lt;p&gt;The situation is somewhat different in the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::shared_ptr&lt;/code&gt;. There is
no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapShared&lt;/code&gt; and the analog – &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::shared_ptr&amp;lt;T&amp;gt;(new T(...))&lt;/code&gt; –
involves two allocations, where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_shared&lt;/code&gt; can be done with one. If this
difference is important, then consider the &lt;em&gt;passkey idiom&lt;/em&gt;: have the constructor
take a special token that only certain code can create. For example,&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
class Widget {
  class Token {
   private:
    explicit Token() = default;
    friend Widget;
  };

 public:
  static std::shared_ptr&amp;lt;Widget&amp;gt; Make() {
    return std::make_shared&amp;lt;Widget&amp;gt;(Token{}, GenerateId());
  }

  Widget(Token, int id) : id_(id) {}

 private:
  static int GenerateId();

  int id_;
};
&lt;/pre&gt;

&lt;p&gt;Note that we are providing an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; defaulted constructor. This is needed
for C++17 and earlier, as otherwise &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Widget::Token&lt;/code&gt; would be an aggregate and
could be aggregate-initialized by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{}&lt;/code&gt;, effectively bypassing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt;
access.&lt;/p&gt;

&lt;p&gt;For a full discussion of the passkey idiom, consult either of these articles:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://arne-mertz.de/2016/10/passkey-idiom/&quot;&gt;Passkey Idiom: More Useful Empty Classes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.spiria.com/en/blog/desktop-software/passkey-idiom-and-better-friendship-c&quot;&gt;Passkey Idiom and Better Friendship in C++&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
          <pubDate>2018-02-22T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/134</link>
          <guid isPermaLink="true">https://abseil.io/tips/134</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #88: Initialization: =, (), and {}</title>
          <description>&lt;p&gt;Originally posted as TotW #88 on Jan 27, 2015&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Titus Winters &lt;a href=&quot;mailto:titus@google.com&quot;&gt;(titus@google.com)&lt;/a&gt;, on behalf of
the Google C++ Style Arbiters&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;C++11 provided a new syntax referred to as “uniform initialization syntax” that
was supposed to unify all of the various styles of initialization, avoid the
&lt;a href=&quot;http://en.wikipedia.org/wiki/Most_vexing_parse&quot;&gt;Most Vexing Parse&lt;/a&gt;, and avoid
narrowing conversions. This new mechanism means we now have
&lt;a href=&quot;https://xkcd.com/927/&quot;&gt;yet another&lt;/a&gt; syntax for initialization, with its own
tradeoffs.&lt;/p&gt;

&lt;h2 id=&quot;c11-brace-initialization&quot;&gt;C++11 Brace Initialization&lt;/h2&gt;

&lt;p&gt;Some uniform initialization syntax proponents would suggest that we use {}s and
direct initialization (no use of the ‘=’, although in most cases both forms call
the same constructor) for initialization of all types:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;vs. (for instance):&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This approach has two shortcomings. First, “uniform” is a stretch: there are
cases where ambiguity still exists (for the casual reader, not the compiler) in
what is being called and how.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// A vector of two empty strings.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;// A vector containing only the integer 2.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Second: this syntax is not exactly intuitive: no other common language uses
something like it. The language can certainly introduce new and surprising
syntax, and there are technical reasons why it’s necessary in some cases –
especially in generic code. The important question is: how much should we
change our habits and language understanding to take advantage of that
change? Are the benefits worth the cost in changing our habits or our existing
code? For uniform initialization syntax, we don’t believe in general that the
benefits outweigh the drawbacks.&lt;/p&gt;

&lt;h2 id=&quot;best-practices-for-initialization&quot;&gt;Best Practices for Initialization&lt;/h2&gt;

&lt;p&gt;Instead, we recommend the following guidelines for “How do I initialize a
variable?”, both to follow in your own code and to cite in your code reviews:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Use assignment syntax when initializing directly with the intended literal
value (for example: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;float&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; values), with smart
pointers such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::shared_ptr&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;, with containers
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::map&lt;/code&gt;, etc), when performing struct initialization, or
doing copy construction.&lt;/strong&gt;&lt;/p&gt;

    &lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Matrix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matrix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NewMatrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MyProto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copied_proto&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;original_proto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;instead of:&lt;/p&gt;

    &lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Bad code&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Matrix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NewMatrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MyProto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copied_proto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;original_proto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Use the traditional constructor syntax (with parentheses) when the
initialization is performing some active logic, rather than simply composing
values together.&lt;/strong&gt;&lt;/p&gt;

    &lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bazzer_to_duplicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fifty_pies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;vs.&lt;/p&gt;

    &lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Bad code&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Could invoke an initializer list constructor, or a two-argument constructor.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bazzer_to_duplicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Makes a vector of two doubles.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fifty_pies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Use {} initialization without the = only if the above options don’t
compile:&lt;/strong&gt;&lt;/p&gt;

    &lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;array_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;array_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Requires {}s because the constructor is marked explicit&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// and the type is non-copyable.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;EventManager&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;em&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EventManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Never mix {}s and auto.&lt;/strong&gt;&lt;br /&gt;
For example, don’t do this:&lt;/p&gt;

    &lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Bad code&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// This is a std::initializer_list&amp;lt;int&amp;gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;(For the language lawyers: prefer copy-initialization over
direct-initialization when available, and use parentheses over curly braces
when resorting to direct-initialization.)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perhaps the best overall description of the issue is Herb Sutter’s
&lt;a href=&quot;http://herbsutter.com/2013/05/09/gotw-1-solution/&quot;&gt;GotW post&lt;/a&gt;. Although he
shows examples that include direct initialization of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; with braces, his
final advice is roughly compatible with what we present here with one caveat:
where Herb says “where you prefer to see only the = sign”, we unambiguously
prefer to see exactly that. In conjunction with more consistent use of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; on multi-parameter constructors (see &lt;a href=&quot;/tips/142&quot;&gt;Tip #142&lt;/a&gt;),
this provides a balance between readability, explicitness, and correctness.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The tradeoffs for uniform initialization syntax are not generally worth it: our
compilers already warn against the Most Vexing Parse (you can use brace
initialization or add parens to resolve the issue), and the safety from
narrowing conversions isn’t worth the readability hit for brace-initialization
(we’ll need a different solution for narrowing conversions, eventually). The
Style Arbiters don’t think this issue is critical enough to make a formal rule
on, especially because there are cases (notably in generic code) where brace
initialization may be justified.&lt;/p&gt;

</description>
          <pubDate>2018-02-15T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/88</link>
          <guid isPermaLink="true">https://abseil.io/tips/88</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #142: Multi-parameter Constructors and &lt;code&gt;explicit&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #142 on January 29, 2018&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;James Dennett&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/142&quot;&gt;abseil.io/tips/142&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“Explicit is better than implicit.” –
&lt;a href=&quot;https://www.python.org/dev/peps/pep-0020/&quot;&gt;PEP 20&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR:&lt;/h2&gt;

&lt;p&gt;Most constructors should be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Prior to C++11, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; keyword was meaningful only for constructors that
could be called with a single argument, and our style guide required its use for
such constructors so that they did not act as “converting constructors”. That
requirement was not applied for multi-parameter constructors. Indeed the style
guide used to discourage use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; for multi-parameter constructors as
it had no meaning. That’s no longer the case.&lt;/p&gt;

&lt;p&gt;In C++11, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; became meaningful for copy-initialization from braced
lists, such as when calling a function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void f(std::pair&amp;lt;int, int&amp;gt;)&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f({1,
2})&lt;/code&gt; or when initializing a variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bad&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;char&amp;gt; bad =
{&quot;hello&quot;, &quot;world&quot;};&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Wait a minute! In that last example the types don’t match. That can’t compile,
can it? &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;std::string&amp;gt; good = {&quot;hello&quot;, &quot;world&quot;};&lt;/code&gt; would be
reasonable, but a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;char&amp;gt;&lt;/code&gt; can’t hold two &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;s. And yet it
does compile (or at least it does with all current C++ compilers). What’s up
with that? Let’s come back to that later, after we’ve talked more about
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;constructors-that-change-types-but-not-values&quot;&gt;Constructors That Change Types, But Not Values&lt;/h2&gt;

&lt;p&gt;Constructors that aren’t marked as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; can be invoked by the compiler to
create a value without mentioning the type’s name. That’s great when we have the
value we want already but the types just don’t quite match – we have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
char[]&lt;/code&gt; and we need a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;, maybe, or we have two &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;s and we
want a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;std::string&amp;gt;&lt;/code&gt;, or we have an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; and we want a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BigNum&lt;/code&gt;.
In short, it works well if the value is essentially the same before and after
the conversion.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// The coordinates of a point in the Cartesian plane, w.r.t. some basis.
class Coordinate2D {
 public:
  Coordinate2D(double x, double y);
  // ...
};

// Computes the Euclidean norm of a given point `p`.
double EuclideanNorm(Coordinate2D p);

// Uses of the non-explicit constructor:
double norm = EuclideanNorm({3.0, 4.0});  // passing a function argument
Coordinate2D origin = {0.0, 0.0};         // initializing with `=`
Coordinate2D Translate(Coordinate2D p, Vector2D v) {
  return {p.x() + v.x(), p.y() + v.y()};  // returning a value from a function
}
&lt;/pre&gt;

&lt;p&gt;By declaring the constructor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Coordinate2D(double, double)&lt;/code&gt; without &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;
we allow for passing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{3.0, 4.0}&lt;/code&gt; to a function that takes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Coordinate2D&lt;/code&gt;
parameter. Given that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{3.0, 4.0}&lt;/code&gt; is a perfectly reasonable value for such an
object, no confusion arises from this affordance.&lt;/p&gt;

&lt;h2 id=&quot;constructors-that-do-more&quot;&gt;Constructors That Do More&lt;/h2&gt;

&lt;p&gt;Implicitly calling a constructor isn’t such a good idea if its output is a
different value than its input, or if it might have preconditions.&lt;/p&gt;

&lt;p&gt;Consider a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Request&lt;/code&gt; class with a constructor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Request(Server*, Connection*)&lt;/code&gt;.
There’s no sense in which the value of the request object “is” the server and
connection — it’s just that we can create a request that uses them. There could
be many semantically different types that can be constructed from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{server,
connection}&lt;/code&gt;, such as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Response&lt;/code&gt;. Such a constructor should be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;, so
that we can’t pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{server, connection}&lt;/code&gt; to a function that accepts a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Request&lt;/code&gt;
(or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Response&lt;/code&gt;) parameter. In such cases marking the constructor as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;
makes the code clearer for readers by requiring the target type to be named when
it’s instantiated and helps to avoid bugs caused by unintended conversions.&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// A line is defined by two distinct points.
class Line {
 public:
  // Constructs the line passing through the given points.
  // REQUIRES: p1 != p2
  explicit Line(Coordinate2D p1, Coordinate2D p2);

  // Determines whether this line contain a given point `p`.
  bool ContainsPoint(Coordinate2D p) const;
};

Line line({0, 0}, {42, 1729});

// Computes the gradient of `line`.  Returns an infinite value if `line` is
// vertical.
double Gradient(const Line&amp;amp; line);
&lt;/pre&gt;

&lt;p&gt;By declaring the constructor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Line(Coordinate2D, Coordinate2D)&lt;/code&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;,
we prevent code from passing unrelated points to Gradient without first
deliberately turning them into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Line&lt;/code&gt; object. The “value” of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Line&lt;/code&gt; isn’t
the two points, and not any two points define a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Line&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As another example, the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; for ownership transfer from a raw
pointer in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; prevents a double-&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delete&lt;/code&gt; bug here:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
std::vector&amp;lt;std::unique_ptr&amp;lt;int&amp;gt;&amp;gt; v;
int* p = new int(-1);
v.push_back(p);  // error: cannot convert int* to std::unique_ptr&amp;lt;int&amp;gt;
// ...
v.push_back(p);
&lt;/pre&gt;

&lt;p&gt;To pass a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; the programmer must explicitly create one, which
leaves a visual clue for readers that ownership is being transferred. The
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; constructor helps to document the constraint that the raw pointer
must own its target.&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Copy constructors and move constructors should never be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Make a constructor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; unless its arguments “are” the value of the
newly created object. (Note:
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Implicit_Conversions&quot;&gt;the Google style guide&lt;/a&gt;
currently requires all single-argument constructors to be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;In particular, constructors for types where identity (address) is relevant
to the value should be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Constructors that impose additional constraints on values (i.e., that have
preconditions) should be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;. Sometimes those are better implemented
as factory functions (see
&lt;a href=&quot;/tips/42&quot;&gt;Tip #42: Prefer Factory Functions to Initializer Methods&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;closing-remarks&quot;&gt;Closing Remarks&lt;/h2&gt;

&lt;p&gt;This tip can be viewed as the flip-side of
&lt;a href=&quot;/tips/88#best-practices-for-initialization&quot;&gt;Tip #88: Initialization: =, (), and {}&lt;/a&gt;,
which advises us to use copy-initialization syntax (with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&lt;/code&gt;) when initializing
from “the intended literal value”. The advice of the present tip is to omit
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; only when tip 88 says to use copy initialization (which would
otherwise be disallowed by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; keyword).&lt;/p&gt;

&lt;p&gt;Finally, a word of warning: The C++ Standard Library doesn’t always get this
right. Going back to our example (that mistakenly declared a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;char&amp;gt;&lt;/code&gt;
rather than a container of strings):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
std::vector&amp;lt;char&amp;gt; bad = {&quot;hello&quot;, &quot;world&quot;};
&lt;/pre&gt;

&lt;p&gt;we find that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; has a templated “range” constructor taking a pair of
iterators, which matches here and deduces the parameter types as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt;.
If the recommendations in this tip were applied, that constructor would be
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt;, because the value of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;char&amp;gt;&lt;/code&gt; is not two iterators
(rather, it’s a sequence of characters). As it is, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit&lt;/code&gt; was omitted, and
this example code gives undefined behavior as the second iterator is not
reachable from the first.&lt;/p&gt;
</description>
          <pubDate>2018-02-15T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/142</link>
          <guid isPermaLink="true">https://abseil.io/tips/142</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #59: Joining Tuples</title>
          <description>&lt;p&gt;Originally published as totw/59 on 2013-10-21&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Greg Miller &lt;a href=&quot;mailto:jgm@google.com&quot;&gt;(jgm@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2018-01-24&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Now join your hands, and with your hands your hearts.” –Henry VI, William
Shakespeare&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In March, 2013 we announced the new &lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_join.h&quot;&gt;string joining
API&lt;/a&gt; in &lt;a href=&quot;/tips/36&quot;&gt;Tip #36&lt;/a&gt;. The response to the new API was quite
positive, and we worked to make the API even better. Topping the list of
feature requests was the ability to join arbitrary lists of possibly
heterogeneous data (I can only assume that Shakespeare was referring to
joining a heterogeneous collection of hands and hearts). We didn’t go with
the varargs or variadic template route, but we did add support for joining
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::tuple&lt;/code&gt; objects, which addresses this need quite nicely. Simply create
a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::tuple&lt;/code&gt; containing your heterogeneous data, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrJoin()&lt;/code&gt;
will accept it just like any other container. Here are a few examples:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tup&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Works, but copies all arguments.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// No copies, but only works with lvalues.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// No copies, and works with lvalues and rvalues.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward_as_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MakeFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As with joining any container, the elements of the tuple are formatted using an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::AlphaNumFormatter&lt;/code&gt; by default, but you can specify a custom
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_join.h#L64&quot;&gt;join Formatter&lt;/a&gt; if your tuple contains elements that are not
handled by the default formatter. To format a tuple with multiple custom
element types, your custom &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Formatter&lt;/code&gt; object may contain multiple overloads
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFormatter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Bar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward_as_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                         &lt;span class=&quot;n&quot;&gt;MyFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EXPECT_EQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Foo-Bar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The goal of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrJoin()&lt;/code&gt; API is to join any collection, range, list, or
group of data using an intuitive and consistent syntax. We think joining
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::tuple&lt;/code&gt; objects fits nicely with this goal and adds more flexibility to the
API.&lt;/p&gt;

</description>
          <pubDate>2018-01-25T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/59</link>
          <guid isPermaLink="true">https://abseil.io/tips/59</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #36: New Join API</title>
          <description>&lt;p&gt;Originally published as totw/36 on 2013-03-21&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Greg Miller &lt;a href=&quot;mailto:jgm@google.com&quot;&gt;(jgm@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2018-01-24&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“I got a good mind to join a club and beat you over the head with it.” –
Groucho Marx&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Many of you asked for a new joining API and we heard you. We now have one
joining function to replace them all, and it is spelled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrJoin()&lt;/code&gt;.
You simply give it a collection of objects to be joined and a separator
 string, and it does the rest. It will work with collections of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;double&lt;/code&gt; – any type that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt;
supports. If you need to join a type that will not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrCat()&lt;/code&gt;, you can
also provide a custom &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Formatter&lt;/code&gt; for that type; we’ll see below how the
use of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Formatter&lt;/code&gt; will let us nicely join a map.&lt;/p&gt;

&lt;p&gt;Now for some quick examples:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// s == &quot;a-b-c&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// s == &quot;a-b-c&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// s == &quot;1-2-3&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// s == &quot;1-2-3&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The following example passes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Formatter&lt;/code&gt; argument to format the pairs in a
map, using a different separator. This makes the output nice and readable.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PairFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// s == &quot;a=1;b=2;c=3&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also pass a C++ lambda expression as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Formatter&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetFoos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrJoin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrAppend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Please refer to &lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_join.h&quot;&gt;absl/strings/str_join.h&lt;/a&gt; for more details.&lt;/p&gt;

</description>
          <pubDate>2018-01-25T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/36</link>
          <guid isPermaLink="true">https://abseil.io/tips/36</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #3: String Concatenation and operator+ vs. StrCat()</title>
          <description>&lt;p&gt;Originally published as totw/3 on 2012-05-11&lt;/p&gt;

&lt;p&gt;Updated 2017-09-18; revised 2018-01-22&lt;/p&gt;

&lt;p&gt;Users are often surprised when a reviewer says, “Don’t use the string
concatenation operator, it’s not that efficient.” How can it be that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string::operator+&lt;/code&gt; is inefficient? Isn’t it hard to get that wrong?&lt;/p&gt;

&lt;p&gt;It turns out, such inefficiency isn’t clear cut. These two snippets have
close to the same execution time, in practice:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foobar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foobar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrCat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, the same is not true for these two snippets:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baz&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foobar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baz&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LongString3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foobar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrCat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The reason these two cases differ can be understood when we pick apart what is
happening in the expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo + bar + baz&lt;/code&gt;. Since there are no overloads for
three-argument operators in C++, this operation is necessarily going to make two
calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string::operator+&lt;/code&gt;. And between those two calls, the operation will
construct (and store) a temporary string. So
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string foobar = foo + bar + baz&lt;/code&gt; is really equivalent to:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foobar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Specifically, note that the contents of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar&lt;/code&gt; must be copied to a
temporary location before they are placed within &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foobar&lt;/code&gt;. (For more on
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move&lt;/code&gt;, see
&lt;a href=&quot;/tips/77&quot;&gt;Tip of the Week #77: Temporaries, moves, and copies&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;C++11 at least allows the second concatenation to happen without creating a new
string object: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move(temp) + baz&lt;/code&gt; is equivalent to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move(temp.append(baz))&lt;/code&gt;. However, it’s possible that the buffer initially
allocated for the temporary won’t be large enough to hold the final string, in
which case a reallocation (and another copy) will be required. As a result, in
the worst case, chains of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt; string concatenations require &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O(n)&lt;/code&gt; reallocations.&lt;/p&gt;

&lt;p&gt;It is better instead to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt;, a nice helper function from
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_cat.h&quot;&gt;absl/strings/str_cat.h&lt;/a&gt; that calculates the necessary string
length, reserves that size, and concatenates all of the input data into the
output - a well-optimized &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O(n)&lt;/code&gt;. Similarly, for cases like:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;foobar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrAppend()&lt;/code&gt;, which performs similar optimizations:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrAppend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foobar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As well, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrAppend()&lt;/code&gt; operate on types other than
just string types: you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrAppend&lt;/code&gt; to convert
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int32_t&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint32_t&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64_t&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint64_t&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;float&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;double&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt;, and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;, like this:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrCat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;The year is &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
          <pubDate>2018-01-25T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/3</link>
          <guid isPermaLink="true">https://abseil.io/tips/3</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #10: Splitting Strings, not Hairs</title>
          <description>&lt;p&gt;Originally published as totw/10 on 2012-08-16&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Greg Miller &lt;a href=&quot;mailto:jgm@google.com&quot;&gt;(jgm@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2018-01-24&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I tend to have an odd split in my mind. –John Cleese&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Splitting a string into substrings is a common task in any general-purpose
programming language, and C++ is no exception. When the need arose at Google,
many engineers found themselves wading through a morass of splitting functions
in organically grown header files. You’d have hunted for the magical combination
of input parameters, output parameters, and semantics that satisfies your need.
After studying 50+ functions in a 600+ line header, you may have finally decided
on something as tortuously named as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SplitStringViewToDequeOfStringAllowEmpty()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To address this, the C++ Library Team implemented a new API for splitting
strings, available for use in
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_split.h&quot;&gt;absl/strings/str_split.h&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The new API replaced many of these splitting functions with a
single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrSplit()&lt;/code&gt; function. This function takes an input string to be
split and a delimiter on which to split the string as arguments.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrSplit()&lt;/code&gt; adapts the returned collection to the type specified by the
caller. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrSplit()&lt;/code&gt;’s implementation is efficient because
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt;s are used internally; no copies are made unless the caller
explicitly requests to store the results in a collection of string objects
(which copy their data).&lt;/p&gt;

&lt;p&gt;Enough talk, let’s see some examples:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// Splits on commas. Stores in vector of string_view (no copies).
std::vector&amp;lt;absl::string_view&amp;gt; v = absl::StrSplit(&quot;a,b,c&quot;, &apos;,&apos;);

// Splits on commas. Stores in vector of string (data copied once).
std::vector&amp;lt;std::string&amp;gt; v = absl::StrSplit(&quot;a,b,c&quot;, &apos;,&apos;);

// Splits on literal string &quot;=&amp;gt;&quot; (not either of &quot;=&quot; or &quot;&amp;gt;&quot;)
std::vector&amp;lt;absl::string_view&amp;gt; v = absl::StrSplit(&quot;a=&amp;gt;b=&amp;gt;c&quot;, &quot;=&amp;gt;&quot;);

// Splits on any of the given characters (&apos;,&apos; or &apos;;&apos;)
using absl::ByAnyChar;
std::vector&amp;lt;std::string&amp;gt; v = absl::StrSplit(&quot;a,b;c&quot;, ByAnyChar(&quot;,;&quot;));

// Stores in various containers (also works w/ absl::string_view)
std::set&amp;lt;std::string&amp;gt; s = absl::StrSplit(&quot;a,b,c&quot;, &apos;,&apos;);
std::multiset&amp;lt;std::string&amp;gt; s = absl::StrSplit(&quot;a,b,c&quot;, &apos;,&apos;);
std::list&amp;lt;std::string&amp;gt; li = absl::StrSplit(&quot;a,b,c&quot;, &apos;,&apos;);

// Equiv. to the mythical SplitStringViewToDequeOfStringAllowEmpty()
std::deque&amp;lt;std::string&amp;gt; d = absl::StrSplit(&quot;a,b,c&quot;, &apos;,&apos;);

// Yields &quot;a&quot;-&amp;gt;&quot;1&quot;, &quot;b&quot;-&amp;gt;&quot;2&quot;, &quot;c&quot;-&amp;gt;&quot;3&quot;
std::map&amp;lt;std::string, std::string&amp;gt; m = absl::StrSplit(&quot;a,1,b,2,c,3&quot;, &apos;,&apos;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For more information, take a look at
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_split.h&quot;&gt;absl/strings/str_split.h&lt;/a&gt; for details about how to use
the Split API and &lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_split_test.cc&quot;&gt;absl/strings/str_split_test.cc&lt;/a&gt;
for some more examples.&lt;/p&gt;

&lt;p&gt;Thanks for reading. Now I really gotta split…&lt;/p&gt;

</description>
          <pubDate>2018-01-25T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/10</link>
          <guid isPermaLink="true">https://abseil.io/tips/10</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #74: Delegating and Inheriting Constructors</title>
          <description>&lt;p&gt;Originally posted as totw/74 on 2014-04-21&lt;/p&gt;

&lt;p&gt;By Bradley White &lt;a href=&quot;mailto:bww@google.com&quot;&gt;(bww@google.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Delegating work works, provided the one delegating works, too.” – Robert
Half&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When a class has multiple constructors there is often a need to perform similar
initialization in each variant. To avoid code duplication, many older
classes resort to defining a private &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SharedInit()&lt;/code&gt; method that is called from
the constructors. For example:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SharedInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;explicit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SharedInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;explicit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SharedInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SharedInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SharedInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;C++11 provides a new mechanism, delegating constructors, for dealing with such
situations more clearly by allowing one constructor to be defined in terms of
another. It is also an efficiency gain if the class has members that are
expensive to default-initialize.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;explicit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;explicit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that if you delegate to another constructor you cannot also use a member
initialization list – all initialization is done by the delegated constructor.
Don’t go overboard though. If all the shared code does is set members, separate
member-initialization lists or in-class initializers are probably clearer than
using delegating constructors. Use good judgement.&lt;/p&gt;

&lt;p class=&quot;note&quot;&gt;
Aside: an object is not considered complete until the delegating constructor
returns; in practice, this only matters if the constructors can throw, as they
leave the delegated-from objects in an incomplete state.
&lt;/p&gt;

&lt;p&gt;Another, less common form of constructor code duplication occurs when extending
the behavior of a multi-constructor class through a wrapper. For example,
consider a “veneer” subclass of C that just adds a new member function.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NewMethod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But what of the constructors for D? We’d like to simply re-use those from C
rather than writing out all the forwarding boilerplate, and C++11 allows for
this via the new &lt;em&gt;inheriting constructors&lt;/em&gt; mechanism.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// inherit all constructors from C&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NewMethod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This new form of “using” for constructors matches its previous use for
member functions.&lt;/p&gt;

&lt;p&gt;Note, however, that constructors should really only be inherited when the
derived class does not add new data members that need to be initialized
explicitly. Indeed, the style guide cautions against inheriting constructors
unless the new members (if any) have in-class initialization.&lt;/p&gt;

&lt;p&gt;So, go ahead and use C++11’s delegating and inheriting constructors when they
reduce duplication, eliminate forwarding boilerplate, or otherwise make your
classes simpler and clearer.&lt;/p&gt;
</description>
          <pubDate>2017-12-21T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/74</link>
          <guid isPermaLink="true">https://abseil.io/tips/74</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #42: Prefer Factory Functions to Initializer Methods</title>
          <description>&lt;p&gt;Originally posted as totw/42 on 2013-05-10&lt;/p&gt;

&lt;p&gt;By Geoffrey Romer &lt;a href=&quot;mailto:gromer@google.com&quot;&gt;(gromer@google.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Revised 2017-12-21&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“The man who builds a factory builds a temple; the man who works there worships
there, and to each is due, not scorn and blame, but reverence and praise.” –
Calvin Coolidge&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In environments where exceptions are disallowed (such as within Google), C++
constructors effectively must succeed, because they have no way to report
failure to the caller. You can use an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;abort()&lt;/code&gt;, of course, but doing so
crashes the whole program, which is often unacceptable in production code.&lt;/p&gt;

&lt;p&gt;If your class’s initialization logic can’t avoid the possibility of failure, one
common approach is to give the class an initializer method (also called an “init
method”), which performs any initialization work that might fail, and signals
that failure via its return value. The assumption is usually that the user will
call this method immediately after construction, and if it fails the user will
immediately destroy the object. However, these assumptions are not always
documented, nor always obeyed. It’s all too easy for users to start calling
other methods before initialization, or after initialization has failed.
Sometimes the class actually encourages this behavior, e.g. by providing methods
to configure the object before initializing it, or to read errors out of it
after initialization fails.&lt;/p&gt;

&lt;p&gt;This design commits you to maintaining a class with at least two distinct
user-visible states, and often three: initialized, uninitialized, and
initialization-failed. Making such a design work requires a lot of discipline:
every method of the class has to specify what states it can be called in, and
users have to comply with these rules. If this discipline lapses, client
developers will tend to write whatever code happens to work, regardless of
what you intended to support. When that starts to happen, maintainability
nosedives, because your implementation has to support whatever combinations of
pre-initialization method calls your clients have started to depend on. In
effect, your implementation has become your interface. (See
&lt;a href=&quot;https://www.hyrumslaw.com&quot;&gt;Hyrum’s Law&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;Fortunately, there’s a simple alternative that lacks these drawbacks: provide a
&lt;em&gt;factory function&lt;/em&gt; which creates and initializes instances of your class, and
returns them by pointer or as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt; (see &lt;a href=&quot;123&quot;&gt;TotW #123&lt;/a&gt;),
using null to indicate failure. Here’s a toy example using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unique_ptr&amp;lt;&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// foo.h&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Factory method: creates and returns a Foo.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// May return null on failure.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Foo is not copyable.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Clients can&apos;t invoke the constructor directly.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// foo.c&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Note that since Foo&apos;s constructor is private, we have to use new.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WrapUnique&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In many cases, this pattern gives you the best of both worlds: the factory
function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo::Create()&lt;/code&gt; exposes only fully-initialized objects like a
constructor, but it can indicate failure like an initializer method. Another
advantage of factory functions is that they can return instances of any subclass
of the return type (though this is not possible if using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt; as
the return type). This allows you to swap in a different implementation
without updating user code, or even choose the implementation class dynamically,
based on user input.&lt;/p&gt;

&lt;p&gt;The primary drawback of this approach is that it returns a pointer to a
heap-allocated object, so it’s not well-suited for “value-like” classes designed
to work on the stack. However, such classes usually don’t require complex
initialization in the first place. Factory functions also can’t be used when a
derived class constructor needs to initialize its base, so initializer methods
are sometimes necessary in the protected API of a base class. The public API can
still use factory functions, though.&lt;/p&gt;
</description>
          <pubDate>2017-12-21T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/42</link>
          <guid isPermaLink="true">https://abseil.io/tips/42</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #131: Special Member Functions and `= default`</title>
          <description>&lt;p&gt;Originally posted as totw/131 on 2017-03-24&lt;/p&gt;

&lt;p&gt;By James Dennett &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;(jdennett@google.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the beginning of time, C++ has supported compiler-declared versions of
some so-called &lt;em&gt;special member functions&lt;/em&gt;: the default constructor, destructor,
copy constructor and copy assignment operators. C++11 added move construction
and move assignment to the list, and added syntax (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt;) to
give control over when those defaults are declared and defined.&lt;/p&gt;

&lt;h2 id=&quot;what-does-default-do-and-why-would-we-use-it&quot;&gt;What Does &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; Do, and Why Would We Use It?&lt;/h2&gt;

&lt;p&gt;Writing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; is our way to tell the compiler “do what you would normally
have done for this special member function”. Why might we want to do this
rather than writing an implementation by hand or leaving the compiler to
declare one for us?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We can change the access level (e.g., make a constructor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;protected&lt;/code&gt; instead
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public&lt;/code&gt;), make a destructor virtual, or reinstate a function that would
be suppressed (e.g., a default constructor for a class that has other
user-declared constructors) and still get the compiler to generate the
function for us.&lt;/li&gt;
  &lt;li&gt;Compiler-defined copy and move operations don’t need maintenance every time
members are added or removed, if copying/moving the members is sufficient.&lt;/li&gt;
  &lt;li&gt;Compiler-provided special member functions can be &lt;em&gt;trivial&lt;/em&gt; (when all of the
operations they invoke are themselves trivial), which can make them faster
and safer.&lt;/li&gt;
  &lt;li&gt;Types with defaulted constructors can be &lt;em&gt;aggregates&lt;/em&gt;, and hence support
&lt;em&gt;aggregate initialization&lt;/em&gt;, whereas those with user-provided constructors
cannot.&lt;/li&gt;
  &lt;li&gt;Explicitly declaring a defaulted member gives us a place to document the
semantics of the resulting function.&lt;/li&gt;
  &lt;li&gt;In a class template, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; is a simple way to declare an operation
conditionally, based on whether some underlying type provides it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; on the initial declaration of a special member function,
the compiler will check whether it can synthesize an inline definition for that
function. If it can, it does. If it can’t, the function is actually declared as
&lt;em&gt;deleted&lt;/em&gt;, just as if we’d written &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt;. That’s just what we’d need for
transparently wrapping a class (say, if we’re defining a class template), but it
can be surprising to readers.&lt;/p&gt;

&lt;p&gt;If a function’s initial declaration uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt;, or if the compiler declares
a special member function that is not user-declared, an appropriate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noexcept&lt;/code&gt;
specification is deduced, potentially allowing faster code.&lt;/p&gt;

&lt;h2 id=&quot;how-does-it-work&quot;&gt;How Does It Work?&lt;/h2&gt;

&lt;p&gt;Before C++11, if we needed a default constructor and already had other
constructors, we’d have written one as:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// User-provided, non-trivial constructor makes A a non-aggregate.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From C++11 onwards we have more options.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// misleading: C has a deleted default constructor&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// const =&amp;gt; must always be initialized.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// unsurprising, but not explicit: D has a default constructor&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// std::unique_ptr has a default constructor&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Clearly we shouldn’t write code like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class C&lt;/code&gt;: in a non-template, use
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; only if you intend the class to support the operation (and then test
that it does).  &lt;em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clang-tidy&lt;/code&gt;&lt;/em&gt; includes a check for this.&lt;/p&gt;

&lt;p&gt;When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; is used &lt;em&gt;after&lt;/em&gt; the first declaration of a special member
function (i.e., outside of the class), it has a simpler meaning: it tells the
compiler to define the function, and to give an error if it is unable to do so.
When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; is used outside of the class, the defaulted function will not be
trivial: triviality is determined by the first declaration (so that all clients
agree on whether the operation is trivial or not).&lt;/p&gt;

&lt;p&gt;If you don’t need your class to be an aggregate and you don’t need the
constructor to be trivial then defaulting the constructor outside of the class
definition, like examples &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;E&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F&lt;/code&gt; below, is often a good choice.  Its meaning
is clear to readers, and is checked by the compiler.  For the special case of
defaulting a &lt;em&gt;default&lt;/em&gt; constructor or a destructor we could write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{}&lt;/code&gt; instead
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt;, but for other defaulted operations the compiler-generated
implementation is less simple, and for consistency it’s good to write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt;
in all applicable cases.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;E&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// promises to have a default constructor, but...&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// const =&amp;gt; must always be initialized.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// compilation error here: would not initialize `i`&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// promises to have a default constructor&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// std::unique_ptr has a default constructor&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// works as expected&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;p&gt;Prefer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; over writing an equivalent implementation by hand, even
if that implementation is just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{}&lt;/code&gt;. Optionally, omit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; from the
initial declaration and provide a separate defaulted implementation.&lt;/p&gt;

&lt;p&gt;Be cautious about defaulting move operations. Moved-from objects must still
satisfy the invariants of their type, and the default implementations will
usually not preserve relationships between fields.&lt;/p&gt;

&lt;p&gt;Outside of templates, write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=delete&lt;/code&gt; instead if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=default&lt;/code&gt; wouldn’t provide an
implementation.&lt;/p&gt;
</description>
          <pubDate>2017-12-07T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/131</link>
          <guid isPermaLink="true">https://abseil.io/tips/131</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #123: &lt;code&gt;absl::optional&lt;/code&gt; and &lt;code&gt;std::unique_ptr&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as totw/123 on 2016-09-06&lt;/p&gt;

&lt;p&gt;By Alexey Sokolov &lt;a href=&quot;mailto:sokolov@google.com&quot;&gt;(sokolov@google.com)&lt;/a&gt; and 
Etienne Dechamps &lt;a href=&quot;mailto:edechamps@google.com&quot;&gt;(edechamps@google.com)&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-to-store-values&quot;&gt;How to Store Values&lt;/h2&gt;

&lt;p&gt;This tip discusses several ways of storing values. Here we use class member
variables as an example, but many of the points below also apply to local
variables.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;memory&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;absl/types/optional.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;.../bar.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opt_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;as-a-bare-object&quot;&gt;As a Bare Object&lt;/h3&gt;

&lt;p&gt;This is the simplest way. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val_&lt;/code&gt; is constructed and destroyed at the beginning
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;’s constructor and at the end of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;’s destructor, respectively. If
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; has a default constructor, it doesn’t even need to be initialized
explicitly.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val_&lt;/code&gt; is very safe to use, because its value can’t be null. This removes a
class of potential bugs.&lt;/p&gt;

&lt;p&gt;But bare objects are not very flexible:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The lifetime of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val_&lt;/code&gt; is fundamentally tied to the lifetime of its parent
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; object, which is sometimes not desirable. If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; supports move or
swap operations, the contents of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val_&lt;/code&gt; can be replaced using these
operations, while any existing pointers or references to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val_&lt;/code&gt; continue
pointing or referring to the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val_&lt;/code&gt; object (as a container), not to the
value stored in it.&lt;/li&gt;
  &lt;li&gt;Any arguments that need to be passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt;’s constructor need to be
computed inside the initializer list of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;’s constructor, which can be
difficult if complicated expressions are involved.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;as-absloptionalbar&quot;&gt;As &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&amp;lt;Bar&amp;gt;&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;This is a good middle ground between the simplicity of bare objects and the
flexibility of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;. The object is stored inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; but, unlike
bare objects, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt; can be empty. It can be populated at any time by
assignment (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opt_ = ...&lt;/code&gt;) or by constructing the object in place
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opt_.emplace(...)&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Because the object is stored inline, the usual caveats about allocating large
objects on the stack apply, just like for a bare object. Also be aware that an
empty &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt; uses as much memory as a populated one.&lt;/p&gt;

&lt;p&gt;Compared to a bare object, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt; has a few downsides:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It’s less obvious for the reader where object construction and destruction
occur.&lt;/li&gt;
  &lt;li&gt;There is a risk of accessing an object which does not exist.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;as-stdunique_ptrbar&quot;&gt;As &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;Bar&amp;gt;&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;This is the most flexible way. The object is stored outside of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;. Just like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt;, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; can be empty. However, unlike
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt;, it is possible to transfer ownership of the object to
something else (through a move operation), to take ownership of the object from
something else (at construction or through assignment), or to assume ownership
of a raw pointer (at construction or through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptr_ = absl::WrapUnique(...)&lt;/code&gt;, see
&lt;a href=&quot;/tips/126&quot;&gt;TotW 126&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; is null, it doesn’t have the object allocated, and
consumes only the size of a pointer&lt;sup id=&quot;fnref:deleter&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:deleter&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Wrapping an object in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; is necessary if the object may need to
outlive the scope of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; (ownership transfer).&lt;/p&gt;

&lt;p&gt;This flexibility comes with some costs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Increased cognitive load on the reader:
    &lt;ul&gt;
      &lt;li&gt;It’s less obvious what’s stored inside (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt;, or something derived from
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt;). However, it may also decrease the cognitive load, as the reader
can focus only on the base interface held by the pointer.&lt;/li&gt;
      &lt;li&gt;It’s even less obvious than with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt; where object
construction and destruction occur, because ownership of the object can
be transferred.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;As with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt;, there is a risk of accessing an object which does
not exist - the famous null pointer dereference.&lt;/li&gt;
  &lt;li&gt;The pointer introduces an additional level of indirection, which requires a
heap allocation, and is &lt;a href=&quot;https://en.wikipedia.org/wiki/Locality_of_reference&quot;&gt;not
friendly&lt;/a&gt; to CPU
caches; Whether this matters or not depends a lot on particular use cases.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;Bar&amp;gt;&lt;/code&gt; is not copyable even if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; is. This also prevents
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; from being copyable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;As always, strive to avoid unnecessary complexity, and use the simplest thing
that works. Prefer bare object, if it works for your case. Otherwise, try
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&lt;/code&gt;. As a last resort, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
  &lt;tr&gt;
    &lt;th&gt;&lt;/th&gt;
    &lt;th&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt;&lt;/th&gt;
    &lt;th&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::optional&amp;lt;Bar&amp;gt;&lt;/code&gt;&lt;/th&gt;
    &lt;th&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;Bar&amp;gt;&lt;/code&gt;&lt;/th&gt;
  &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
  &lt;tr&gt;
    &lt;td&gt;Supports delayed construction&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Always safe to access&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Can transfer ownership of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Can store subclasses of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Movable&lt;/td&gt;
    &lt;td&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; is movable&lt;/td&gt;
    &lt;td&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; is movable&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Copyable&lt;/td&gt;
    &lt;td&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; is copyable&lt;/td&gt;
    &lt;td&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; is copyable&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Friendly to CPU caches&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;No heap allocation overhead&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
    &lt;td&gt;✓&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Memory usage&lt;/td&gt;
    &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(Bar)&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;&lt;nobr&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(Bar) + sizeof(bool)&lt;/code&gt;&lt;/nobr&gt;&lt;sup id=&quot;fnref:padding&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:padding&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;
    &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(Bar*)&lt;/code&gt; when null, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(Bar*) + sizeof(Bar)&lt;/code&gt; otherwise&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Object lifetime&lt;/td&gt;
    &lt;td&gt;Same as enclosing scope&lt;/td&gt;
    &lt;td&gt;Restricted to enclosing scope&lt;/td&gt;
    &lt;td&gt;Unrestricted&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(Bar*)&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(&amp;amp;val_)&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(&amp;amp;opt_.value())&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(&amp;amp;*opt_)&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(ptr_.get())&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(&amp;amp;*ptr_)&lt;/code&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Remove value&lt;/td&gt;
    &lt;td&gt;N/A&lt;/td&gt;
    &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opt_.reset();&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opt_ = absl::nullopt;&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptr_.reset();&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptr_ = nullptr;&lt;/code&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:deleter&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;In case of a non-empty custom deleter there is also an additional
space for that deleter. &lt;a href=&quot;#fnref:deleter&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:padding&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Also padding may be added. &lt;a href=&quot;#fnref:padding&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
          <pubDate>2017-12-07T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/123</link>
          <guid isPermaLink="true">https://abseil.io/tips/123</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #130: Namespace Naming</title>
          <description>&lt;p&gt;Originally posted as totw/130 on 2017-02-17&lt;/p&gt;

&lt;p&gt;By Titus Winters &lt;a href=&quot;mailto:titus@google.com&quot;&gt;(titus@google.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The precision of naming takes away from the uniqueness of seeing&lt;/em&gt; — Pierre
Bonnard&lt;/p&gt;

&lt;p&gt;The earliest commit of the Google C++ Style Guide contains the guidance that
many people are still using for namespace naming. Roughly, this can be
summarized as “namespaces are derived from package paths.” Following on
the heels of Java’s package naming requirements, this makes a lot of sense: we
want to be able to uniquely identify symbols in C++ and we want there to be
uniqueness and consistency in namespace choice.&lt;/p&gt;

&lt;p&gt;Except in actuality, we don’t. We just didn’t realize for almost a decade.&lt;/p&gt;

&lt;h2 id=&quot;name-lookup&quot;&gt;Name Lookup&lt;/h2&gt;

&lt;p&gt;Let’s start with how name lookup works in C++ and how it’s different from Java.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Baz&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In C++, lookup on an unqualified name (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Baz&lt;/code&gt;) will search expanding scopes for a
symbol of the same name: first in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f()&lt;/code&gt; (the function), then in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar&lt;/code&gt;, then in
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt;, then in the global namespace.&lt;/p&gt;

&lt;p&gt;In Java, there is no such thing as an unqualified symbol: either a symbol is
a qualified name:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Baz&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Baz&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or it is imported, either as a single package member or via wildcard:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.google.foo.bar.Baz&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.google.foo.bar.*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In no case is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Baz&lt;/code&gt; looked for outside of the package that is explicitly
provided: wildcards don’t descend into child packages, nor is search extended
into parent packages. As it turns out, this difference in how parent
packages/namespaces are handled within Java and C++ is fundamental to why
structural namespace naming (making the namespace structure match the package
hierarchy) is a mistake within C++.&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;

&lt;p&gt;The fundamental problem for building namespaces out of packages is that we
rarely rely on fully-qualified lookup in C++, normally writing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;
rather than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::std::unique_ptr&lt;/code&gt;. Coupled with lookup in enclosing namespaces,
this means that for code in a deeply nested package
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::division::section::team::subteam::project&lt;/code&gt;, for example) any symbol that is not
fully qualified (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;) can in fact reference any of&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::std::unique_ptr&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::division::std::unique_ptr&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::division::section::std::unique_ptr&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::division::section::team::std::unique_ptr&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::division::section::team::subteam::std::unique_ptr&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::division::section::team::subteam::project::std::unique_ptr&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And what’s worse: unqualified search starts at the bottom of that list &lt;em&gt;and
stops as soon as there is a namespace match&lt;/em&gt;. This means that your build can be
broken if any of your transitive includes add a previously unused namespace that
matches the leading namespace of any symbol you use out of an unqualified
namespace. Strictly speaking, this doesn’t even have to be a build break: if
someone adds something with a matching name and a syntactically-compatible API,
the implementation of that API may be completely incompatible and cause
widespread havoc at runtime. Obviously this isn’t too bad with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std&lt;/code&gt; - nobody
should ever be adding a nested namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std&lt;/code&gt; -  but what about more common
namespaces? How about things like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;testing&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Names aren’t chosen to be unique. Since teams commonly create local utility
packages to handle common tasks relating to the infrastructure they rely on, we
wind up with local &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;util&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pipeline&lt;/code&gt; packages - and
sub-namespaces. This is a recipe for unnecessary and unintended collisions.&lt;/p&gt;

&lt;p&gt;For comparison, the problem in Java is far reduced: if you wildcard-import from
two packages in Java and one adds a new symbol with the same name as the other
package, your build can break. This is easily and completely solved by
forbidding wildcard imports as is done in many Java styles.&lt;/p&gt;

&lt;h2 id=&quot;two-consistent-options-three-approaches&quot;&gt;Two Consistent Options, Three Approaches&lt;/h2&gt;

&lt;p&gt;There are two features that prevent this build-break-at-a-distance:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If no leaf namespace (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search::foo::bar&lt;/code&gt;) matches any top-level namespace
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::bar&lt;/code&gt;) or a sub-namespace of any parent of that leaf (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search::bar&lt;/code&gt;), no
name collisions will occur.&lt;/li&gt;
  &lt;li&gt;If there are no unqualified lookups, there will be no problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are (at least) three ways to achieve this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Always fully qualify everything outside of the current namespace. This is
very verbose and sort of weird: nothing in C++ (including the standard
library) is written with leading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::&lt;/code&gt; on every symbol.&lt;/li&gt;
  &lt;li&gt;Build some tooling to identify introduction of new namespaces and ensure
that it doesn’t overlap with any other namespace in the same hierarchy. That
is, do not add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search::bar&lt;/code&gt; if there is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::bar&lt;/code&gt; or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search::foo::bar&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Don’t nest deeply: a single top-level namespace per project gets the same
result without long/complicated names, with less exposure to accidents,
without causing surprise for new engineers, and without the need to build any
tooling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The current style guide suggests the &lt;a href=&quot;http://google.github.io/styleguide/cppguide.html#Namespace_Names&quot;&gt;last
option&lt;/a&gt;, but
allows for the old style (namespaces match package names) if necessary. This is
largely because the Google didn’t want to cause too much anxiety or
trigger anyone re-namespacing things. That said, if we had it to do over again
in a fresh codebase we would unambiguously say this: one top-level namespace for
public interfaces per project. Ensure uniqueness of namespaces via a common
database. Thus we get (only) top-level namespaces like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl&lt;/code&gt;, and can have no
ambiguity in lookup (barring collision between local symbols and those in the
global namespace, but modern rules discourage the global namespace anyway).&lt;/p&gt;

&lt;p&gt;Because there is so much code that existed before this change, and so much code
following the old pattern even after this change, we find ourselves in a sort of
half-way space, with some namespaces that often need to be fully qualified
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::util&lt;/code&gt;), and some that are obviously unique and never need to be (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;but-it-keeps-things-organized&quot;&gt;But It Keeps Things Organized!&lt;/h2&gt;

&lt;p&gt;I regularly hear people express that small/nested namespaces “keep things
organized.” Putting things in their place feels right - why lump together
something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrCat()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make_unique()&lt;/code&gt; other than being in Abseil these
have nothing to do with one another! Wouldn’t an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::strings::utilities&lt;/code&gt;
namespace help differentiate from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::smart_ptrs&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;In other languages this would probably be good - better organization with no
downside. However, because of how lookup works (expanding into successive layers
of containing namespace scopes) your fine-grained namespace is impacted by every
symbol (and sub-namespace) added in every parent namespace. That is: while you
don’t exactly “contain” the names from parent namespaces, name/namespace
collisions matter nearly as much as if you do. Small/deeply-nested namespaces
don’t &lt;em&gt;shield&lt;/em&gt; you from this, they &lt;em&gt;exacerbate&lt;/em&gt; it.&lt;/p&gt;

&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;/h2&gt;

&lt;p&gt;Practically speaking, the following is the best we can do given the
realities of most codebases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Have a database of some form for a codebase to identify the unique namespaces.&lt;/li&gt;
  &lt;li&gt;When introducing a new namespace, use that database and introduce it as
a top-level.&lt;/li&gt;
  &lt;li&gt;If for some reason the above is impossible, never &lt;em&gt;ever&lt;/em&gt; introduce a
sub-namespace that matches a well-known top-level namespace. No
sub-namespaces for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;testing&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;util&lt;/code&gt;, etc. Try to give
sub-namespaces unique names that are unlikely to collide with future
top-levels.&lt;/li&gt;
  &lt;li&gt;When declaring namespace aliases and using-declarations, use fully qualified
names, unless you are referring to a name inside the current namespace, as
per &lt;a href=&quot;/tips/119&quot;&gt;TotW 119&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;For code in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;util&lt;/code&gt; or other commonly-abused namespaces, try to avoid full
qualification, but qualify if necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The advice in &lt;a href=&quot;/tips/119&quot;&gt;TotW 119&lt;/a&gt; also helps, for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; files: our concern with
fully-qualifying is not that it is bad, but that it is &lt;em&gt;weird&lt;/em&gt; compared to C++
code in the rest of the world. Limited use in using-declarations strikes an
acceptable balance. However, even complete adherence to this suggestion doesn’t
fully mitigate the dangers from unqualified name lookup because we still have
header files and don’t want to fully qualify every symbol in every header.&lt;/p&gt;
</description>
          <pubDate>2017-11-30T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/130</link>
          <guid isPermaLink="true">https://abseil.io/tips/130</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #119: Using-declarations and namespace aliases</title>
          <description>&lt;p&gt;Originally posted as totw/119 on 2016-07-14&lt;/p&gt;

&lt;p&gt;By Thomas Köppe &lt;a href=&quot;mailto:tkoeppe@google.com&quot;&gt;(tkoeppe@google.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This tip gives a simple, robust recipe for writing &lt;em&gt;using-declarations&lt;/em&gt; and
namespace aliases in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; files that avoids subtle pitfalls.&lt;/p&gt;

&lt;p&gt;Before we dive into the details, here is an example of the recipe in action:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;makers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;otherlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BazBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mylib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BarFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;applied&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bitfiddling&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concepts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Private helper code here.&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Interface implementation code here.&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace makers&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace example&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remember that everything in this tip applies only to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cc&lt;/code&gt; files, since you
should &lt;a href=&quot;http://google.github.io/styleguide/cppguide.html#Aliases&quot;&gt;never put convenience aliases in header
files&lt;/a&gt;. Such aliases
are a convenience for the implementer (and the reader of an implementation), not
an exported facility. (Names that &lt;em&gt;are&lt;/em&gt; part of the exported API may of course
be declared in headers.)&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Never declare namespace aliases or convenience
  &lt;em&gt;using-declaration&lt;/em&gt;s at namespace scope in header files, only
  in `.cc` files.&lt;/li&gt;
  &lt;li&gt;Declare namespace aliases and &lt;em&gt;using-declaration&lt;/em&gt;s inside the
  innermost namespace, whether named or anonymous. (Do not add an anonymous
  namespace just for this purpose.)&lt;/li&gt;
  &lt;li&gt;When declaring namespace aliases and &lt;em&gt;using-declaration&lt;/em&gt;s, use
  fully qualified names (with leading `::`) unless you are referring to a
  name inside the current namespace.&lt;/li&gt;
  &lt;li&gt;For other uses of names, avoid fully qualifying when reasonable, see
  &lt;a href=&quot;/tips/130&quot;&gt;TotW 130&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Remember that you can always have a local namespace alias or
&lt;em&gt;using-declaration&lt;/em&gt; in a block scope, which can be handy in header-only
libraries.)&lt;/p&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;C++ organizes names into &lt;em&gt;namespaces&lt;/em&gt;. This crucial facility allows code bases
to scale by keeping ownership of names local avoiding name collisions in other
scopes. However, namespaces impose a certain cosmetic burden, since qualified
names (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo::Bar&lt;/code&gt;) are often long and quickly become clutter. We often find it
convenient to use &lt;em&gt;unqualified names&lt;/em&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt;). Additionally, we may wish to
introduce a namespace alias for a long but frequently used namespace: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespace
eu = example::v1::util;&lt;/code&gt; We will collectively call &lt;em&gt;using-declaration&lt;/em&gt;s
and namespace aliases just &lt;em&gt;aliases&lt;/em&gt; in this tip.&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;

&lt;p&gt;The purpose of a namespace is to help code authors avoid name collisions, both
at the point of name lookup and at the point of linking. Aliases can potentially
undermine the protection afforded by namespaces. The problem has two separate
aspects: the scope of the alias, and the use of relative qualifiers.&lt;/p&gt;

&lt;h3 id=&quot;scope-of-the-alias&quot;&gt;Scope of the Alias&lt;/h3&gt;

&lt;p&gt;The scope at which you place an alias can have subtle effects on code
maintainability. Consider the following two variants:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Quz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;util&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It appears that both &lt;em&gt;using-declaration&lt;/em&gt;s are effective at making the
names &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Quz&lt;/code&gt; available for unqualified lookup inside our working
namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::example::util&lt;/code&gt;. For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt;, everything is working as expected,
provided there is no other declaration of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; inside namespace
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::example::util&lt;/code&gt;. But this is your namespace, so it is in your power to control
this.&lt;/p&gt;

&lt;p&gt;On the other hand, if a header is later included that declares a global name
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Quz&lt;/code&gt;, then the first &lt;em&gt;using-declaration&lt;/em&gt; becomes ill-formed, as it attempts to
redeclare the name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Quz&lt;/code&gt;. And if another header declares &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::example::Quz&lt;/code&gt; or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::example::util::Quz&lt;/code&gt;, then unqualified lookup will find &lt;em&gt;that&lt;/em&gt; name rather
than your alias.&lt;/p&gt;

&lt;p&gt;This brittleness can be avoided if you do not add names to namespaces that you
do not own (which includes the global namespace). By placing the aliases inside
your own namespace, the unqualified lookup finds your alias first and never
continues to search containing namespaces.&lt;/p&gt;

&lt;p&gt;More generally, the closer a declaration is to the point of use, the smaller is
the set of scopes that can break your code. At the worst end of our example is
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Quz&lt;/code&gt;, which can be broken by anyone; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar&lt;/code&gt; can only be broken by other code in
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::example::util&lt;/code&gt;, and a name that is declared and used inside an unnamed
namespace cannot be broken by any other scope. See &lt;a href=&quot;#unnamed-namespaces&quot;&gt;Unnamed
Namespaces&lt;/a&gt; for an example.&lt;/p&gt;

&lt;h3 id=&quot;relative-qualifiers&quot;&gt;Relative Qualifiers&lt;/h3&gt;

&lt;p&gt;A &lt;em&gt;using-declaration&lt;/em&gt; of the form &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using foo::Bar&lt;/code&gt; seems innocuous, but it is in
fact ambiguous. The problem is that it is safe to rely on the &lt;em&gt;existence&lt;/em&gt; of
names in a namespace, but it is not safe to rely on the &lt;em&gt;absence&lt;/em&gt; of names.
Consider this code:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;util&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is perhaps the author’s intention to use the name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::foo::Bar&lt;/code&gt;.
However, this can break, because the code is relying on the existence of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::foo::Bar&lt;/code&gt; &lt;em&gt;and also&lt;/em&gt; on the non-existence of namespaces &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::example::foo&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::example::util::foo&lt;/code&gt;. This brittleness can be avoided by qualifying the used
name fully: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using ::foo::Bar&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The only time that a relative name is unambiguous and cannot possibly be broken
by outside declarations is if it refers to a name that is already inside your
current namespace:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;util&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Params&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace internal&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;internal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// OK, same as ::example::util::internal::Params&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This follows the same logic that we discussed in the previous section.&lt;/p&gt;

&lt;p&gt;What if a name lives in a sibling namespace, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::example::tools::Thing&lt;/code&gt;?
You can say either &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tools::Thing&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::example::tools::Thing&lt;/code&gt;. The fully
qualified name is always correct, but it may also be appropriate to use the
relative name. Use your own judgment.&lt;/p&gt;

&lt;p&gt;A cheap way to avoid a lot of these problems is not to use namespaces in your
project that are the same as popular top-level namespaces (such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;util&lt;/code&gt;); the
Style Guide &lt;a href=&quot;http://google.github.io/styleguide/cppguide.html#Namespace_Names&quot;&gt;recommends this practice&lt;/a&gt; explicitly.&lt;/p&gt;

&lt;h3 id=&quot;demo&quot;&gt;Demo&lt;/h3&gt;

&lt;p&gt;The following code shows examples of both failure modes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;helper.h:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace foo&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace bar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;some_feature.h:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Your code:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;helper.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;some_feature.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace foo&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Failure mode #1: Alias at a bad scope.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Error: redeclaration (because of &quot;f&quot; declared in some_feature.h)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Failure mode #2: Alias badly qualified.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Error: No &quot;f&quot; in namespace ::bar::foo (because that namespace was declared in helper.h)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// The recommended way, robust in the face of unrelated declarations:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// OK&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UseCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace bar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;unnamed-namespaces&quot;&gt;Unnamed Namespaces&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;using-declaration&lt;/em&gt; placed in an unnamed namespace can be accessed from the
enclosing namespace and vice versa. If you already have an unnamed namespace at
the top of the file, prefer putting all aliases there. From within that unnamed
namespace, you gain an extra little bit of robustness against clashing with
something declared in the enclosing namespace.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;util&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Put all using-declarations in here. Don&apos;t spread them over the file.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Quz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// In here, Bar and Quz refer inalienably to your aliases.&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Can use both Bar and Quz here too. (But don&apos;t declare any entities called Bar or Quz yourself now.)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;non-aliased-names&quot;&gt;Non-aliased names&lt;/h2&gt;

&lt;p&gt;So far we have been talking about local aliases for distant names. But what if
we want to use names directly and not create aliases at all? Should we say
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;util::Status&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::util::Status&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;There is no obvious answer. Unlike the alias declarations that we have been
discussing until now, which appear at the top of the file far away from the
actual code, the direct use of names affects the local readability of your code.
While it is true that relatively qualified names may break in the future, there
is a significant cost for using absolute qualifications. The visual clutter
caused by the leading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::&lt;/code&gt; may well be distracting and not worth the added
robustness. In this case, use your own judgment to decide which style you
prefer. See &lt;a href=&quot;/tips/130&quot;&gt;TotW 130&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;acknowledgments&quot;&gt;Acknowledgments&lt;/h2&gt;

&lt;p&gt;All credit is due to Roman Perepelitsa (romanp@google.com) who originally
suggested this style in a mailing list discussion and who contributed numerous
corrections and punchlines. However, all errors are mine.&lt;/p&gt;
</description>
          <pubDate>2017-11-30T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/119</link>
          <guid isPermaLink="true">https://abseil.io/tips/119</guid>
        </item>
      
    
      
        <item>
          <title>CppCon 2017: How to Break an ABI</title>
          <description>&lt;h3 id=&quot;gennadiy-rozentals-lightning-talk&quot;&gt;Gennadiy Rozental’s Lightning Talk&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:shreck@google.com&quot;&gt;Tom Manshreck&lt;/a&gt;, Abseil Tech Writer&lt;/p&gt;

&lt;p&gt;Breaking an
&lt;a href=&quot;https://en.wikipedia.org/wiki/Application_binary_interface&quot; target=&quot;_blank&quot;&gt;ABI&lt;/a&gt;
is seldom your first choice, but what do you do if you simply must
break this contract with your developers?&lt;/p&gt;

&lt;p&gt;Check out Gennadiy Rozental’s talk on how we implemented our own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::string&lt;/code&gt;
class in Google, decided we eventually should move back to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;,
and how we kept Google’s engineers happy during the transition.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=NzaYUlAw93k&quot; target=&quot;_blank&quot;&gt;
&lt;img src=&quot;/img/cppcon-breaking-abi.png&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;
</description>
          <pubDate>2017-11-30T00:00:00-05:00</pubDate>
          <link>https://abseil.io/blog/20171023-cppcon-breaking-abi</link>
          <guid isPermaLink="true">https://abseil.io/blog/20171023-cppcon-breaking-abi</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #126: `make_unique` is the new `new`</title>
          <description>&lt;p&gt;Originally posted as totw/126 on 2016-12-12&lt;/p&gt;

&lt;p&gt;By James Dennett &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;(jdennett@google.com)&lt;/a&gt; based on a
mailing list post by Titus Winters &lt;a href=&quot;mailto:titus@google.com&quot;&gt;(titus@google.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a codebase expands it is increasingly difficult to know the details of
everything you depend on. Requiring deep knowledge doesn’t scale: we have to
rely on interfaces and contracts to know that code is correct, both when writing
and when reviewing. In many cases the type system can provide those contracts in
a common fashion. Consistent use of type system contracts makes for easier
authoring and reviewing of code by identifying places where there are
potentially risky allocations or ownership transfers for objects allocated on
the heap.&lt;/p&gt;

&lt;p&gt;While in C++ we can reduce the need for dynamic memory allocation by using plain
values, sometimes we need objects to outlive their scope. C++ code should prefer
smart pointers (most commonly &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;) instead of raw pointers when
dynamically allocating objects. This provides a consistent story around
allocation and ownership transfer, and leaves a clearer visual signal where
there’s code that needs closer inspection for ownership issues. The side effect
of matching how allocation works in the outside world post-C++14 and being
exception safe is just icing.&lt;/p&gt;

&lt;p&gt;Two key tools for this are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique()&lt;/code&gt; (a C++11 implementation of
C++14’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique()&lt;/code&gt;, for leak-free dynamic allocation) and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique()&lt;/code&gt; (for wrapping owned raw pointers into the corresponding
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; types). They can be found in
&lt;a href=&quot;https://github.com/abseil/abseil-cpp/blob/master/absl/memory/memory.h&quot;&gt;absl/memory/memory.h&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;why-avoid-new&quot;&gt;Why Avoid &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt;?&lt;/h2&gt;

&lt;p&gt;Why should code prefer smart pointers and these allocation functions over raw
pointers and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt;?&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;When possible, ownership is best expressed in the type system. This allows
reviewers to verify correctness (absence of leaks and of double-deletes)
almost entirely by local inspection. (In code that is exceptionally
performance sensitive, this may be excused: while cheap, passing
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; across function boundaries by value has non-zero overhead
because of ABI constraints. That’s rarely important enough to justify
avoiding it.)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Somewhat like the reasoning for preferring &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; over
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace_back()&lt;/code&gt; (&lt;a href=&quot;/tips/112&quot;&gt;TotW 112&lt;/a&gt;), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique()&lt;/code&gt; directly
expresses the intent and can only do one thing (do the allocation with a
public constructor, returning a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; of the specified
type). There’s no type conversion or hidden behavior. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique()&lt;/code&gt;
does what it says on the tin.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The same could be achieved with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;T&amp;gt; my_t(new T(args));&lt;/code&gt; but
that is redundant (repeating the type name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;) and for some people there’s
value in minimizing calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt;. More on this in #5.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If all allocations are handled via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique()&lt;/code&gt; or factory calls,
that leaves &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique()&lt;/code&gt; for the implementation of those factory
calls, for code interacting with legacy methods that don’t rely on
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; for ownership transfer, and for rare cases that need to
dynamically allocate with aggregate initialization (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique(new
MyStruct{3.141, &quot;pi&quot;})&lt;/code&gt;). In code review it’s easy to spot the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique&lt;/code&gt; calls and evaluate “does that expression look like an
ownership transfer?” Usually it’s obvious (for example, it’s some factory
function). When it’s not obvious, we need to check the function to be sure
that it’s actually a raw-pointer ownership transfer.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If we instead rely mostly on the constructors of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;, we see
calls like: &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;T&amp;gt; foo(Blah());&lt;/code&gt; &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;T&amp;gt; bar(new T());&lt;/code&gt; &lt;br /&gt;
It takes only a moment’s inspection to see that the latter is safe (no leak,
no double-delete). The former? It depends: if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Blah()&lt;/code&gt; is returning a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;, it’s fine, though in that case it would be more obviously
safe if written as &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;T&amp;gt; foo = Blah();&lt;/code&gt; &lt;br /&gt;
If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Blah()&lt;/code&gt; is returning an ownership-transferred raw pointer, that’s also
fine. If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Blah()&lt;/code&gt; is returning just some random pointer (no transfer), then
there’s a problem. Reliance on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique()&lt;/code&gt;
(avoiding the constructors) provides an additional visual clue for the
places where we have to worry (calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique()&lt;/code&gt;, and only those).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;how-should-we-choose-which-to-use&quot;&gt;How Should We Choose Which to Use?&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;By default, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique()&lt;/code&gt; (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_shared()&lt;/code&gt; for the rare
cases where shared ownership is appropriate) for dynamic allocation. For
example, instead of: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;T&amp;gt; bar(new T());&lt;/code&gt; write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto bar
= absl::make_unique&amp;lt;T&amp;gt;();&lt;/code&gt; and instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar.reset(new T());&lt;/code&gt; write
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar = absl::make_unique&amp;lt;T&amp;gt;();&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In a factory function that uses a non-public constructor, return a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&amp;lt;T&amp;gt;&lt;/code&gt; and use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique(new T(...))&lt;/code&gt; in the
implementation.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When dynamically allocating an object that requires brace initialization
(typically a struct, an array, or a container), use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique(new
T{...})&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When calling a legacy API that accepts ownership via a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T*&lt;/code&gt;, either allocate
the object in advance with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique&lt;/code&gt; and call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptr.release()&lt;/code&gt; in
the call, or use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt; directly in the function argument.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When calling a legacy API that returns ownership via a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T*&lt;/code&gt;, immediately
construct a smart pointer with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WrapUnique&lt;/code&gt; (unless you’re immediately
passing the pointer to another legacy API that accepts ownership via a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T*&lt;/code&gt;).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Prefer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique()&lt;/code&gt; over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique()&lt;/code&gt;, and prefer
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::WrapUnique()&lt;/code&gt; over raw &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt;.&lt;/p&gt;
</description>
          <pubDate>2017-11-23T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/126</link>
          <guid isPermaLink="true">https://abseil.io/tips/126</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #109: Meaningful `const` in Function Declarations</title>
          <description>&lt;p&gt;Originally posted as totw/109 on 2016-01-14&lt;/p&gt;

&lt;p&gt;By Greg Miller &lt;a href=&quot;mailto:jgm@google.com&quot;&gt;(jgm@google.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This document will explain when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; is meaningful in function declarations,
and when it is meaningless and best omitted. But first, let us briefly explain
what is meant by the terms &lt;em&gt;declaration&lt;/em&gt; and &lt;em&gt;definition&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Consider the following code:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;                     &lt;span class=&quot;c1&quot;&gt;// 1: declaration of F(int)&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;               &lt;span class=&quot;c1&quot;&gt;// 2: re-declaration of F(int)&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// 3: definition of F(int)&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// 4: error: re-definition of F(int)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first two lines are function &lt;em&gt;declarations&lt;/em&gt;. A function &lt;em&gt;declaration&lt;/em&gt; tells
the compiler the function’s signature and return type. In the above example, the
function’s signature is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F(int)&lt;/code&gt;. The constness of the function’s parameter type
is ignored, so both declarations are equivalent (See &lt;a href=&quot;http://eel.is/c++draft/over.load&quot;&gt;“Overloadable
declarations”&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;Lines 3 and 4 from the above code are both function &lt;em&gt;definitions&lt;/em&gt;. A function
&lt;em&gt;definition&lt;/em&gt; is also a declaration, but a definition also contains the
function’s body. Therefore, line 3 is a definition for a function with the
signature &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F(int)&lt;/code&gt;. Similarly, line 4 is also a definition for the same
function, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F(int)&lt;/code&gt;, which will result in an error at link time. Multiple
declarations are allowed, but only a single definition is permitted.&lt;/p&gt;

&lt;p&gt;Even though the definitions on lines 3 and 4 &lt;em&gt;declare&lt;/em&gt; and &lt;em&gt;define&lt;/em&gt; the same
function, there is a difference within their function bodies due to the way they
are declared. From the definition on line 3, the type of the function-parameter
variable within the function will be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; (i.e., non-const). On the other hand,
the definition on line 4 will produce a function-parameter variable within the
function whose type is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const int&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;meaningful-const-in-function-declarations&quot;&gt;Meaningful &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; in Function Declarations&lt;/h2&gt;

&lt;p&gt;Not all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; qualifications in function declarations are ignored. To quote
from “Overloadable declarations” ([over.load]) in the C++ standard (emphasis
added):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; type-specifiers &lt;strong&gt;buried within a parameter type specification&lt;/strong&gt; are
significant and can be used to distinguish overloaded function declarations&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The following are examples where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; is significant and not ignored:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;                  &lt;span class=&quot;c1&quot;&gt;// 1&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;                  &lt;span class=&quot;c1&quot;&gt;// 2&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// 3&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;                        &lt;span class=&quot;c1&quot;&gt;// 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the above examples, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; parameter itself is never declared &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;. Each
of the above functions accepts a parameter named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; of a different type, thus
forming a valid overload set. Line 1 declares a function that accepts a “pointer
to an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; that is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;”. Line 2 declares a function that accepts a
“reference to an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; that is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;”. And line 3 declares a function that
accepts a “unique_ptr to an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; that is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;”. All of these uses of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;
are important and not ignored because they are part of the parameter type
specification and are not top-level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; qualifications that affect the
parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;Line 4 is interesting because it does not include the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; keyword at all,
and may at first appear to be equivalent to the declaration on line 1 given the
reasons cited at the beginning of this document. The reason that this is not
true and that line 4 is a valid and distinct declaration is that only top-level,
or outermost, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; qualifications of the parameter type specification are
ignored.&lt;/p&gt;

&lt;p&gt;To complete this example, let us look at a few more examples where a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; is
meaningless and ignored.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// 1: declares F(int)&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// 2: declares F(int*)&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// 3: declares F(const int*)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;rules-of-thumb&quot;&gt;Rules of Thumb&lt;/h2&gt;

&lt;p&gt;Though few of us will ever truly master all the delightful obscurities of C++,
it is important that we do our best to understand the rules of the game. This
will help us write code that is understood by other C++ programmers who are
following the same rules and playing the same game. For this reason, it is
important that we understand when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; qualification is meaningful in a
function declaration and when it is ignored.&lt;/p&gt;

&lt;p&gt;Although there is no official guidance from the &lt;a href=&quot;http://google.github.io/styleguide/cppguide.html&quot;&gt;Google C++ style guide&lt;/a&gt;, and there is no single
generally accepted opinion, the following is one reasonable set of guidelines:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Never use top-level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; on function parameters in &lt;em&gt;declarations&lt;/em&gt; that
are not definitions (and be careful not to copy/paste a meaningless
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;). It is meaningless and ignored by the compiler, it is visual noise,
and it could mislead readers.&lt;/li&gt;
  &lt;li&gt;Do use top-level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; on function parameters in &lt;em&gt;definitions&lt;/em&gt; at your (or
your team’s) discretion. You might follow the same rationale as you would
for when to declare a function-local variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
</description>
          <pubDate>2017-11-23T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/109</link>
          <guid isPermaLink="true">https://abseil.io/tips/109</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #99: Nonmember Interface Etiquette</title>
          <description>&lt;p&gt;Originally posted as totw/99 on 2015-06-24&lt;/p&gt;

&lt;p&gt;Revised 2017-10-10&lt;/p&gt;

&lt;p&gt;The interface of a C++ class is not constrained to its members or to its
definition. When evaluating an API, we must consider definitions beyond the
class body that can be as much a part of its interface as its public members.&lt;/p&gt;

&lt;p&gt;These external interface points include template specializations like hashers or
traits, nonmember operator overloads (e.g. logging, relationals), and other
canonical nonmember functions designed for use with argument-dependent lookup
(ADL), most notably &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swap()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A few of these are illustrated below for some sample class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;space::Key&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// standard streaming&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// gTest printing&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrintTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// new-style flag extension:&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParseFlag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UnparseFlag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace space&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;HASH_NAMESPACE_BEGIN&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;space&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;HASH_NAMESPACE_END&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are some important risks associated with making such extensions
incorrectly, so this article will try to present some guidance.&lt;/p&gt;

&lt;h2 id=&quot;the-proper-namespace&quot;&gt;The Proper Namespace&lt;/h2&gt;

&lt;p&gt;Interface points that are functions are usually designed to be found by
argument-dependent lookup (ADL, see &lt;a href=&quot;/tips/49&quot;&gt;TotW 49&lt;/a&gt;). Operators and some
operator-like functions (notably &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swap()&lt;/code&gt;) are designed to be found by ADL. This
protocol only works reliably when the function is defined in a namespace
associated with the type being customized. The associated namespaces include
those of its base classes and class template parameters. A common mistake is to
place these functions in the global namespace. To illustrate the problem,
consider the following code in which &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;good(x)&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bad(x)&lt;/code&gt; functions are called
with identical syntax:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;library&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Letter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;good&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Letter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace library&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// bad is improperly placed in global namespace&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;library&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Letter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;good&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;library&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Letter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;good&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ok: &apos;library::good&apos; is found by ADL.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;bad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// oops: &apos;::bad&apos; is hidden by &apos;client::bad&apos;.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace client&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note the difference between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;library::good()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::bad()&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test()&lt;/code&gt;
function is relying on the absence of any function called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bad()&lt;/code&gt; in namespaces
enclosing the call site. The appearance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;client::bad()&lt;/code&gt; hides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::bad()&lt;/code&gt; from
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt; caller.  Meanwhile, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;good()&lt;/code&gt; function is found regardless of what
else exists in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test()&lt;/code&gt; function’s enclosing scope. The C++ name lookup
sequence will only yield a global if a name search from closer lexical scopes to
the call site fails to find any names.&lt;/p&gt;

&lt;p&gt;This is all very subtle, which is the point, really. It’s all much simpler if we
&lt;em&gt;default to defining functions alongside the data on which they operate&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;a-quick-note-on-in-class-friend-definitions&quot;&gt;A Quick Note on In-Class Friend Definitions&lt;/h2&gt;

&lt;p&gt;There’s a way to add non-member functions to a class from within the class
definition. Friend functions can be defined directly inside a class.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;library&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;explicit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;friend&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;friend&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;friend&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;swap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

 &lt;span class=&quot;nl&quot;&gt;private:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace library&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These friend functions have a special property of ONLY being visible through
ADL. They’re a little strange in that they are defined in the enclosing
namespace, but don’t appear in name lookup there. These in-class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;friend&lt;/code&gt;
definitions must have inlined bodies for this stealth property to kick in. See
&lt;a href=&quot;http://stackoverflow.com/questions/381164/friend-and-inline-method-whats-the-point&quot;&gt;“Friend
Definitions”&lt;/a&gt;
for more detail.&lt;/p&gt;

&lt;p&gt;Such functions will not hide global functions from fragile call sites in their
namespace or appear in diagnostic messages for unrelated calls to functions of
the same name. They get out of the way, essentially. They’re also very
convenient to define, easy to discover, and they have access to class internals.
Probably the biggest drawback is that they will not be found in cases where the
enclosing class is implicitly convertible from an argument type.&lt;/p&gt;

&lt;p&gt;Note that access (i.e. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;protected&lt;/code&gt;) has no effect on
friend functions, but it might be polite to place these in the public section
anyway, just so they’ll be more visible during perusal of the public API points.&lt;/p&gt;

&lt;h2 id=&quot;the-proper-source-location&quot;&gt;The Proper Source Location&lt;/h2&gt;

&lt;p&gt;To avoid violations of the one-definition rule (ODR), any customizations on a
type’s interface should appear where they can’t accidentally be defined multiple
times. This usually means they should be packaged with the type in the same
header. It’s not appropriate to add this sort of nonmember customization in a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*_test.cc&lt;/code&gt; file, or in a “utilities” header off to the side where it can be
overlooked. Force the compiler to see the customization and you will be more
likely to catch violations.&lt;/p&gt;

&lt;p&gt;A function overload (including operator overloads) intended as a nonmember
extension should be declared in a header that defines one of its arguments.&lt;/p&gt;

&lt;p&gt;The same goes for template specializations. Template specializations can be
packaged with the primary template definition, or packaged with the type on
which it’s being specialized. For partial specializations or with multiple
parameters it’s a judgment call. It’s usually pretty clear in practice which
site is better. The important thing is that the specialization should not be
hidden in client code: it should be as visible as the template and the
user-defined types involved.&lt;/p&gt;

&lt;h2 id=&quot;when-to-customize&quot;&gt;When to Customize&lt;/h2&gt;

&lt;p&gt;Don’t customize the behavior of a class in a test. This is dangerous and
unfortunately very common. Test source files are not immune to these dangers and
should follow the same rules as production code. We find a lot of inappropriate
operators in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*_test.cc&lt;/code&gt; files that are written with the intent to “get
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPECT_EQ&lt;/code&gt; to compile” or some other pragmatic concern. Unfortunately they are
still ODR risks (if not violations) and can make library maintenance
difficult. These rogue definitions might even stand in the way of library
maintenance as adding these operators upstream would break the very tests that
needed them and defined their own. For testing there are alternatives available
with a little more effort.&lt;/p&gt;

&lt;p&gt;Note that ADL works from the original declaration point for a type. Typedefs,
type aliases, alias templates, and using declarations do not create types and
have no impact on ADL. This can make it a little tricky to locate the proper
placement for customizations, but this cannot be helped, so just do it.&lt;/p&gt;

&lt;p&gt;Don’t augment the interface to types generated by protobufs. This is another
common pitfall. You may own the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.proto&lt;/code&gt; file, but that doesn’t mean you own the
C++ API it generates, and your augmentations could block improvements to the
generated C++ API. This is an ODR risk because you can’t ensure that your
augmentations are seen whenever the generated header is included.&lt;/p&gt;

&lt;p&gt;When defining &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;, it may be tempting to define behavior for templates like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;T&amp;gt;&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::pair&amp;lt;T,T&amp;gt;&lt;/code&gt;. Though your customizations may take
precedence and may do what you expect, you may be conflicting with other
expected customizations defined on the broader class template.&lt;/p&gt;

&lt;p&gt;It’s possible to define some customizations for raw pointers. It may be tempting
in some cases to supply these customizations for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T*&lt;/code&gt; along with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;. This is
not advised. It’s dangerous because the customization may conflict with the
expected ordinary behavior of pointers (e.g. the way they’re logged, swapped, or
compared). It’s best to leave pointers alone.&lt;/p&gt;

&lt;h2 id=&quot;what-to-do-when-youre-stuck&quot;&gt;What to Do When You’re Stuck&lt;/h2&gt;

&lt;p&gt;Following these guidelines can be challenging. Much of the inappropriate
overloading and specialization seen in C++ code is motivated by a small set of
root causes. Below is a partial listing with successful workarounds. If you
run into a library API that can’t be worked with, please send a note to the
owners to see about adding the appropriate customization hooks. Common APIs should
be usable without breaking these interface packaging guidelines.&lt;/p&gt;

&lt;h3 id=&quot;testing-a-type-with-expect_eq-etc&quot;&gt;Testing a Type with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPECT_EQ&lt;/code&gt;, etc.&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;temptation:&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPECT_EQ&lt;/code&gt; requires &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator==&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt; or
GoogleTest’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PrintTo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;workaround:&lt;/em&gt; Write lightweight gmock matchers with
&lt;a href=&quot;https://google.github.io/googletest/gmock_cook_book.html#writing-new-parameterized-matchers-quickly&quot;&gt;MATCHER_P&lt;/a&gt;
instead of relying exclusively on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPECT_EQ&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;workaround:&lt;/em&gt; Create &lt;em&gt;local&lt;/em&gt; (this is essential) wrapper types you DO truly own
and provide customizations on those, possibly using trivial inheritance as a
shortcut.&lt;/p&gt;

&lt;h3 id=&quot;using-t-as-a-container-key&quot;&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; as a Container Key&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;temptation:&lt;/em&gt; Container default functor types may rely on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator==&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hash&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;workaround:&lt;/em&gt; Use more custom comparators or custom hashers. Use more typedefs
for your associative container types to hide these details from client code.&lt;/p&gt;

&lt;h3 id=&quot;logging-containers-of-t&quot;&gt;Logging Containers of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;temptation:&lt;/em&gt; Defining &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt; overloads for standard containers.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;workaround:&lt;/em&gt; Don’t try to log the container directly.&lt;/p&gt;

&lt;h2 id=&quot;take-aways&quot;&gt;Take-Aways&lt;/h2&gt;

&lt;p&gt;A type’s behavior is not completely defined by its class definition. Non-member
definitions and specializations also contribute. You may need to keep reading
past that closing brace to really understand how a class works.&lt;/p&gt;

&lt;p&gt;Be aware of when and where it’s safe to add these customizations. Adding
inappropriate definitions may get your code to work for now, but you could be
adding fragility and maintenance blockers for other engineers down the line to
deal with.&lt;/p&gt;

</description>
          <pubDate>2017-11-16T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/99</link>
          <guid isPermaLink="true">https://abseil.io/tips/99</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #65: Putting Things in their Place</title>
          <description>&lt;p&gt;Originally posted as totw/65 on 2013-12-12&lt;/p&gt;

&lt;p&gt;By Hyrum Wright &lt;a href=&quot;mailto:hyrum@hyrumwright.org&quot;&gt;(hyrum@hyrumwright.org)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Let me ’splain. No, there is too much. Let me sum up.” –Inigo Montoya&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;C++11 added a new way to insert elements into standard containers: the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace()&lt;/code&gt; family of methods. These methods create an object directly within a
container, instead of creating a temporary object and then copying or moving
that object into the container. Avoiding these copies is more efficient for
almost all objects, and makes it easier to store move-only objects (such as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;) in standard containers.&lt;/p&gt;

&lt;h2 id=&quot;the-old-way-and-the-new-way&quot;&gt;The Old Way and the New Way&lt;/h2&gt;

&lt;p&gt;Let’s look at a simple example using vectors to contrast the two styles. The
first example uses pre-C++11 code:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using the older &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; method, two &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; objects are constructed: the
temporary argument and the object in the vector that is move-constructed from
the temporary.&lt;/p&gt;

&lt;p&gt;We can instead use C++11’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace_back()&lt;/code&gt; and only one object will be
constructed directly within the memory of the vector. Since the “emplace” family
of functions forward their arguments to the underlying object’s constructor, we
can provide the constructor arguments directly, obviating the need to create a
temporary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;addBetterFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;using-emplace-methods-for-move-only-operations&quot;&gt;Using Emplace Methods for Move-Only Operations&lt;/h2&gt;

&lt;p&gt;So far, we’ve looked at cases where emplace methods improve performance, but
they also make previously impossible code feasible, such as storing move-only
types like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; within containers. Consider this snippet:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;How would you insert values into this vector? One way would be to use
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; and construct the value directly within its argument:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This syntax works, but can be a bit unwieldy. Unfortunately, the traditional way
of getting around this confusion is fraught with complexity:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code compiles, but it leaves ownership of the raw pointer unclear until the
insertion. What’s worse, the vector now owns the object, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f2&lt;/code&gt; still remains
valid, and could accidentally be deleted later on. To an uninformed reader, this
ownership pattern can be confusing, particularly if construction and insertion
are not sequential events as above.&lt;/p&gt;

&lt;p&gt;Other solutions won’t even compile, because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unique_ptr&lt;/code&gt; isn’t copyable:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;// Does not compile!&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Does not compile!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using emplace methods can make it more intuitive to insert the object while it’s
being created. In other cases, if you need to move the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unique_ptr&lt;/code&gt; into the
vector, you can:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;By combining emplace with a standard iterator, you can also insert the object at
an arbitrary location in the vector:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That said, in practical terms we wouldn’t want to see these ways to construct a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unique_ptr&lt;/code&gt; - Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::make_unique&lt;/code&gt; (from C++14) or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::make_unique&lt;/code&gt; (if
you’re still on C++11).&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;We’ve used vector as an example in this Tip, but emplace methods are also
available for maps, lists and other STL containers. When combined with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unique_ptr&lt;/code&gt;, emplace allows for good encapsulation and makes the ownership
semantics of heap-allocated objects clear in ways that weren’t possible before.
Hopefully this has given you a feel for the power of the new emplace family of
container methods, and a desire to use them where appropriate in your own code.&lt;/p&gt;

</description>
          <pubDate>2017-11-16T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/65</link>
          <guid isPermaLink="true">https://abseil.io/tips/65</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #112: emplace vs. push_back</title>
          <description>&lt;p&gt;Originally posted as totw/112 on 2016-02-25&lt;/p&gt;

&lt;p&gt;By Geoff Romer &lt;a href=&quot;mailto:gromer@google.com&quot;&gt;(gromer@google.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Revised 2017-08-30&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“The less we use our power, the greater it will be.” — Thomas Jefferson&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you may already know (and if not, &lt;a href=&quot;/tips/65&quot;&gt;TotW 65&lt;/a&gt;), C++11 introduced a
powerful new way to insert items into containers: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace&lt;/code&gt; methods. These let
you construct an object in-place inside the container, using any of the object’s
constructors. That includes the move and copy constructors, so it turns out any
time you could use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insert&lt;/code&gt; method, you can use an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace&lt;/code&gt; method
instead, with no other changes:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;my_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// This is OK, so...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;my_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// This is also OK, and has the same result&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;my_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// Same here: any insert call can be&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;my_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// rewritten as an emplace call.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This raises an obvious question: which one should you use? Should we perhaps
just discard &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insert()&lt;/code&gt;, and use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace&lt;/code&gt; methods all the
time?&lt;/p&gt;

&lt;p&gt;Let me answer that question by asking another: what do these two lines of code
do?&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;vec1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first line is quite straightforward: it adds the number 1048576 to the end
of the vector. The second, however, is not so clear. Without knowing the type of
the vector, we don’t know what constructor it’s invoking, so we can’t really say
what that line is doing. For example, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vec2&lt;/code&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;int&amp;gt;&lt;/code&gt;, that
line merely adds 1048576 to the end, as with the first line, but if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vec2&lt;/code&gt; is a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;std::vector&amp;lt;int&amp;gt;&amp;gt;&lt;/code&gt;, that second line constructs a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; of over
a million elements, allocating several megabytes of memory in the process.&lt;/p&gt;

&lt;p&gt;Consequently, if you have a choice between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace_back()&lt;/code&gt;
with the same arguments, your code will tend to be more readable if you choose
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt;, because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; expresses your intent more specifically.
Choosing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; is also safer: suppose you have a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;std::vector&amp;lt;int&amp;gt;&amp;gt;&lt;/code&gt; and you want to append a number to the end of
the first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt;, but you accidentally forget the subscript. If you write
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_vec.push_back(2&amp;lt;&amp;lt;20)&lt;/code&gt;, you’ll get a compile error and you’ll quickly spot
the problem. On the other hand, if you write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_vec.emplace_back(2&amp;lt;&amp;lt;20)&lt;/code&gt;, the
code will compile, and you won’t notice any problems until run-time.&lt;/p&gt;

&lt;p&gt;Now, it’s true that when implicit conversions are involved, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace_back()&lt;/code&gt; can
be somewhat faster than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt;. For example, in the code that we began
with, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_vec.push_back(&quot;foo&quot;)&lt;/code&gt; constructs a temporary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; from the string
literal, and then moves that string into the container, whereas
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_vec.emplace_back(&quot;foo&quot;)&lt;/code&gt; just constructs the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; directly in the
container, avoiding the extra move. For more expensive types, this may be a
reason to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace_back()&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt;, despite the readability and
safety costs, but then again it may not. Very often the performance difference
just won’t matter. As always, the rule of thumb is that you should avoid
“optimizations” that make the code less safe or less clear, unless the
performance benefit is big enough to show up in your application benchmarks.&lt;/p&gt;

&lt;p&gt;So in general, if both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace_back()&lt;/code&gt; would work with the same
arguments, you should prefer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push_back()&lt;/code&gt;, and likewise for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insert()&lt;/code&gt; vs.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emplace()&lt;/code&gt;.&lt;/p&gt;

</description>
          <pubDate>2017-11-16T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/112</link>
          <guid isPermaLink="true">https://abseil.io/tips/112</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #49: Argument-Dependent Lookup</title>
          <description>&lt;p&gt;Originally posted as totw/49 on 2013-07-14&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“…whatever disappearing trail of its legalistic argle-bargle one chooses to
follow…” –Antonin Scalia, &lt;a href=&quot;http://www.supremecourt.gov/opinions/12pdf/12-307_6j37.pdf&quot;&gt;U.S. v Windsor dissenting opinion&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;p&gt;A function call expression such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;func(a,b,c)&lt;/code&gt;, in which the function is named
without the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::&lt;/code&gt; scope operator, is called unqualified. When C++ code refers to
a function by an unqualified name, the compiler performs a search for a matching
function declaration. What is surprising to some people (and different from
other languages) is that in addition to the caller’s lexical scope, the set of
search scopes is augmented by namespaces associated with the function argument
types. This additional lookup is called &lt;em&gt;Argument-Dependent Lookup&lt;/em&gt; (ADL). It’s
definitely happening in your code, so you’ll be much better off with a basic
understanding of how it works.&lt;/p&gt;

&lt;h2 id=&quot;name-lookup-basics&quot;&gt;Name Lookup Basics&lt;/h2&gt;

&lt;p&gt;A function call must be mapped to a single function definition by the compiler.
This matching is done in two independent serial processing stages. First, &lt;em&gt;name
lookup&lt;/em&gt; applies some scope searching rules to produce a set of overloads
matching the name of the function. Then &lt;em&gt;overload resolution&lt;/em&gt; takes those
overloads produced by that name lookup and tries to choose a best match for the
arguments given at the call site. Keep this distinction in mind. Name lookup
comes first, and it doesn’t try to make any determination as to whether a
function is a good match or not. It doesn’t even consider the argument count. It
just searches scopes for a function name. Overload resolution is a complex topic
in its own right, but it’s not our focus right now. Just know that it’s a
separate processing stage that gets its inputs from name lookup.&lt;/p&gt;

&lt;p&gt;When an unqualified function call is encountered, several independent search
sequences can occur for that function name, each attempting to match the name to
a set of overloads. The most obvious search is the outward search starting from
the lexical scope of the call site:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ok: finds b::func().&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// b::internal&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This name lookup has nothing to do with ADL yet (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;func()&lt;/code&gt; has no arguments). It
is simply a search outward from the site of the function call, proceeding
outward from local function scope (if applicable), to class scope, enclosing
class scope, and base classes (if applicable), then to namespace scope, and out
into enclosing namespaces, and finally the global &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::&lt;/code&gt; namespace.&lt;/p&gt;

&lt;p&gt;As name lookup progresses through a sequence of increasingly widening scopes,
the process stops as soon as any function with the target name is found, whether
or not that function’s arguments are compatible with the arguments supplied by
the call site. When a scope is encountered containing at least one function
declaration with the target name, the overloads in that scope become the result
of that name lookup.&lt;/p&gt;

&lt;p&gt;This is illustrated in the example below:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// b::func&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// b::internal::func&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deep&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// error: finds only b::internal::func(int).&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// b::internal::deep&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// b::internal&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s tempting but incorrect to think a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;func(s)&lt;/code&gt; expression will overlook the
obviously bad match of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b::internal::func(int)&lt;/code&gt;, and continue looking to the
next outward enclosing scope to find &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b::func(const string&amp;amp;)&lt;/code&gt;. However, name
lookup doesn’t consider argument types. It finds something called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;func&lt;/code&gt; and
stops in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b::internal&lt;/code&gt;, leaving the evaluation of “obviously bad” to the
overload resolution phase. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b::func(const string&amp;amp;)&lt;/code&gt; function is never even
seen by overload resolution.&lt;/p&gt;

&lt;p&gt;An important implication of the scoped search order is that overloads in a scope
appearing earlier in the search order will hide overloads from later scopes.&lt;/p&gt;

&lt;h2 id=&quot;argument-dependent-lookup-adl&quot;&gt;Argument-Dependent Lookup (ADL)&lt;/h2&gt;

&lt;p&gt;If a function call passes arguments, a few more parallel name lookups are
launched. These extra lookups consider each associated namespace of each of the
function call’s arguments. Unlike lexical scope name lookup, these argument-
dependent lookups do not proceed to enclosing scopes.&lt;/p&gt;

&lt;p&gt;Results of lexical scope name lookup and all ADLs are merged together, to form 
the final set of function overloads.&lt;/p&gt;

&lt;h2 id=&quot;the-simple-case&quot;&gt;The Simple Case&lt;/h2&gt;

&lt;p&gt;Consider the following code:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aspace&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// found by ADL name lookup on &apos;a&apos;.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace aspace&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bspace&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// found by lexical scope name lookup&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aspace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// aspace::func(const aspace::A&amp;amp;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace bspace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Two name lookups are launched to resolve the call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;func(a)&lt;/code&gt;. The lexical
scope name lookup starts in the local function scope of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bspace::test()&lt;/code&gt;. It
finds no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;func&lt;/code&gt; there and proceeds to the scope of namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bspace&lt;/code&gt;, in which
it finds &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;func(int)&lt;/code&gt; and stops. The other name lookup, which is due to ADL,
starts in the namespace associated with the argument &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt;. In this case, that’s
only namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aspace&lt;/code&gt;. That lookup finds &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aspace::func(const aspace::A&amp;amp;)&lt;/code&gt; and
stops. Overload resolution therefore receives two candidates. These are
‘bspace::func(int)’ from lexical name lookup, and ‘aspace::func(const
aspace::A&amp;amp;)’ from the single ADL lookup. In overload resolution, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;func(a)&lt;/code&gt;
call resolves to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aspace::func(const aspace::A&amp;amp;)&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bspace::func(int)&lt;/code&gt;
overload is not a good match for the argument type and so it is rejected by
overload resolution.&lt;/p&gt;

&lt;p&gt;The lexical name search and each of the additional ADL-triggered name searches
can be considered to occur in parallel, with each returning a set of candidate
function overloads. The results of all such searches are thrown in a bag and
they compete via overload resolution to determine the best match. If there’s a
tie for best match, the compiler issues an ambiguity error; “There can be only
one.” If no overload is a good match, that’s an error too. So more precisely,
“there must be exactly one”, which doesn’t sound as cool in a movie trailer.&lt;/p&gt;

&lt;h2 id=&quot;type-associated-namespaces&quot;&gt;Type-Associated Namespaces&lt;/h2&gt;

&lt;p&gt;The previous example was the simple case, but a more sophisticated type can have
many namespaces associated with it. The set of namespaces associated with a type
includes any namespace of any type that appears as a part of the argument type’s
full name, including its template parameter types. It also includes the
namespaces of direct and indirect base classes. For example, a single argument
that expands to the type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a::A&amp;lt;b::B, c::internal::C*&amp;gt;&lt;/code&gt; will produce searches
beginning in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c::internal&lt;/code&gt; namespaces (and any other namespaces
associated with the constituent types &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a::A&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b::B&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c::internal::C&lt;/code&gt;), each
looking for the called function name. The following example shows a few of these
effects:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aspace&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AGeneric&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;find_me&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace aspace&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bspace&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aspace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AliasForA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aspace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BGeneric&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ok: base class namespace searched.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ok: template parameter namespace searched.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;find_me&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BGeneric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aspace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ok: template namespace searched.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;find_me&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aspace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AGeneric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace bspace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;tips&quot;&gt;Tips&lt;/h2&gt;

&lt;p&gt;With the fundamental name lookup mechanism fresh in your mind, consider the
following tips which may help you when you are working with real C++ code.&lt;/p&gt;

&lt;h2 id=&quot;type-aliases&quot;&gt;Type Aliases&lt;/h2&gt;

&lt;p&gt;Sometimes determining the set of namespaces associated with a type will take a
bit of detective work. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typedef&lt;/code&gt; and using declarations can introduce aliases
for a type. In those cases the aliases are fully resolved and expanded to their
source types before the list of namespaces to search are chosen. This is one way
in which &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typedef&lt;/code&gt; and using declarations can be a bit misleading, because they
can lead you to make incorrect predictions about which namespaces will be
searched by ADL. This is demonstrated below:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cspace&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ok: note that this searches aspace, not bspace.&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bspace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AliasForA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace cspace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;caveat-iterator&quot;&gt;Caveat Iterator&lt;/h2&gt;

&lt;p&gt;Be careful with iterators. You don’t really know with what namespaces they are
associated, so don’t rely on ADL for resolving function calls involving
iterators. They might just be pointers to the elements, or they might be in some
namespace private to the implementation that has nothing to do with the
container’s namespace.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// maybe this compiles, maybe not!&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// namespace d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above code has a dependency on whether &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&amp;lt;int&amp;gt;::iterator&lt;/code&gt; is
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int*&lt;/code&gt; (which is possible) or some type in a namespace that has a count overload
(like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::count()&lt;/code&gt;). It’s possible that this will work on some platforms and not
others, or that it will work in debug builds with instrumented iterators, but
not in optimized builds. It’s better to just qualify the function name. If you
want to call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::count()&lt;/code&gt;, spell it that way.&lt;/p&gt;

&lt;h2 id=&quot;overloaded-operators&quot;&gt;Overloaded Operators&lt;/h2&gt;

&lt;p&gt;An operator (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt;) can be thought of as a kind of function name,
e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator+(a,b)&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;(a,b)&lt;/code&gt;, and are also unqualified. One of the
most important uses of ADL is the search for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt; used during logging.
Usually we see something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::cout &amp;lt;&amp;lt; obj;&lt;/code&gt; for some &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;obj&lt;/code&gt;, let’s say of
type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O::Obj&lt;/code&gt;. This statement is like an unqualified function call of the form
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;(std::ostream&amp;amp;, const O::Obj&amp;amp;)&lt;/code&gt;, which will find overloads in the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std&lt;/code&gt; namespace from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::ostream&lt;/code&gt; parameter, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O&lt;/code&gt; namespace from the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O::Obj&lt;/code&gt; parameter, and of course any overloads picked up from the lexical scope
search from the call site.&lt;/p&gt;

&lt;p&gt;It’s important to place such operators in the same namespace as the user-defined
type they’re meant to operate upon: in this case within namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O&lt;/code&gt;. If the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt; is placed in an outer namespace like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::&lt;/code&gt; (the global namespace),
that operator will work for a while until someone quite innocently places an
unrelated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt; in namespace ‘O’ for some other type. It takes a bit of
discipline but saves a lot of confusion later to follow the simple rule of
defining all operators and other associated nonmember functions next to the
type’s definition in the same namespace.&lt;/p&gt;

&lt;h2 id=&quot;fundamental-types&quot;&gt;Fundamental Types&lt;/h2&gt;

&lt;p&gt;Note that the fundamental types (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;double&lt;/code&gt;, etc) are not associated
with the global namespace. They are associated with no namespace. They do not
contribute any namespaces to ADL. Pointer and array types are associated with
their pointee or element types.&lt;/p&gt;

&lt;h2 id=&quot;refactoring-gotchas&quot;&gt;Refactoring Gotchas&lt;/h2&gt;

&lt;p&gt;Refactorings that change the types of arguments to an unqualified function call
can affect which, if any, overloads are considered. Just moving a type into a
namespace and leaving behind a typedef in the old namespace for compatibility
doesn’t help, and really just makes the problem harder to diagnose. Be careful
when moving types to new namespaces.&lt;/p&gt;

&lt;p&gt;Similarly, moving a function to a new namespace and leaving behind a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using&lt;/code&gt;
declaration might mean that unqualified calls won’t find it anymore. Sadly, they
might still compile by finding a different function you didn’t intend them to
find. Be careful when moving functions to new namespaces.&lt;/p&gt;

&lt;h2 id=&quot;final-thought&quot;&gt;Final Thought&lt;/h2&gt;

&lt;p&gt;Relatively few programmers understand the exact rules and corner cases involved
with function lookups. The language spec contains 13 pages of rules about what
exactly goes into a name search, including special cases, details about friend
functions, and enclosing class scopes to keep your head spinning for years.
Despite all this complexity, if you keep the basic idea of parallel name
searches in mind, you’ll be on solid footing for understanding how your function
calls and operators are resolving. You will now be able to see how seemingly
remote declarations end up being chosen when you invoke functions or operators.
And you’ll be a little better able to diagnose puzzling build errors like
ambiguities or name-hiding effects when they happen.&lt;/p&gt;

</description>
          <pubDate>2017-11-09T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/49</link>
          <guid isPermaLink="true">https://abseil.io/tips/49</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #135: Test the Contract, not the Implementation</title>
          <description>&lt;p&gt;Originally posted as TotW #135 on June 5, 2017&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:jdennett@google.com&quot;&gt;James Dennett&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-04-06&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/135&quot;&gt;abseil.io/tips/135&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“If you have one true friend you have more than your share.” — Thomas Fuller&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;C++ has a somewhat elaborate access control mechanism using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;protected&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;friend&lt;/code&gt;. Test code has its own rules of etiquette
for using those facilities, and GoogleTest augments them with its own
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FRIEND_TEST&lt;/code&gt; macro. Use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FRIEND_TEST&lt;/code&gt; should be a last resort, not a
preferred choice.&lt;/p&gt;

&lt;h2 id=&quot;test-the-contract&quot;&gt;Test the Contract&lt;/h2&gt;

&lt;p&gt;We write tests to find bugs in the implementation of a component’s contract, or
to give us sufficient confidence that there are no such bugs. When using
test-driven development (TDD), we also write tests to help us to design that
contract. Tests that depend on unspecified aspects of a component are brittle,
and prone to reporting failures even when the production code is working
correctly.&lt;/p&gt;

&lt;p&gt;Prefer to test via the public interface of a component. More generally, tests
should verify the contract of a component and, just as with any other client,
should not make assumptions beyond what’s guaranteed.&lt;/p&gt;

&lt;h2 id=&quot;techniques-for-providing-access-from-tests&quot;&gt;Techniques for Providing Access from Tests&lt;/h2&gt;

&lt;p&gt;A number of techniques can be used to allow test code the access needed to do
its job. Some are enumerated here, roughly arranged from best to worst.&lt;/p&gt;

&lt;h3 id=&quot;augmenting-the-public-api-for-tests&quot;&gt;Augmenting the Public API for Tests&lt;/h3&gt;

&lt;p&gt;Sometimes it’s hard to get sufficient coverage when testing via a minimal
interface. If your component is implementing a very narrow interface specified
by a base class (e.g., one with only a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessItem&lt;/code&gt; virtual function) and it’s
impractical to gain sufficient confidence from a test that uses only that
interface, consider creating a new, testable component containing the
implementation details. Then the class containing the virtual function can be so
simple that it needs only minimal testing. BUILD visibility can be used to
restrict use of your implementation class (if needed and if your build system
supports it).&lt;/p&gt;

&lt;p&gt;If a test depends on just one or two private functions, consider making those
functions part of the public interface. This isn’t so bad: you’ll need them to
have a clearly documented interface anyway, and other clients (not just the
test) might find them useful. If, after consideration, you decide that a
function really is only for tests, then it should be documented as such, and
maybe named with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ForTesting&lt;/code&gt; suffix.&lt;/p&gt;

&lt;h3 id=&quot;using-peers-to-avoid-exposing-implementation&quot;&gt;Using Peers to Avoid Exposing Implementation&lt;/h3&gt;

&lt;p&gt;If the test still needs to have access to private implementation details, create
a &lt;em&gt;test peer&lt;/em&gt; (sometimes called a &lt;em&gt;test spouse&lt;/em&gt;). A test peer is a friend class
of the class under test, often defined in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_test.cc&lt;/code&gt; file (though some
prefer to define it in the same file as the class that befriends it), and used
to provide controlled access to the class under test to the test code. The test
peer won’t be able to live in an anonymous namespace as its exact name needs to
match the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;friend&lt;/code&gt; declaration, but the rest of the test code can be in an
anonymous namespace as usual. The name of a test peer class typically ends in
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Peer&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;avoid-using-friend_test&quot;&gt;(Avoid) Using &lt;code&gt;FRIEND_TEST&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;While common in older code, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FRIEND_TEST&lt;/code&gt; should not be used in new code. It
introduces reverse coupling, making the production header file depend on details
of the associated unit test. It forces the tests to move out of the anonymous
namespace. Every &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FRIEND_TEST&lt;/code&gt; grants a test function unrestricted access to the
class under test; in long test functions it can be hard to see where the test
modifies the state of the class under test. It requires use of an unusual header
file provided by &lt;a href=&quot;https://github.com/google/googletest&quot;&gt;GoogleTest&lt;/a&gt; for
inclusion in production code, whereas almost all of GoogleTest is intended only
for use in tests. And finally it scales badly, requiring new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FRIEND_TEST&lt;/code&gt; uses
to be added to the production header when new tests are added. In practice this
often results in header files having lengthy blocks of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FRIEND_TEST&lt;/code&gt; lines.&lt;/p&gt;

&lt;h3 id=&quot;dont-make-the-entire-test-fixture-a-friend&quot;&gt;(Don’t) Make the Entire Test Fixture a &lt;code&gt;friend&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Making the entire test fixture a friend of the class under test (with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;friend
class MyClassTest;&lt;/code&gt;) is strongly discouraged. Compared to the options above, it
allows the entire test fixture (but not the tests themselves, which are
sub-classes of the fixture) unrestricted and unannotated access to every member
of the class under test, meaning that readers of the test code have no visual
clue of when the test is breaking encapsulation. It also forces the test fixture
to be outside of the anonymous namespace. Compared to a friend fixture, a test
peer makes the code much more self-documenting for readers, and costs just a
little extra work for code authors.&lt;/p&gt;

&lt;h2 id=&quot;summary-of-recommendations&quot;&gt;Summary of Recommendations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Prefer to test the client interface of a component, and keep tests
independent of private implementation details.&lt;/li&gt;
  &lt;li&gt;Factor out a testable, possibly test-only subcomponent if the client
interface isn’t sufficient to thoroughly exercise the unit under test.&lt;/li&gt;
  &lt;li&gt;Sometimes it’s reasonable to add to the public interface in order to make a
component testable.&lt;/li&gt;
  &lt;li&gt;If necessary, access private members from tests using a &lt;em&gt;test peer&lt;/em&gt; rather
than using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FRIEND_TEST&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Do not befriend an entire test fixture. Use one of the more targeted
approaches described above.&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2017-11-09T00:00:00-05:00</pubDate>
          <link>https://abseil.io/tips/135</link>
          <guid isPermaLink="true">https://abseil.io/tips/135</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #107: Reference Lifetime Extension</title>
          <description>&lt;p&gt;Originally posted as totw/107 on 2015-12-10&lt;/p&gt;

&lt;p&gt;By Titus Winters (titus@google.com)&lt;/p&gt;

&lt;p&gt;There have been some reports of confusion about references and lifetimes after
&lt;a href=&quot;/tips/101&quot;&gt;TotW 101&lt;/a&gt;, so in this Tip we’ll dive more into the question, “When does
reference lifetime extension apply?”&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Is this safe/legal?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In short, lifetimes of temporaries (referents) will be extended &lt;em&gt;if and only if&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A local &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt; (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&amp;amp;&amp;amp;&lt;/code&gt;, although Google style generally ignores that)
is initialized to the result of an expression (usually a function call)
returning a temporary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; &lt;em&gt;or&lt;/em&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; subobject of a temporary (e.g. a
struct containing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The standard-ese may be a little tricky to unpack, so lets discuss some of the
edge cases to clarify:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;This doesn’t work when assigning to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&amp;amp;&lt;/code&gt;, it must be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt;. (It’s a
compilation error.)&lt;/li&gt;
  &lt;li&gt;This doesn’t work if there is a (non-polymorphic) type conversion at
play. For instance, assigning to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const absl::string_view&amp;amp;&lt;/code&gt; from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;
does not extend the lifetime of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;. (You also don’t want &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
absl::string_view&amp;amp;&lt;/code&gt; in the first place, but that’s a separate issue).&lt;/li&gt;
  &lt;li&gt;This doesn’t work when you’re getting the subobject indirectly: the compiler
doesn’t look through function calls (getters or the like). The subobject
form only works when you’re directly assigning from a public member variable
subobject of the temporary. (So it doesn’t come up often because we don’t
have many expressions that return temporary structs.)&lt;/li&gt;
  &lt;li&gt;The case where type conversion is allowed is when assigning to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&amp;amp;&lt;/code&gt; from a
temporary of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U&lt;/code&gt; when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is a parent class of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U&lt;/code&gt;. Please don’t do that:
it’s even more confusing for readers than the other cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the lifetime of the temporary is extended, it will last until the reference
goes out of scope. If the lifetime of the temporary isn’t extended in the above
fashion, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; being referred to is destroyed at the end of the statement
(when we get to the next &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;As per &lt;a href=&quot;/tips/101&quot;&gt;TotW 101&lt;/a&gt; you probably shouldn’t rely on lifetime extension
in the explicit case of reference-initialization: it’s not gaining you much/any
performance, and it is subtle, fragile, and prone to cause extra work for your
reviewers and future maintainers.&lt;/p&gt;

&lt;p&gt;There are subtle cases where lifetime extension &lt;em&gt;is&lt;/em&gt; happening and is necessary
and beneficial (like ranged-for over a temporary container), but again, the
extension is only for the result of the temporary expression, not any
sub-expressions. For instance, these work:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// lifetime extension on the vector is important&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Return string_views of size 1 for each char in this string.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Explode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Lifetime extension kicks in on the vector, but *not* on the temporary string!&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string_view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Explode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StrCat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;oo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ps&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// WRONG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This does not work:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;MyProto&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetProto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Lifetime extension *doesn&apos;t work* here: sub_protos (a repeated field)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// is destroyed by MyProto going out of scope, and the lifetime extension rules&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// don&apos;t kick in here to magically lifetime extend the MyProto returned by&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// GetProto().  The sub-object lifetime extension only works for simple&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// is-a-member-of relationships: the compiler doesn&apos;t see that sub_protos()&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// itself returning a reference to an sub-object of the outer temporary.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SubProto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetProto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sub_protos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// WRONG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
          <pubDate>2017-11-02T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/107</link>
          <guid isPermaLink="true">https://abseil.io/tips/107</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #101: Return Values, References, and Lifetimes</title>
          <description>&lt;p&gt;Originally posted as totw/101 on 2015-07-29&lt;/p&gt;

&lt;p&gt;By Titus Winters (titus@google.com)&lt;/p&gt;

&lt;p&gt;Consider the following code snippet:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Consumer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;consumer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Consumer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In particular, I’d like to draw your attention to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt;. Is it appropriate?
What should we check? What can go wrong? I find a decent number of C++
programmers that aren’t entirely clear on references, but do generally know that
they “avoid making copies.” As with most issues in C++, it’s more complicated
than that.&lt;/p&gt;

&lt;h2 id=&quot;case-by-case-what-is-being-returned-and-how-is-it-being-stored&quot;&gt;Case by Case: What is Being Returned and How is it Being Stored?&lt;/h2&gt;

&lt;p&gt;There are two (maybe three) important questions here:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;What type is returned (in this example, by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetName()&lt;/code&gt;)?&lt;/li&gt;
  &lt;li&gt;What type are we storing into/initializing (in this example, what is the
type of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;)?&lt;/li&gt;
  &lt;li&gt;If we are returning a reference, does the object being returned by reference
have any lifetime limitations?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We’ll continue with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; as our example type, but the same arguments
generalize for most non-trivial value types.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;, initializing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;: This is usually
&lt;a href=&quot;https://en.wikipedia.org/wiki/Return_value_optimization&quot;&gt;RVO&lt;/a&gt; and is
guaranteed to be, at worst, a move for modern types (See &lt;a href=&quot;/tips/77&quot;&gt;TotW
77&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&amp;amp;&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string&amp;amp;&lt;/code&gt;, initializing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;: This is a
copy (there must be some long-living object which we are returning a
reference to, so once we initialize a new string there are two names for
that data, hence a copy. See &lt;a href=&quot;/tips/77&quot;&gt;TotW 77&lt;/a&gt;). Sometimes this is
valuable, like if you need your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; to outlast the lifetime guarantees
provided by the function.&lt;/li&gt;
  &lt;li&gt;Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;, initializing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&amp;amp;&lt;/code&gt;: This won’t compile, as you
cannot bind a reference to a temporary.&lt;/li&gt;
  &lt;li&gt;Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string&amp;amp;&lt;/code&gt;, initializing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&amp;amp;&lt;/code&gt;: This won’t compile, as
you’ve dropped the const inappropriately.&lt;/li&gt;
  &lt;li&gt;Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string&amp;amp;&lt;/code&gt;, initializing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string&amp;amp;&lt;/code&gt;: This is no cost
(you’re effectively returning just a pointer). However, you have inherited
any existing lifetime restrictions: how long is that reference good for?
Most accessor methods that return a reference are returning a member - at
most, the reference can be valid for the life of the containing object.&lt;/li&gt;
  &lt;li&gt;Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&amp;amp;&lt;/code&gt;, initializing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&amp;amp;&lt;/code&gt;: This is the same as #5, but
with the additional caveat: the returned reference is non-const, so any
modifications to your reference will be reflected in the source.&lt;/li&gt;
  &lt;li&gt;Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&amp;amp;&lt;/code&gt;, initializing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string&amp;amp;&lt;/code&gt;: The same as #5.&lt;/li&gt;
  &lt;li&gt;Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;, initializing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string&amp;amp;&lt;/code&gt;: You’d think, given #3,
that this wouldn’t work. However, the language has special-case support for
this: if you initialize a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const T&amp;amp;&lt;/code&gt; with a temporary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;, that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; (in this
case &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;) is not destroyed until the &lt;em&gt;reference&lt;/em&gt; goes out of scope (in
the common case of automatic or static variables).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Scenario #8 is what allows most reflexive use of references (that is “Oh, I
don’t want to copy so I’ll just assign into a reference” without necessarily
thinking about what is being returned). However, because of #1, it’s also
not really doing anything for you: there probably wouldn’t have been a copy in
the first place. Further, now readers of your code have to contend with your
local variable being of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string&amp;amp;&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;, and thus worry
about whether the underlying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; has gone out of scope or changed.&lt;/p&gt;

&lt;p&gt;Put another way: when code reviewing the original snippet, I have to worry
about:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetName()&lt;/code&gt; returning by value or by reference?&lt;/li&gt;
  &lt;li&gt;Does the constructor for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Consumer&lt;/code&gt; take &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const string&amp;amp;&lt;/code&gt; or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;?&lt;/li&gt;
  &lt;li&gt;Does the constructor have any lifetime requirements placed on that
parameter? (If it isn’t just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, if you just declare &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; in the first place, it’s
generally no less efficient (because of RVO and move semantics), and at least as
likely to be safe with respect to object lifetimes.&lt;/p&gt;

&lt;p&gt;Additionally, if there is an object lifetime issue, it’s often simpler to spot
when storing as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;: rather than looking at the interplay between the
lifetime promise of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetName()&lt;/code&gt;’s returned reference and the lifetime
requirements of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetName()&lt;/code&gt;, having your own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; means only having to look
at the local code and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetName()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All of which is to say: avoiding copies is fine, so long as you’re not making
things more complicated. Making code more complicated when there wasn’t a copy
in the first place is not a good tradeoff.&lt;/p&gt;
</description>
          <pubDate>2017-11-02T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/101</link>
          <guid isPermaLink="true">https://abseil.io/tips/101</guid>
        </item>
      
    
      
        <item>
          <title>CppCon 2017: &apos;A Type, by Any Other Name&apos;</title>
          <description>&lt;h3 id=&quot;jon-cohen-a-type-by-any-other-name&quot;&gt;Jon Cohen: “A Type, by Any Other Name”&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:shreck@google.com&quot;&gt;Tom Manshreck&lt;/a&gt;, Abseil Tech Writer&lt;/p&gt;

&lt;p&gt;It’s Halloween, so find out what spooky things (like ADL) lurk when
doing a major renaming/refactoring on a codebase as large as Google’s.
Oooh, scary, kids!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ely_hVVZjEU&quot; target=&quot;_blank&quot;&gt;
&lt;img src=&quot;/img/cppcon-renaming.png&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;
</description>
          <pubDate>2017-10-31T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20171031-cppcon-renaming</link>
          <guid isPermaLink="true">https://abseil.io/blog/20171031-cppcon-renaming</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #94: Callsite Readability and bool Parameters</title>
          <description>&lt;p&gt;Originally posted as totw/94 on 2015-04-27&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Geoff Romer &lt;a href=&quot;mailto:gromer@google.com&quot;&gt;(gromer@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Revised 2017-10-25&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Of the many forms of false culture, a premature converse with abstractions is
perhaps the most likely to prove fatal to the growth of … vigour of
intellect.” — George Boole.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Suppose you come across code like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ParseCommandLineFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Can you tell what this code does, and in particular what the last argument
means? Now suppose you’ve come across this function before, and you know that
the last argument has to do with whether command-line flags are left in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;argv&lt;/code&gt;
after the call. Can you tell which is true and which is false?&lt;/p&gt;

&lt;p&gt;Of course you don’t know, because this is hypothetical, but even in real code,
we have better things to do with our brains than memorize the meaning of every
function parameter, and better things to do with our time than go look up the
documentation for every function call we encounter. We have to be able to make
pretty good guesses about what function calls mean, just from looking at the
callsite.&lt;/p&gt;

&lt;p&gt;Well-chosen function names are the key to making function calls readable, but
they’re often not enough. We usually need the arguments themselves to give us
some clues about what they mean. For example, you might not know what to make of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view s(x, y);&lt;/code&gt; if you’d never seen &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; before, but
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view s(my_str.data(), my_str.size());&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view
s(&quot;foo&quot;);&lt;/code&gt; are much clearer. The trouble with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt; parameters is that the
argument at the callsite is very often a literal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;, and that
gives the reader no contextual cues about the meaning of the parameter, as we
saw in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ParseCommandLineFlags()&lt;/code&gt; example. This problem is compounded if
there’s more than one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt; parameter, because now you have the additional
problem of figuring out which parameter is which.&lt;/p&gt;

&lt;p&gt;So how can we fix code like that example? One (bad) possibility is to do
something like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ParseCommandLineFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* preserve flags */&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The drawbacks of this approach are evident: it’s not clear if that comment is
describing the meaning of the parameter or the effect of the argument. In other
words, is it saying that we’re preserving the flags, or is it saying that it’s
false that we’re preserving the flags? Even if the comment manages to make that
clear, there’s still a risk that the comment will get out of sync with the code.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;better&lt;/em&gt; approach is to specify the name of the parameter in the comment:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ParseCommandLineFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*remove_flags=*/&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is much clearer, and much less likely to fall out of sync with the code.
&lt;a href=&quot;https://clang.llvm.org/extra/clang-tidy/checks/bugprone-argument-comment.html&quot;&gt;Clang-tidy will even
check&lt;/a&gt;
that the comment has the correct parameter name. A less ambiguous but longer
variant is to use an explanatory variable:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove_flags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ParseCommandLineFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove_flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, explanatory variable names are not checked by the compiler, and so they
may be erroneous. This is a particular problem when you have multiple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt;
parameters, which might be transposed by the caller.&lt;/p&gt;

&lt;p&gt;All these approaches also rely on programmers to consistently remember to add
these comments or variables, and to do so correctly (although clang-tidy will
check the correctness of parameter-name comments).&lt;/p&gt;

&lt;p&gt;In many cases, the best solution is to avoid using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt; parameters in the
first place, and use an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum&lt;/code&gt; instead. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ParseCommandLineFlags()&lt;/code&gt;
could be declared like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ShouldRemoveFlags&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kDontRemoveFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kRemoveFlags&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParseCommandLineFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;***&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ShouldRemoveFlags&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove_flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;so that the call could look like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ParseCommandLineFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kDontRemoveFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also use an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum class&lt;/code&gt;, as described in &lt;a href=&quot;/tips/86&quot;&gt;TotW 86&lt;/a&gt;, but
in that case you’d want to use a slightly different naming convention, e.g.:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShouldRemoveFlags&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kNo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kYes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ParseCommandLineFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ShouldRemoveFlags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kNo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Obviously, this approach has to be implemented when the function is defined; you
can’t really opt into it at the callsite (you can fake it, but for little
benefit). So when you’re defining a function, particularly if it’s going to be
widely used, the onus is on you to think carefully about how the callsites will
look, and in particular to be very skeptical of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt; parameters.&lt;/p&gt;

</description>
          <pubDate>2017-10-26T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/94</link>
          <guid isPermaLink="true">https://abseil.io/tips/94</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #86: Enumerating with Class</title>
          <description>&lt;p&gt;Originally posted as totw/86 on 2015-01-05&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Bradley White &lt;a href=&quot;mailto:bww@google.com&quot;&gt;(bww@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Show class, … and display character.” - Bear Bryant.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An enumeration, or simply an &lt;strong&gt;enum&lt;/strong&gt;, is a type that can hold one of a
specified set of integers. Some values of this set can be given names, and are
called the enumerators.&lt;/p&gt;

&lt;h2 id=&quot;unscoped-enumerations&quot;&gt;Unscoped Enumerations&lt;/h2&gt;

&lt;p&gt;This concept will be familiar to C++ programmers, but prior to C++11
enumerations had two significant shortcomings: the enumeration names were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;in the same scope as the enum type, and&lt;/li&gt;
  &lt;li&gt;implicitly convertible to values of some integer type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, with C++98 …&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CursorDirection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kRight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kDown&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CursorDirection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// OK: enumerator in scope&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kRight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;// OK: enumerator converts to int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;but, …&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// error: redeclarations of kLeft and kRight&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PoliticalOrientation&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kCenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kRight&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;C++11 modified the behavior of unscoped enums in one way: the enumerators are
now local to the enum, but continue to be exported into the enum’s scope for
backwards compatibility.&lt;/p&gt;

&lt;p&gt;So, with C++11 …&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;CursorDirection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CursorDirection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// OK in C++11&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CursorDirection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kRight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;// OK: still converts to int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;but the declaration of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PoliticalOrientation&lt;/code&gt; would still elicit errors.&lt;/p&gt;

&lt;h2 id=&quot;scoped-enumerations&quot;&gt;Scoped Enumerations&lt;/h2&gt;

&lt;p&gt;The implicit conversion to integer has been observed to be a common source of
bugs, while the namespace pollution caused by having the enumerators in the same
scope as the enum causes problems in large, multi-library projects. To address
both these concerns, C++11 introduced a new concept: the &lt;strong&gt;scoped enum&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a scoped enum, introduced by the keywords &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum class&lt;/code&gt;, the enumerators are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;only local to the enum (they are not exported into the enum’s scope), and&lt;/li&gt;
  &lt;li&gt;not implicitly convertible to integer types.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, (note the additional class keyword) …&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CursorDirection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kRight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kDown&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CursorDirection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;                    &lt;span class=&quot;c1&quot;&gt;// error: kLeft not in this scope&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CursorDirection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CursorDirection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// OK&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CursorDirection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kRight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;              &lt;span class=&quot;c1&quot;&gt;// error: no conversion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and, …&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// OK: kLeft and kRight are local to each scoped enum&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PoliticalOrientation&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kCenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kRight&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These simple changes eliminate the problems with plain enumerations, so enum
class should be preferred in all new code.&lt;/p&gt;

&lt;p&gt;Using a scoped enum does mean that you’ll have to explicitly cast to an integer
type should you still want such a conversion (e.g., when logging an enumeration
value, or when using bitwise operations on flag-like enumerators). Hashing with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::hash&lt;/code&gt; will continue to work though (e.g.,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unordered_map&amp;lt;CursorDirection, int&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;underlying-enumeration-types&quot;&gt;Underlying Enumeration Types&lt;/h2&gt;

&lt;p&gt;C++11 also introduced the ability to specify the underlying type for both
varieties of enumeration. Previously the underlying integer type of an enum was
determined by examining the sign and magnitude of the enumerators, but now we
can be explicit. For example, …&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Use &quot;int&quot; as the underlying type for CursorDirection&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CursorDirection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kRight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kDown&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Because this enumerator range is small, and if we wished to avoid wasting space
when storing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CursorDirection&lt;/code&gt; values, we could specify &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;char&lt;/code&gt; instead.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Use &quot;char&quot; as the underlying type for CursorDirection&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CursorDirection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kRight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kDown&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The compiler will issue an error if an enumerator value exceeds the range of the
underlying type.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Prefer using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enum class&lt;/code&gt; in new code. You’ll reduce namespace pollution, and
you may avoid bugs in implicit conversions.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Parting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kSoLong&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kFarewell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kAufWiedersehen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kAdieu&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
          <pubDate>2017-10-26T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/86</link>
          <guid isPermaLink="true">https://abseil.io/tips/86</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #64: Raw String Literals</title>
          <description>&lt;p&gt;Originally published as totw/64 on 2013-12-09&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Titus Winters &lt;a href=&quot;mailto:titus@google.com&quot;&gt;(titus@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2017-10-23&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/64&quot;&gt;abseil.io/tips/64&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;(?:\&quot;(?:\\\\\&quot;|[^\&quot;])*\&quot;|&apos;(?:\\\\&apos;|[^&apos;])*&apos;)&quot;;&lt;/code&gt; — A cat walking over the
keyboard . . . or maybe what the fox says . . . no, actually just a highly-
escaped regexp found in real C++ code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Odds are you’ve had trouble getting your regular expression understood properly
in C++ due to escaping issues. Similarly, you’ve probably been annoyed with
preserving quotes and newlines when embedding a text version of Protobuf or JSON
data into your unittests. When you have to use significant escaping (or worse,
multi-layer escaping), code clarity drops precipitously.&lt;/p&gt;

&lt;p&gt;Luckily, there’s a new C++11 feature that removes this need for escaping: raw
string literals.&lt;/p&gt;

&lt;h2 id=&quot;the-raw-string-literal-format&quot;&gt;The Raw String Literal Format&lt;/h2&gt;

&lt;p&gt;A raw string literal has the following special syntax:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;R&quot;tag(whatever you want to say)tag&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tag&lt;/code&gt; is a sequence of up to 16 characters (and an empty tag is both OK and
common). The characters after ‘“tag(‘ and before the first following occurrence
of ‘)tag”’ are used literally as the contents of the string literal. ‘tag’ may
contain any character but parentheses, backslash, and whitespace.&lt;/p&gt;

&lt;p&gt;Examine the difference:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;concert_17_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;id: 17&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;artist: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Beyonce&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;date: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Wed Oct 10 12:39:54 EDT 2012&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;price_usd: 200&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;versus:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;concert_17_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;R&quot;(
    id: 17
    artist: &quot;Beyonce&quot;
    date: &quot;Wed Oct 10 12:39:54 EDT 2012&quot;
    price_usd: 200)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;special-cases&quot;&gt;Special Cases&lt;/h2&gt;

&lt;p&gt;Note that indentation rules, combined with the fact that raw string literals may
contain newlines, leave you with an awkward choice on how to indent the first
line of your raw string block. Because text protobufs ignore whitespace, this
problem can be avoided by throwing in a leading newline (ignored by the parser)
in that case, but not all uses of raw strings are so forgiving.&lt;/p&gt;

&lt;p&gt;A non-empty tag is useful when the sequence &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;)&quot;&lt;/code&gt; happens to appear in your
string and therefore can’t act as the closing delimiter:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;R&quot;foo(This contains quoted parens &quot;()&quot;)foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Raw string literals are certainly not an everyday tool for most of us, but there
are times when good use of this new language feature will increase readability.
So the next time you’re scratching your head trying to figure out if you need
two &lt;code&gt;\\&lt;/code&gt;s or four, try raw string literals instead. Your readers will
thank you for it, even if regular expressions are still hard:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;R&quot;regexp((?:&quot;(?:\\&quot;|[^&quot;])*&quot;|&apos;(?:\\&apos;|[^&apos;])*&apos;))regexp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
          <pubDate>2017-10-26T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/64</link>
          <guid isPermaLink="true">https://abseil.io/tips/64</guid>
        </item>
      
    
      
        <item>
          <title>CppCon 2017: The design of absl::StrCat</title>
          <description>&lt;h3 id=&quot;jorg-browns-lightning-talk&quot;&gt;Jorg Brown’s Lightning Talk&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:shreck@google.com&quot;&gt;Tom Manshreck&lt;/a&gt;, Abseil Tech Writer&lt;/p&gt;

&lt;p&gt;Check out Jorg Brown’s Lightning Talk on the design of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt;
for background on what problem it was designed to solve and why it was
designed the way it was.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=tuWnw3sWZ4w&quot; target=&quot;_blank&quot;&gt;
&lt;img src=&quot;/img/cppcon-strcat.png&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;
</description>
          <pubDate>2017-10-23T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20171023-cppcon-strcat</link>
          <guid isPermaLink="true">https://abseil.io/blog/20171023-cppcon-strcat</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #77: Temporaries, Moves, and Copies</title>
          <description>&lt;p&gt;Originally published as totw/77 on 2014-07-09&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Titus Winters &lt;a href=&quot;mailto:titus@google.com&quot;&gt;(titus@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2017-10-20&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/77&quot;&gt;abseil.io/tips/77&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the ongoing attempt to figure out how to explain to non-language-lawyers how
C++11 changed things, we present yet another entry in the series “When are
copies made?” This is part of a general attempt to simplify the subtle rules
that have surrounded copies in C++ and replace it with a simpler set of rules.&lt;/p&gt;

&lt;h2 id=&quot;can-you-count-to-2&quot;&gt;Can You Count to 2?&lt;/h2&gt;

&lt;p&gt;You can? Awesome. Remember that the “name rule” means that each unique name you
can assign to a certain resource affects how many copies of the object are in
circulation. (See &lt;a href=&quot;/tips/55&quot;&gt;TotW 55&lt;/a&gt; on Name Counting for a refresher.)&lt;/p&gt;

&lt;h2 id=&quot;name-counting-in-brief&quot;&gt;Name Counting, in Brief&lt;/h2&gt;

&lt;p&gt;If you’re worrying about a copy being created, presumably you’re worried about
some line of code in particular. So, look at that point. How many names exist
for the data you think is being copied? There are only 3 cases to consider:&lt;/p&gt;

&lt;h2 id=&quot;two-names-its-a-copy&quot;&gt;Two Names: It’s a Copy&lt;/h2&gt;

&lt;p&gt;This one is easy: if you’re giving a second name to the same data, it’s a copy.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;FillAVectorOfIntsByOutputParameterSoNobodyThinksAboutCopies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// Yep, this is a copy.&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forty_two&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;42&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;my_map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forty_two&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// Also a copy: my_map[5] counts as a name.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;one-name-its-a-move&quot;&gt;One Name: It’s a Move&lt;/h2&gt;

&lt;p&gt;This one is a little surprising: C++11 recognizes that if you can’t refer to a
name anymore, you also don’t care about that data anymore. The language had to
be careful not to break cases where you were relying on the destructor (say,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::MutexLock&lt;/code&gt;), so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt; is the easy case to identify.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetSomeInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Just a move: either &quot;ret&quot; or &quot;foo&quot; has the data, but never both at once.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetSomeInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The other way to tell the compiler that you’re done with a name (the “name
eraser” from &lt;a href=&quot;/tips/55&quot;&gt;TotW 55&lt;/a&gt;) is calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetSomeInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Not a copy, move allows the compiler to treat foo as a&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// temporary, so this is invoking the move constructor for&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// std::vector&amp;lt;int&amp;gt;.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Note that it isn’t the call to std::move that does the moving,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// it’s the constructor. The call to std::move just allows foo to&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// be treated as a temporary (rather than as an object with a name).&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;zero-names-its-a-temporary&quot;&gt;Zero Names: It’s a Temporary&lt;/h2&gt;

&lt;p&gt;Temporaries are also special: if you want to avoid copies, avoid providing names
to variables.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;OperatesOnVector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// No copies: the values in the vector returned by GetSomeInts()&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// will be moved (O(1)) into the temporary constructed between these&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// calls and passed by reference into OperatesOnVector().&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;OperatesOnVector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetSomeInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;beware-zombies&quot;&gt;Beware: Zombies&lt;/h2&gt;

&lt;p&gt;The above (other than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt; itself) is hopefully pretty intuitive, it’s
just that we all built up weird notions of copies in the years pre-dating C++11.
For a language without garbage collection, this type of accounting gives us an
excellent mix of performance and clarity. However, it’s not without dangers, and
the big one is this: what is left in a value after it has been moved from?&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CHECK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Is this valid? Maybe, but don’t count on it.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is one of the major difficulties: what can we say about these leftover
values? For most standard library types, such a value is left in a “valid but
unspecified state.” Non-standard types usually hold to the same rule. The safe
approach is to stay away from these objects: you are allowed to re-assign to
them, or let them go out of scope, but don’t make any other assumptions about
their state.&lt;/p&gt;

&lt;p&gt;Clang-tidy provides some some static-checking to catch use-after move with the
&lt;a href=&quot;https://clang.llvm.org/extra/clang-tidy/checks/bugprone/use-after-move.html&quot;&gt;bugprone-use-after-move&lt;/a&gt;
check. However, static-analysis won’t ever be able to catch all of these - be on
the lookout. Call these out in code review, and avoid them in your own code.
Stay away from the zombies.&lt;/p&gt;

&lt;h2 id=&quot;wait-stdmove-doesnt-move&quot;&gt;Wait, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move&lt;/code&gt; Doesn’t Move?&lt;/h2&gt;

&lt;p&gt;Yeah, one other thing to watch for is that a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt; isn’t 
actually a move itself, it’s just a cast to an rvalue-reference. It’s only the 
use of that reference by a move constructor or move assignment that does the 
work.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetSomeInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Does nothing.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Invokes std::vector&amp;lt;int&amp;gt;’s move-constructor.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This should almost never happen, and you probably shouldn’t waste a lot of
mental storage on it. I really only mention it if the connection between
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt; and a move constructor was confusing you.&lt;/p&gt;

&lt;h2 id=&quot;aaaagh-its-all-complicated-why&quot;&gt;Aaaagh! It’s All Complicated! Why!?!&lt;/h2&gt;

&lt;p&gt;First: it’s really not so bad. Since we have move operations in the majority of
our value types (including protobufs), we can do away with all of the
discussions of “Is this a copy? Is this efficient?” and just rely on name
counting: two names, a copy. Fewer than that: no copy.&lt;/p&gt;

&lt;p&gt;Ignoring the issue of copies, value semantics are clearer and simpler to reason
about. Consider these two operations:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ExpandGlob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GenerateGlob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ExpandGlob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GenerateGlob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Are these the same? What about if there is existing data in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*paths&lt;/code&gt;? How can
you tell? Value semantics are easier for a reader to reason about than
input/output parameters, where you need to think about (and document) what
happens to existing data, and potentially whether there is an pointer ownership
transfer.&lt;/p&gt;

&lt;p&gt;Because of the simpler guarantees about lifetime and usage when dealing with
values (instead of pointers), it is easier for the compiler’s optimizers to
operate on code in that style. Well-managed value semantics also minimizes hits
on the allocator (which is cheap but not free). Once we understand how move
semantics help rid us of copies, the compiler’s optimizers can better reason
about object types, lifetimes, virtual dispatch, and a host of other issues that
help generate more efficient machine code.&lt;/p&gt;

&lt;p&gt;Since most utility code is now move-aware, we should stop worrying about copies
and pointer semantics, and focus on writing simple easy-to-follow code. Please
make sure you understand the new rules: not all legacy interfaces you encounter
may be updated to return by value (instead of by output parameter), so there will
always be a mix of styles. It’s important that you understand when one is more
appropriate than the other.&lt;/p&gt;

</description>
          <pubDate>2017-10-20T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/77</link>
          <guid isPermaLink="true">https://abseil.io/tips/77</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #55: Name Counting and unique_ptr</title>
          <description>&lt;p&gt;Originally published as totw/55 on 2013-09-12&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Titus Winters &lt;a href=&quot;mailto:titus@google.com&quot;&gt;(titus@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2017-10-20&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/55&quot;&gt;abseil.io/tips/55&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Though we may know Him by a thousand names, He is one and the same to us
all.” - Mahatma Gandhi&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Colloquially, a “name” for a value is any value-typed variable (not a pointer,
nor a reference), in any scope, that holds a particular data value. (For the
spec-lawyers, if we say “name” we’re essentially talking about lvalues.) Because
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;’s specific behavioral requirements, we need to make sure
that any value held in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; only has one name.&lt;/p&gt;

&lt;p&gt;It’s important to note that the C++ language committee picked a very apt name
for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;. Any non-null pointer value stored in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;
must occur in only one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; at any time; the standard library is
designed to enforce this. Many common problems compiling code that uses
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; can be resolved by learning to recognize how to count the
names for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;: one is OK, but multiple names for the same
pointer value are not.&lt;/p&gt;

&lt;p&gt;Let’s count some names. At each line number, count the number of names alive at
that point (whether in scope or not) that refer to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;
containing the same pointer. If you find any line with more than one name for
the same pointer value, that’s an error!&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NewFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AcceptFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrintDebugString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Simple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;AcceptFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NewFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoesNotBuild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NewFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;AcceptFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// DOES NOT COMPILE!&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SmarterThanTheCompilerButNot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Compiles, BUT VIOLATES THE RULE and will double-delete at runtime.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Simple()&lt;/code&gt;, the unique pointer allocated with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NewFoo()&lt;/code&gt; only ever has one
name by which you could refer it: the name “f” inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AcceptFoo()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Contrast this with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoesNotBuild()&lt;/code&gt;: the unique pointer allocated with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NewFoo()&lt;/code&gt; has two names which refer to it: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DoesNotBuild()&lt;/code&gt;’s “g” and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AcceptFoo()&lt;/code&gt;’s “f”.&lt;/p&gt;

&lt;p&gt;This is the classic uniqueness violation: at any given point in the execution,
any value held by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; (or more generally, any move-only type)
can only be referred to by a single distinct name. Anything that looks like a
copy introducing an additional name is forbidden and won’t compile:&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;scratch.cc: error: call to deleted constructor of std::unique_ptr&amp;lt;Foo&amp;gt;&apos;
  AcceptFoo(g);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Even if the compiler doesn’t catch you, the runtime behavior of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; will. Any time where you “outsmart” the compiler (see
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SmarterThanTheCompilerButNot()&lt;/code&gt;) and introduce multiple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;
names, it may compile (for now) but you’ll get a run-time memory problem.&lt;/p&gt;

&lt;p&gt;Now the question becomes: how do we remove a name? C++11 provides a solution for
that as well, in the form of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;EraseTheName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NewFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;AcceptFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Fixes DoesNotBuild with std::move&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt; is effectively a name-eraser: conceptually you can
stop counting “h” as a name for the pointer value. This now passes the
distinct-names rule: on the unique pointer allocated with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NewFoo()&lt;/code&gt; has a
single name (“h”), and within the call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AcceptFoo()&lt;/code&gt; there is again only a
single name (“f”). By  using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move()&lt;/code&gt; we promise that we will not read
from “h” again until we assign a new value to it.&lt;/p&gt;

&lt;p&gt;Name counting is a handy trick in modern C++ for those that aren’t expert in the
subtleties of lvalues, rvalues, etc: it can help you recognize the possibility
of unnecessary copies, and it will help you use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt; properly.
After counting, if you discover a point where there are too many names, use
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move&lt;/code&gt; to erase the no-longer-necessary name.&lt;/p&gt;
</description>
          <pubDate>2017-10-20T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/55</link>
          <guid isPermaLink="true">https://abseil.io/tips/55</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #122: Test Fixtures, Clarity, and Dataflow</title>
          <description>&lt;p&gt;Originally published as totw/122 on 2016-08-30&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Titus Winters &lt;a href=&quot;mailto:titus@google.com&quot;&gt;(titus@google.com)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2017-10-20&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/122&quot;&gt;abseil.io/tips/122&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Be obscure clearly.&lt;/em&gt; — E.B. White&lt;/p&gt;

&lt;p&gt;How does test code differ from production code? For one thing, tests are
untested: when you write messy spaghetti code that is spread over several files
and has hundreds of lines of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetUp&lt;/code&gt; how can anyone be sure that the test is
really testing what it needs to? Too often your code reviewers will have to
assume that the setup makes sense and are at best spot-checking the logic for
each individual test case. In those cases, your test is likely to fail if
something changes, but it’s rarely clear whether that something is the right
something.&lt;/p&gt;

&lt;p&gt;On the other hand, if you keep each test simple and as straightforward as
possible, it’s easier to see that it is correct by inspection, understand the
logic, and review for higher quality test logic. Let’s look at a few simple ways
to achieve that.&lt;/p&gt;

&lt;h2 id=&quot;dataflow-in-fixtures&quot;&gt;Dataflow in Fixtures&lt;/h2&gt;

&lt;p&gt;Consider the following example:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FrobberTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;protected:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigureExampleA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;example_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Example A&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;frobber_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;example_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;expected_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Result A&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigureExampleB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;example_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Example B&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;frobber_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;example_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;expected_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Result B&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frobber_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TEST_F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FrobberTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CalculatesA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ConfigureExampleA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frobber_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Calculate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;EXPECT_EQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TEST_F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FrobberTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CalculatesB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ConfigureExampleB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frobber_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Calculate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;EXPECT_EQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this fairly simple example, our tests span 30 lines of code. It’s very easy
to imagine less simple examples that are 10x that: certainly more than will fit
on any single screen. A reader or code reviewer that wants to validate that the
code is correct has to scan around as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“OK, this is a FrobberTest, where’s that defined … oh, this file. Great.”&lt;/li&gt;
  &lt;li&gt;“&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigureExampleA&lt;/code&gt; … that’s a FrobberTest method. It’s operating on some
member variables. What types are those? How are they initialized? OK,
Frobber and two strings. Is there a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetUp&lt;/code&gt;? OK, default constructed.”&lt;/li&gt;
  &lt;li&gt;“Back to the test: OK, we calculate a result and compare it against
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expected_&lt;/code&gt; … what did we store there again?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compare to the equivalent code written in a simpler style:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;TEST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FrobberTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CalculatesA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Example A&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;EXPECT_EQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Calculate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Result A&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TEST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FrobberTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CalculatesB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Frobber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Example B&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;EXPECT_EQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Calculate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Result B&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With this style, even in a world where we have hundreds of tests, we can tell
with only local information exactly what is going on.&lt;/p&gt;

&lt;h2 id=&quot;prefer-free-functions&quot;&gt;Prefer Free Functions&lt;/h2&gt;

&lt;p&gt;In the previous example, all of the variable initialization was nice and terse.
In real tests, that isn’t always true. However, the same ideas about dataflow
and avoiding fixtures may apply. Consider this protobuf example:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BobberTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;protected:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SetUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bobber1_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PARSE_TEXT_PROTO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;R&quot;(
        id: 17
        artist: &quot;Beyonce&quot;
        when: &quot;2012-10-10 12:39:54 -04:00&quot;
        price_usd: 200)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bobber2_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PARSE_TEXT_PROTO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;R&quot;(
        id: 21
        artist: &quot;The Shouting Matches&quot;
        when: &quot;2016-08-24 20:30:21 -04:00&quot;
        price_usd: 60)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;BobberProto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bobber1_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;BobberProto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bobber2_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TEST_F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BobberTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UsesProtos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Bobber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bobber1_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bobber2_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SomeCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;EXPECT_THAT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MostRecent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EqualsProto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bobber2_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again, the centralized refactoring leads to a lot of indirection: declarations
and initialization are separate, and potentially far away from actual use.
Further, because of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SomeCall()&lt;/code&gt; in the middle, and the fact we’re using a
fixture and fixture member variables, there’s no way to be &lt;em&gt;sure&lt;/em&gt; that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bobber1_&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bobber2_&lt;/code&gt; weren’t modified between initialization and the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPECT_THAT&lt;/code&gt; validation, without checking the details of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SomeCall()&lt;/code&gt;. More
scrolling around is likely necessary.&lt;/p&gt;

&lt;p&gt;Consider instead:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;BobberProto&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RecentCheapConcert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PARSE_TEXT_PROTO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;R&quot;(
      id: 21
      artist: &quot;The Shouting Matches&quot;
      when: &quot;2016-08-24 20:30:21 -04:00&quot;
      price_usd: 60)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;BobberProto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PastExpensiveConcert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PARSE_TEXT_PROTO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;R&quot;(
      id: 17
      artist: &quot;Beyonce&quot;
      when: &quot;2012-10-10 12:39:54 -04:00&quot;
      price_usd: 200)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TEST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BobberTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UsesProtos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Bobber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PastExpensiveConcert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RecentCheapConcert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()});&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SomeCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;EXPECT_THAT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bobber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MostRecent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EqualsProto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RecentCheapConcert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Moving the initialization into free functions makes it clear that there is no
hidden dataflow. Well chosen names for the helpers mean that you can likely
review the test for correctness without even scrolling up to see the details of
the helper.&lt;/p&gt;

&lt;h2 id=&quot;five-easy-steps&quot;&gt;Five Easy Steps&lt;/h2&gt;

&lt;p&gt;You can generally improve test clarity by following these steps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Avoid fixtures where reasonable. Sometimes it’s not.&lt;/li&gt;
  &lt;li&gt;If you are using fixtures, try to avoid fixture member variables. It is far
too easy to start operating on those in ways akin to globals: data flow is
hard to track since absolutely any code path in the fixture may modify the
member.&lt;/li&gt;
  &lt;li&gt;If you’ve got variables that need complex initialization that would make
each test hard to read, consider a helper function (not part of the fixture)
that documents that initialization and returns the object directly.&lt;/li&gt;
  &lt;li&gt;If you must have fixtures that contain member variables, try to avoid
methods that operate on those members directly: pass them in as parameters
whenever possible to make the dataflow clear.&lt;/li&gt;
  &lt;li&gt;Try to write tests before writing headers: if you start with a usage that is
pleasant to test, your API is usually better, and your tests are almost
always clearer.&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2017-10-20T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/122</link>
          <guid isPermaLink="true">https://abseil.io/tips/122</guid>
        </item>
      
    
      
        <item>
          <title>CppCon 2017: C++ as a &apos;Live at Head&apos; Language</title>
          <description>&lt;h3 id=&quot;titus-winters-plenary-keynote&quot;&gt;Titus Winters’ Plenary Keynote&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:shreck@google.com&quot;&gt;Tom Manshreck&lt;/a&gt;, Abseil Tech Writer&lt;/p&gt;

&lt;p&gt;If you didn’t get a chance to check out Titus Winters’ plenary
keynote in person, check it out below.&lt;/p&gt;

&lt;p&gt;Find out why “Living at Head” is a good thing!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=tISy7EJQPzI&amp;amp;t=1032s&quot; target=&quot;_blank&quot;&gt;
&lt;img src=&quot;/img/cppcon-plenary.jpg&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;
</description>
          <pubDate>2017-10-04T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20171004-cppcon-plenary</link>
          <guid isPermaLink="true">https://abseil.io/blog/20171004-cppcon-plenary</guid>
        </item>
      
    
      
        <item>
          <title>Welcome to Abseil!</title>
          <description>&lt;h3 id=&quot;a-new-common-libraries-project&quot;&gt;A New Common Libraries Project&lt;/h3&gt;

&lt;p&gt;By &lt;a href=&quot;mailto:titus@google.com&quot;&gt;Titus Winters&lt;/a&gt;, Abseil Lead&lt;/p&gt;

&lt;p&gt;Today we are open sourcing &lt;a href=&quot;https://abseil.io&quot;&gt;Abseil&lt;/a&gt;, a collection of 
libraries drawn from the most fundamental pieces of Google’s internal codebase. 
These libraries are the nuts-and-bolts that underpin almost everything that 
Google runs. Bits and pieces of these APIs are embedded in most of our open 
source projects, and now we have brought them together into one comprehensive 
project. Abseil encompasses the most basic building blocks of Google’s 
codebase: code that is production tested and will be fully maintained for years 
to come.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;Our C++ code repository is available at
&lt;a href=&quot;https://github.com/abseil/abseil-cpp&quot;&gt;https://github.com/abseil/abseil-cpp&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By adopting these new Apache-licensed libraries, you can reap the benefit of years (over a decade in many cases) of our design and optimization work in this space. Our past experience is baked in.&lt;/p&gt;

&lt;p&gt;Just as interesting, we’ve also prepared for the future: several types in
 Abseil’s C++ libraries are “pre-adoption” versions of C++17 types like 
 &lt;a href=&quot;http://en.cppreference.com/w/cpp/string/basic_string_view&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;&lt;/a&gt; and 
 &lt;a href=&quot;http://en.cppreference.com/w/cpp/utility/optional&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&lt;/code&gt;&lt;/a&gt; - implemented 
 in C++11 to the greatest extent possible. We look forward to moving more and 
 more of our code to match the current standard, and using these new vocabulary 
 types helps us make that transition. Importantly, in C++17 mode these types 
 are merely aliases to the standard, ensuring that you only ever have one type 
 for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; in a project at a time. Put another way: 
 Abseil is focused on the engineering task of providing APIs that remain stable 
 &lt;strong&gt;over time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Consisting of the foundational C++ and Python code at Google, Abseil includes 
libraries that will grow to underpin other Google-backed open source projects 
like &lt;a href=&quot;https://grpc.io/&quot;&gt;gRPC&lt;/a&gt;, &lt;a href=&quot;https://github.com/google/protobuf&quot;&gt;Protobuf&lt;/a&gt; 
and &lt;a href=&quot;https://www.tensorflow.org/&quot;&gt;TensorFlow&lt;/a&gt;. We love those projects, and we 
love the users of those projects - we want to ensure smooth usage for these 
things over time. In the next few months we’ll introduce new distribution 
methods to incorporate these projects as a collection into your project.&lt;/p&gt;

&lt;p&gt;Continuing with the “over time” theme, Abseil aims for compatibility with major 
compilers, platforms and standard libraries for approximately 5 years. Our 
5-year target also applies to language version: we assume everyone builds with 
C++11 at this point. (In 2019 we’ll start talking about requiring C++14 as our 
base language version.) This 5-year horizon is part of our balance between 
“support everything” and “provide modern implementations and APIs.”&lt;/p&gt;

&lt;p&gt;Highlights of the initial release include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Zero configuration: most platforms (OS, compiler, architecture) should just 
work.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/about/design/dropin-types&quot;&gt;Pre-adoption for C++17 types&lt;/a&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;, 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optional&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any&lt;/code&gt;. We’ll follow up with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;variant&lt;/code&gt; soon.&lt;/li&gt;
  &lt;li&gt;Our primary synchronization type, &lt;a href=&quot;/about/design/mutex&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Mutex&lt;/code&gt;&lt;/a&gt;, has 
an elegant interface and has been extensively optimized.&lt;/li&gt;
  &lt;li&gt;Efficient support for handling time: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Time&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Duration&lt;/code&gt; are 
conceptually similar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::chrono&lt;/code&gt; types, but are concrete (not class 
templates) and have defined behavior in all cases. Additionally, our 
clock-sampling API &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::Now()&lt;/code&gt; is more heavily optimized than most standard 
library calls for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::chrono::system_clock::now()&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;String handling routines: among internal users, we’ve been told that 
releasing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrCat()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrJoin()&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::StrSplit()&lt;/code&gt; would 
itself be a big improvement for the open source C++ world.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project has support for C++ and some Python. Over time we’ll tie those two 
projects together more closely with shared logging and command-line flag 
infrastructure. To start contributing, please see our contribution guidelines 
and fork us on &lt;a href=&quot;https://github.com/abseil/&quot;&gt;GitHub&lt;/a&gt;. Check out our 
&lt;a href=&quot;/docs&quot;&gt;documentation&lt;/a&gt; and &lt;a href=&quot;/community&quot;&gt;community page&lt;/a&gt; for information on how 
to contact us, ask questions or contribute to Abseil.&lt;/p&gt;
</description>
          <pubDate>2017-09-26T00:00:00-04:00</pubDate>
          <link>https://abseil.io/blog/20170926-welcome-to-abseil</link>
          <guid isPermaLink="true">https://abseil.io/blog/20170926-welcome-to-abseil</guid>
        </item>
      
    
      
        <item>
          <title>Tip of the Week #1: &lt;code&gt;string_view&lt;/code&gt;</title>
          <description>&lt;p&gt;Originally posted as TotW #1 on April 20, 2012&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By &lt;a href=&quot;mailto:mec.desktop@gmail.com&quot;&gt;Michael Chastain&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updated 2020-08-18&lt;/p&gt;

&lt;p&gt;Quicklink: &lt;a href=&quot;https://abseil.io/tips/1&quot;&gt;abseil.io/tips/1&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;whats-a-string_view-and-why-should-you-care&quot;&gt;What’s a &lt;code&gt;string_view&lt;/code&gt;, and Why Should You Care?&lt;/h2&gt;

&lt;p&gt;When creating a function to take a (constant) string as an argument, you have
three common alternatives: two that you already know, and one of which you might
not be aware:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
// C Convention
void TakesCharStar(const char* s);

// Old Standard C++ convention
void TakesString(const std::string&amp;amp; s);

// string_view C++ conventions
void TakesStringView(absl::string_view s);    // Abseil
void TakesStringView(std::string_view s);     // C++17
&lt;/pre&gt;

&lt;p&gt;The first two cases work best when a caller has the string in the format already
provided, but what happens when a conversion is needed (either from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
char*&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt;)?&lt;/p&gt;

&lt;p&gt;Callers needing to convert a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; need to use the
(efficient but inconvenient) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c_str()&lt;/code&gt; function:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void AlreadyHasString(const std::string&amp;amp; s) {
  TakesCharStar(s.c_str());               // explicit conversion
}
&lt;/pre&gt;

&lt;p&gt;Callers needing to convert a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; don’t need to do
anything additional (the good news) but will invoke the creation of a
(convenient but inefficient) temporary string, copying the contents of that
string (the bad news):&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void AlreadyHasCharStar(const char* s) {
  TakesString(s); // compiler will make a copy
}
&lt;/pre&gt;

&lt;h2 id=&quot;what-to-do&quot;&gt;What to Do?&lt;/h2&gt;

&lt;p&gt;Google’s preferred option for accepting such string parameters is through a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;. This is a “pre-adopted” type from C++17 - for now, use
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absl::string_view&lt;/code&gt; even if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string_view&lt;/code&gt; is available.&lt;/p&gt;

&lt;p&gt;An instance of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; class can be thought of as a “view” into an
existing character buffer. Specifically, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; consists of only a
pointer and a length, identifying a section of character data that is not owned
by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; and cannot be modified by the view. Consequently, making a
copy of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; is a shallow operation: no string data is copied.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; has implicit conversion constructors from both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::string&amp;amp;&lt;/code&gt;, and since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; doesn’t copy, there is no O(n)
memory penalty for making a hidden copy. In the case where a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
std::string&amp;amp;&lt;/code&gt; is passed, the constructor runs in O(1) time. In the case where a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; is passed, the constructor invokes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strlen()&lt;/code&gt; automatically (or
you can use the two-parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; constructor).&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
void AlreadyHasString(const std::string&amp;amp; s) {
  TakesStringView(s); // no explicit conversion; convenient!
}

void AlreadyHasCharStar(const char* s) {
  TakesStringView(s); // no copy; efficient!
}
&lt;/pre&gt;

&lt;p&gt;Because the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; does not own its data, any strings pointed to by the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; (just like a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt;) must have a known lifespan, and must
outlast the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;This means that using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; for storage is often questionable: you need
some proof that the underlying data will outlive the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;. For example,
the following struct probably doesn’t make sense if it might be stored beyond
the result of a function call that accepts it as a parameter:&lt;/p&gt;

&lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
struct TestScore {
  absl::string_view username;  // Probably should be a `std::string`
  double score;
};
&lt;/pre&gt;

&lt;p&gt;If your API only needs to reference the string data during a single call, and
doesn’t need to modify the data, accepting a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; is sufficient.&lt;/p&gt;

&lt;p&gt;If you need to use the data later or modify the data, you can explicitly convert
to a C++ string object using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string(my_string_view)&lt;/code&gt;. Another option,
discussed in &lt;a href=&quot;/tips/117&quot;&gt;Tip #117&lt;/a&gt;, is to pass a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; by value and use
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::move&lt;/code&gt; in callers when applicable.&lt;/p&gt;

&lt;p&gt;Adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; into an existing codebase is not always the right answer:
changing parameters to pass by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; can be inefficient if those are
then passed to a function requiring a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; or a NUL-terminated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
char*&lt;/code&gt;. It is best to adopt &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; starting at the utility code and
working upward, or with complete consistency when starting a new project.&lt;/p&gt;

&lt;h2 id=&quot;a-few-additional-notes&quot;&gt;A Few Additional Notes&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Unlike other string types, you should pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; by value just like
you would pass an int or a double because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; is a small value.&lt;/li&gt;
  &lt;li&gt;Marking a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; only affects whether the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt;
object itself can be modified, and not whether it can be used to modify the
underlying chars – it never can. This is exactly analogous to how a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
char*&lt;/code&gt; can never be used to modify the chars, even if the pointer itself can
be modified.&lt;/li&gt;
  &lt;li&gt;For function parameters, don’t qualify &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; in
function declarations (see &lt;a href=&quot;/tips/109&quot;&gt;Tip #109&lt;/a&gt;). You may use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; to
qualify &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; in function definitions at your (or your team’s)
discretion, e.g., to be consistent with the surrounding code
(&lt;a href=&quot;/tips/109&quot;&gt;Tip #109&lt;/a&gt;). For other local variables, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; is neither
encouraged nor discouraged
(https://google.github.io/styleguide/cppguide.html#Use_of_const).&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; is not necessarily NUL-terminated. Thus, it’s not safe to
write:&lt;/p&gt;

    &lt;pre class=&quot;prettyprint lang-cpp bad-code&quot;&gt;
    printf(&quot;%s\n&quot;, sv.data()); // DON’T DO THIS
&lt;/pre&gt;

    &lt;p&gt;Prefer this instead (see &lt;a href=&quot;/tips/124&quot;&gt;Tip #124&lt;/a&gt;):&lt;/p&gt;

    &lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
    absl::PrintF(&quot;%s\n&quot;, sv);
&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;You can log a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; just like you would a string or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const
char*&lt;/code&gt; :&lt;/p&gt;

    &lt;pre class=&quot;prettyprint lang-cpp code&quot;&gt;
    LOG(INFO) &amp;lt;&amp;lt; &quot;Took &apos;&quot; &amp;lt;&amp;lt; sv &amp;lt;&amp;lt; &quot;&apos;&quot;;
&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;You can convert an existing routine that accepts &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const std::string&amp;amp;&lt;/code&gt; or
NUL-terminated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const char*&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; safely in most cases. The only
danger we have encountered in performing this operation is if the address of
the function has been taken, this will result in a build break as the
resulting function-pointer type will be different.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; has a constexpr constructor and a trivial destructor; keep
this in mind when using in static and global variables (see
&lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables&quot;&gt;the style guide&lt;/a&gt;)
or constants (see &lt;a href=&quot;/tips/140&quot;&gt;Tip #140&lt;/a&gt;).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_view&lt;/code&gt; is an effective reference and may not be the best choice for
member variables (also see &lt;a href=&quot;/tips/180&quot;&gt;Tip #180&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
</description>
          <pubDate>2017-09-26T00:00:00-04:00</pubDate>
          <link>https://abseil.io/tips/1</link>
          <guid isPermaLink="true">https://abseil.io/tips/1</guid>
        </item>
      
    
  </channel>
</rss>