<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Anthony Calandra</title>
  <subtitle>Thoughts on software, and other things.</subtitle>
  <link href="https://anthony-calandra.com/feed.xml" rel="self" />
  <link href="https://anthony-calandra.com/" />
  <updated>2025-03-01T00:00:00Z</updated>
  <id>https://anthony-calandra.com/</id>
  <author>
    <name>Anthony Calandra</name>
  </author>
    <entry>
        <title>Queues in Postgres</title>
        <link href="https://anthony-calandra.com/b/queues-in-postgres/" />
        <updated>2025-03-01T00:00:00Z</updated>
        <id>https://anthony-calandra.com/b/queues-in-postgres/</id>
        <content type="html">&lt;h1 id=&quot;queues-in-postgres&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/queues-in-postgres/#queues-in-postgres&quot;&gt;#&lt;/a&gt; Queues in Postgres&lt;/h1&gt;
&lt;p&gt;Problem: We&#39;ve got a queue of tasks that workers can consume and work on. The database stores all the tasks, a worker will come along to take the oldest task available, assign itself to it then begin its work.&lt;/p&gt;
&lt;p&gt;Let&#39;s create a simple schema to represent the list of tasks and workers:&lt;/p&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;TABLE&lt;/span&gt; task {
  id &lt;span class=&quot;token keyword&quot;&gt;SERIAL&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  worker_id &lt;span class=&quot;token keyword&quot;&gt;INTEGER&lt;/span&gt;
}&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;TABLE&lt;/span&gt; worker {
  id &lt;span class=&quot;token keyword&quot;&gt;SERIAL&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;KEY&lt;/span&gt;  
}&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assumptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assume other external systems are responsible for inserting tasks and managing workers.&lt;/li&gt;
&lt;li&gt;Assume task ids are implicitly ordered by their task id; i.e. older tasks have smaller ids.&lt;/li&gt;
&lt;li&gt;Assume workers eventually delete the task from the queue when it&#39;s done.&lt;/li&gt;
&lt;li&gt;Generally, there are enough workers around that the size of the queue will be small, so we won&#39;t add an index.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How do we assign workers to tasks?&lt;/p&gt;
&lt;h2 id=&quot;naive-implementation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/queues-in-postgres/#naive-implementation&quot;&gt;#&lt;/a&gt; Naive Implementation&lt;/h2&gt;
&lt;p&gt;Here&#39;s a simple implementation:&lt;/p&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;UPDATE&lt;/span&gt; task
&lt;span class=&quot;token keyword&quot;&gt;SET&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ?
&lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;MIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; task_id
  &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; task
  &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The query selects the oldest task id currently in the queue that isn&#39;t assigned to a worker. If we find a task, we set the worker to be the current one executing the query (using the &lt;code&gt;?&lt;/code&gt; as a placeholder).&lt;/p&gt;
&lt;p&gt;On the surface this query is correct, however, how would it behave if there are multiple workers competing for tasks?&lt;/p&gt;
&lt;h2 id=&quot;implementation-2-fix-concurrency-bugs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/queues-in-postgres/#implementation-2-fix-concurrency-bugs&quot;&gt;#&lt;/a&gt; Implementation 2: Fix Concurrency Bugs&lt;/h2&gt;
&lt;p&gt;Try and spot some concurrency bugs in this implementation. Can you find any?&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;Here&#39;s one: two workers work on the same task. But how? Let&#39;s see if we can reproduce this scenario.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Worker 0&lt;/th&gt;
&lt;th&gt;Worker 1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;BEGIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;BEGIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;UPDATE&lt;/span&gt; task
&lt;span class=&quot;token keyword&quot;&gt;SET&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;MIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; task_id
  &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; task
  &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;UPDATE&lt;/span&gt; task
&lt;span class=&quot;token keyword&quot;&gt;SET&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;MIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; task_id
  &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; task
  &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COMMIT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COMMIT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;

&lt;/table&gt;
&lt;p&gt;Result: the task is assigned to worker 1!&lt;/p&gt;
&lt;p&gt;What we experienced here is a &lt;strong&gt;lost update&lt;/strong&gt;. Implicit in this query, is that it&#39;s running at the &lt;code&gt;READ COMMITTED&lt;/code&gt; transaction isolation level -- the default in Postgres &lt;sup&gt;&lt;a href=&quot;https://www.postgresql.org/docs/current/transaction-iso.html#XACT-READ-COMMITTED&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;When the UPDATE query for Worker 1 is executed, it&#39;s blocked on the same row that Worker 0 updated until that worker commits. Then once the change is committed, Worker 1&#39;s UPDATE query rereads the row, rechecks all of its conditions in the WHERE clause, and successfully executes the UPDATE and commits.&lt;/p&gt;
&lt;p&gt;You can find this in the full set of the documentation on READ COMMITTED &lt;a href=&quot;https://www.postgresql.org/docs/current/transaction-iso.html#XACT-READ-COMMITTED&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The change is pretty simple: just add an extra condition on the WHERE clause to ensure the &lt;code&gt;worker_id&lt;/code&gt; is still NULL before doing the UPDATE:&lt;/p&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;UPDATE&lt;/span&gt; task
&lt;span class=&quot;token keyword&quot;&gt;SET&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ?
&lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;MIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; task_id
    &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; task
    &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;AND&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;implementation-3-better-performance&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/queues-in-postgres/#implementation-3-better-performance&quot;&gt;#&lt;/a&gt; Implementation 3: Better Performance&lt;/h2&gt;
&lt;p&gt;We&#39;re still faced with a subtle (but important) problem: blocking. As indicated in the documentation, when a transaction is making an update (or delete, etc.) to a row that has been changed by another pending transaction, it&#39;s required to block on that transaction until completion and load the new row if it had changed. If the pending transaction had rolled back, the UPDATE simply locks the row and changes it as usual.&lt;/p&gt;
&lt;p&gt;For a highly-contended task queue, this scales poorly when more workers are competing for tasks to work on.&lt;/p&gt;
&lt;p&gt;Is there a way to prevent the worker from waiting?&lt;/p&gt;
&lt;p&gt;Postgres provides explicit locking clauses that let us choose certain behaviors when locking on rows. Two of them (as of Postgres 17) are &lt;code&gt;NOWAIT&lt;/code&gt; and &lt;code&gt;SKIP LOCKED&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;nowait&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/queues-in-postgres/#nowait&quot;&gt;#&lt;/a&gt; NOWAIT&lt;/h3&gt;
&lt;p&gt;Using this clause, if a row-level lock cannot be acquired the moment it is needed, Postgres will abort the transaction an issue an error to the client.&lt;/p&gt;
&lt;p&gt;This may be useful for client-sided retry logic and error-handling, but it&#39;s likely for most queues we&#39;ll want the second option.&lt;/p&gt;
&lt;h3 id=&quot;skip-locked&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/queues-in-postgres/#skip-locked&quot;&gt;#&lt;/a&gt; SKIP LOCKED&lt;/h3&gt;
&lt;p&gt;This option will skip a row if the row-level lock cannot be acquired.&lt;/p&gt;
&lt;p&gt;For queueing systems, this is likely the behavior that would be desired; the worker will simply give up on that task and attempt to find the next one to work on (if there are any). Since only one worker will be able to lock a row at a given time, it&#39;s not possible for a lost update to occur because any other competing workers would have lost the race and moved on.&lt;/p&gt;
&lt;p&gt;Here&#39;s what the new query looks like:&lt;/p&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;UPDATE&lt;/span&gt; task
&lt;span class=&quot;token keyword&quot;&gt;SET&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ?
&lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;MIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; task_id
  &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; task
  &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; worker_id &lt;span class=&quot;token operator&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;FOR&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;UPDATE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;OF&lt;/span&gt; task SKIP LOCKED
  &lt;span class=&quot;token keyword&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Three things to observe with these changes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;FOR UPDATE&lt;/code&gt; grants the transaction an exclusive lock on the row for the task that&#39;s selected. With the &lt;code&gt;SELECT .. FOR UPDATE&lt;/code&gt; command, if a row had been changed by a concurrently committed transaction (i.e. after it committed and released its lock, and while the current transaction still sees the old row in its snapshot), it will reload and lock the latest version of the row to ensure it still satisfies the WHERE clause&#39;s conditions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SKIP LOCKED&lt;/code&gt; will skip this row if the transaction is unable to acquire a lock.&lt;/li&gt;
&lt;li&gt;The condition in the UPDATE for &lt;code&gt;worker_id&lt;/code&gt; is gone since we will be the exclusive reader of the row that&#39;s to be updated. No other transaction can see this row in their task selection query.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To summarize, this query won&#39;t cause transactions to block on a task that may have been taken by another. So for example, if 50 workers had tried to access this task at the same time, the winner will get to take ownership of the task, while the other 49 will move on to the next oldest task to take, and so on.&lt;/p&gt;
&lt;h2 id=&quot;isolation-levels&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/queues-in-postgres/#isolation-levels&quot;&gt;#&lt;/a&gt; Isolation Levels&lt;/h2&gt;
&lt;p&gt;While the condition to take a task is pretty simple, in your production system you may have more requirements on how workers should take a task to work on.&lt;/p&gt;
&lt;p&gt;Keep in mind the complexity of your task selection, for you might need the stronger guarantees that other levels such as REPEATABLE READ and SERIALIZABLE provide. At these levels, transaction rollbacks are common and may come at a performance cost for your application.&lt;/p&gt;
&lt;p&gt;At work, I had seen hundreds of thousands of transaction rollbacks per day when our task selection query was both expensive and at the REPEATABLE READ isolation level. Once we refactored the query and were able to drop down to READ COMMITTED, our average task queue times dropped significantly. A task queue time is defined by how long a task takes to be picked up and owned by a worker.&lt;/p&gt;
&lt;p&gt;Now because we dropped down to this level, our task selection logic had to accept stale reads in certain circumstances, therefore affecting how workers accepted tasks. This is a change we were fine with for our use case.&lt;/p&gt;
&lt;p&gt;So to put it simply: if your task selection process is complicated, the tradeoff in correctness by choosing a stronger isolation level is performance cost, and that tradeoff may be quite significant. If your application can retry and do it quickly for potential rollbacks, the cost of using a higher isolation level may be acceptable. On the contrary, if transaction rollbacks are too slow to be acceptable, dropping down to READ COMMITTED and using a locking strategy like in Implementation 3 is likely to be more beneficial.&lt;/p&gt;
&lt;h2 id=&quot;other-implementations&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/queues-in-postgres/#other-implementations&quot;&gt;#&lt;/a&gt; Other Implementations&lt;/h2&gt;
&lt;p&gt;Postgres also provides &lt;code&gt;LISTEN&lt;/code&gt; and &lt;code&gt;NOTIFY&lt;/code&gt; for alerting workers to new tasks. This provides an opportunity for a different task selection implementation.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <title>const in C++</title>
        <link href="https://anthony-calandra.com/b/const-in-cpp/" />
        <updated>2024-12-15T00:00:00Z</updated>
        <id>https://anthony-calandra.com/b/const-in-cpp/</id>
        <content type="html">&lt;h1 id=&quot;const-in-c&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-in-c&quot;&gt;#&lt;/a&gt; const in C++&lt;/h1&gt;
&lt;p&gt;In this article I&#39;m going to go over all the cases of &lt;code&gt;const&lt;/code&gt; in C++ I see regularly.&lt;/p&gt;
&lt;h2 id=&quot;why-const&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#why-const&quot;&gt;#&lt;/a&gt; Why &lt;code&gt;const&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;First I want to briefly touch on why we should bother having to qualify as many variables, member functions, etc. whenever we can.&lt;/p&gt;
&lt;p&gt;The topic of compiler optimizations have been written many times before. Please take a look at &lt;a href=&quot;http://www.gotw.ca/gotw/081.htm&quot;&gt;this GotW article&lt;/a&gt; for when &lt;code&gt;const&lt;/code&gt; is effective and also when it may be ineffective at optimizing code. Another practical example can be found &lt;a href=&quot;https://queue.acm.org/detail.cfm?id=3372264&quot;&gt;here&lt;/a&gt; by Matt Godbolt, specifically when talking about &lt;code&gt;const&lt;/code&gt; in &lt;code&gt;testFunc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Besides compiler optimizations, &lt;code&gt;const&lt;/code&gt; is also important for developers, arguably more so. When you something is qualified as &lt;code&gt;const&lt;/code&gt;, it&#39;s effectively shrinking the set of runtime state you need to manage in your mental model of the code you&#39;re looking at. In other words, the fewer variables that are changing in a function, the more you can focus on the code that &lt;em&gt;does&lt;/em&gt; change state.&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    T t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    U u &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In &lt;code&gt;foo&lt;/code&gt;, because nothing is qualified as &lt;code&gt;const&lt;/code&gt;, you need to examine every single local variable and determine if you need to keep track of their state throughout the body of this function. However, with &lt;code&gt;bar&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; T t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    U u &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this fictitious function, I qualified three local variables with &lt;code&gt;const&lt;/code&gt;. Now for a future developer who needs to understand what this function does, step through in a debugger, and so on, we only need to observe the values of &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, and &lt;code&gt;t&lt;/code&gt; once, and focus on the runtime state of &lt;code&gt;u&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; only.&lt;/p&gt;
&lt;h2 id=&quot;when-const&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#when-const&quot;&gt;#&lt;/a&gt; When &lt;code&gt;const&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;I like to make it a habit to proactively use &lt;code&gt;const&lt;/code&gt;, and while I continue working on code if I find I have to change the state of something and it makes sense to do so, I&#39;ll remove it. Due to having to write out an extra few keystrokes, I think it&#39;s more cumbersome than using a language like Rust which took the opposite direction (&lt;code&gt;const&lt;/code&gt; by default rather than opt-in). Although it&#39;s annoying, the benefits are worth it.&lt;/p&gt;
&lt;h2 id=&quot;const-with-variables&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-with-variables&quot;&gt;#&lt;/a&gt; &lt;code&gt;const&lt;/code&gt; with variables&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;const&lt;/code&gt; when you want to essentially mark the value of this variable immutable. When used with objects, you can only call special member functions (such as constructors, destructors) and &lt;code&gt;const&lt;/code&gt; member functions.&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; T t&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;lifetime-extension&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#lifetime-extension&quot;&gt;#&lt;/a&gt; Lifetime extension&lt;/h3&gt;
&lt;p&gt;An interesting feature of using &lt;code&gt;const&lt;/code&gt; references like in the first line above is you get &lt;em&gt;lifetime extension&lt;/em&gt;: the literal value &lt;code&gt;123&lt;/code&gt; can be bound to a reference because the compiler extends the lifetime of this value simply because we use &lt;code&gt;const&lt;/code&gt; to tell the compiler we aren&#39;t changing the value. This would not compile if it was a mutable reference. In practice, don&#39;t worry about this too much.&lt;/p&gt;
&lt;h2 id=&quot;const-with-functions&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-with-functions&quot;&gt;#&lt;/a&gt; &lt;code&gt;const&lt;/code&gt; with functions&lt;/h2&gt;
&lt;p&gt;Consider &lt;code&gt;const&lt;/code&gt; in the return type when you&#39;re returning a pointer or reference that you want don&#39;t intend to modify. Don&#39;t use &lt;code&gt;const&lt;/code&gt; for value types, like &lt;code&gt;int&lt;/code&gt;, some &lt;code&gt;T&lt;/code&gt; type you create, etc. as this doesn&#39;t provide any practical benefit in modern C++.&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// BAD:&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// GOOD:&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Consider &lt;code&gt;const&lt;/code&gt; for parameters that you don&#39;t intend to modify. This advice also includes value types.&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// BAD: `n` doesn&#39;t change, so it could be `const`.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// GOOD: no intention to change `n`.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do not add &lt;code&gt;const&lt;/code&gt; qualifiers to value types in the parameter list of function declarations (such as those in header files), as these are redundant.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// BAD: no need for `const` here.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// do something with x&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// GOOD&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// do something with x&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Same applies to member functions.&lt;/p&gt;
&lt;p&gt;But why?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;const&lt;/code&gt; matters for things like references and pointers, but for value types these are copied anyway. It doesn&#39;t matter if the thing passed in is &lt;code&gt;const&lt;/code&gt; from a declaration perspective, what matters when we use &lt;code&gt;const&lt;/code&gt; is &lt;strong&gt;how we&#39;re using it in the definition (i.e. the body of a function).&lt;/strong&gt; From the interface, a value type that gets copied doesn&#39;t need to advertise its &amp;quot;const-ness&amp;quot;; it&#39;s irrelevant to the caller.&lt;/li&gt;
&lt;li&gt;The two declarations cannot be overloaded together, as they&#39;re the same declaration:&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;myfoo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; myfoo&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
Using GCC 14.2:&lt;pre&gt;&lt;code&gt;&amp;lt;source&amp;gt;:10:6: error: &#39;void myfoo::foo(int)&#39; cannot be overloaded with &#39;void myfoo::foo(int)&#39;
10 | void foo(const int x);
    |      ^~~
&amp;lt;source&amp;gt;:9:6: note: previous declaration &#39;void myfoo::foo(int)&#39;
    9 | void foo(int x);
    |      ^~~
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;const-with-member-functions&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-with-member-functions&quot;&gt;#&lt;/a&gt; &lt;code&gt;const&lt;/code&gt; with member functions&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;const&lt;/code&gt; can be applied to member functions like so:&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyClass&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The advice for using &lt;code&gt;const&lt;/code&gt; in regular functions apply here too.&lt;/p&gt;
&lt;p&gt;Consider &lt;code&gt;const&lt;/code&gt; when the member function doesn&#39;t change the state of the class. In the above example, since we simply read the value of &lt;code&gt;x&lt;/code&gt;, we&#39;re not modifying the class in any way so it&#39;s appropriate to mark &lt;code&gt;get&lt;/code&gt; as &lt;code&gt;const&lt;/code&gt;-qualified.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;this&lt;/code&gt; pointer also becomes &lt;code&gt;const&lt;/code&gt;-qualified by the compiler in the body of a &lt;code&gt;const&lt;/code&gt; member function.&lt;/p&gt;
&lt;h3 id=&quot;mutable&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#mutable&quot;&gt;#&lt;/a&gt; &lt;code&gt;mutable&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;There is one edge-case to be remindful of when it comes to &lt;code&gt;const&lt;/code&gt; member functions. I&#39;ll illustrate with a common example:&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyClass&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;mutable&lt;/span&gt; mutex mx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; xValue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        mx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        xValue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        mx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unlock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; xValue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a simplified example where we use a mutex to safely get the value of &lt;code&gt;x&lt;/code&gt; since there is concurrency involved. Notice that we call &lt;code&gt;lock&lt;/code&gt; and &lt;code&gt;unlock&lt;/code&gt; which changes the state of &lt;code&gt;mx&lt;/code&gt; -- also changing the state of &lt;code&gt;MyClass&lt;/code&gt;. We can use the &lt;code&gt;mutable&lt;/code&gt; keyword to allow these calls in a &lt;code&gt;const&lt;/code&gt;-qualified member function.&lt;/p&gt;
&lt;p&gt;But why is this useful? The idea is if we have an interface that semantically makes sense to be &lt;code&gt;const&lt;/code&gt; (think of this as read-only), we can use &lt;code&gt;mutable&lt;/code&gt; as an escape hatch to keep our interface sensible. The only reason we needed to use &lt;code&gt;mutable&lt;/code&gt; was due to an implementation detail hidden from the user (i.e. locking/unlocking the mutex). Remember, we only did this because the mutex is a side-effect of safe concurrency -- it is not part of the semantic state of our class and so it&#39;s acceptable to keep it logically separated from our interface.&lt;/p&gt;
&lt;h2 id=&quot;const-with-member-variables&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-with-member-variables&quot;&gt;#&lt;/a&gt; &lt;code&gt;const&lt;/code&gt; with member variables&lt;/h2&gt;
&lt;p&gt;Member variables &lt;code&gt;const&lt;/code&gt;-qualified are generally not useful except for view types (classes which are used as read-only containers for data -- think of &lt;code&gt;std::string_view&lt;/code&gt; semantically).&lt;/p&gt;
&lt;p&gt;Additionally, &lt;code&gt;const&lt;/code&gt;-qualified members may prevent implicitly-defined special member functions such as default constructors.&lt;/p&gt;
&lt;p&gt;For class constants, consider making them &lt;code&gt;static&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;const-with-raw-pointers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-with-raw-pointers&quot;&gt;#&lt;/a&gt; &lt;code&gt;const&lt;/code&gt; with raw pointers&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;const&lt;/code&gt; has a few forms with raw pointers, so use the form most appropriate for your use case:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;int*&lt;/code&gt; - pointer to &lt;code&gt;int&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;int const *&lt;/code&gt; - pointer to &lt;code&gt;const int&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;int * const&lt;/code&gt; - &lt;code&gt;const&lt;/code&gt; pointer to &lt;code&gt;int&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;int const * const&lt;/code&gt; - &lt;code&gt;const&lt;/code&gt; pointer to &lt;code&gt;const int&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;const-with-smart-pointers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-with-smart-pointers&quot;&gt;#&lt;/a&gt; &lt;code&gt;const&lt;/code&gt; with smart pointers&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;const&lt;/code&gt; also shares a few forms with smart pointers, so use the form most appropriate for your use case:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;std::unique_ptr&amp;lt;int&amp;gt;&lt;/code&gt; - exclusive pointer to &lt;code&gt;int&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::unique_ptr&amp;lt;const int&amp;gt;&lt;/code&gt; - exclusive pointer to &lt;code&gt;const int&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;const std::unique_ptr&amp;lt;int&amp;gt;&lt;/code&gt; - &lt;code&gt;const&lt;/code&gt; exclusive pointer to &lt;code&gt;int&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;const std::unique_ptr&amp;lt;const int&amp;gt;&lt;/code&gt; - &lt;code&gt;const&lt;/code&gt; exclusive pointer to &lt;code&gt;const int&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;const-with-containers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-with-containers&quot;&gt;#&lt;/a&gt; &lt;code&gt;const&lt;/code&gt; with containers&lt;/h2&gt;
&lt;p&gt;Using &lt;code&gt;const&lt;/code&gt; prevents reassignment of a container and also keeps immutable elements:&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector v &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
v &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ERROR&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector v &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
v&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ERROR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some containers also propagate &lt;code&gt;const&lt;/code&gt; because the &lt;code&gt;operator[]&lt;/code&gt; or &lt;code&gt;at&lt;/code&gt; member functions return &lt;code&gt;const&lt;/code&gt; references:&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Foo&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; v &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;Foo&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Foo&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Foo&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
v&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ERROR: f is not `const`-qualified&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;However, not all containers do this!&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;span s &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
s&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With &lt;code&gt;std::span&lt;/code&gt; you&#39;d need a span of &lt;code&gt;const int&lt;/code&gt; to make this work.&lt;/p&gt;
&lt;h2 id=&quot;const-with-iterators&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-with-iterators&quot;&gt;#&lt;/a&gt; &lt;code&gt;const&lt;/code&gt; with iterators&lt;/h2&gt;
&lt;p&gt;Most people are familiar with &lt;code&gt;begin&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; on containers to express the begin and end iterators respectively. The standard library also provides their &lt;code&gt;const&lt;/code&gt; equivalents: &lt;code&gt;cbegin&lt;/code&gt; and &lt;code&gt;cend&lt;/code&gt;. These return the &lt;code&gt;const&lt;/code&gt;-equivalent iterators into the container.&lt;/p&gt;
&lt;p&gt;These are useful when you want to express algorithms or ranges where you don&#39;t intend to mutate container elements.&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector v &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cbegin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;plus&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// sum == 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;lambda-parameters&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#lambda-parameters&quot;&gt;#&lt;/a&gt; Lambda parameters&lt;/h3&gt;
&lt;p&gt;Lambdas don&#39;t work differently when it comes to parameters than with functions, but I often see confusion when they are passed to algorithms. Here&#39;s an example:&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector v &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cbegin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function returns the same sum, but while this example compiles, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are not &lt;code&gt;const&lt;/code&gt;. Since we&#39;re taking a copy of a simple type like an &lt;code&gt;int&lt;/code&gt;, this works just fine, but these parameters should be &lt;code&gt;const&lt;/code&gt; for the reasons in the opening section (see: &amp;quot;Why &lt;code&gt;const&lt;/code&gt;?&amp;quot;). We would get a compiler error if we tried to take a mutable reference:&lt;/p&gt;
&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cbegin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ERROR: int&amp;amp; is not `const`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in general, match up the iterator qualification with the lambda parameters unless you&#39;re doing non-trivial work (in that case, it probably makes sense to move this out into a free/member function).&lt;/p&gt;
&lt;h2 id=&quot;const-with-ranges&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/const-in-cpp/#const-with-ranges&quot;&gt;#&lt;/a&gt; &lt;code&gt;const&lt;/code&gt; with ranges&lt;/h2&gt;
&lt;p&gt;Ranges with &lt;code&gt;const&lt;/code&gt; is messy and complicated. In &lt;em&gt;C++20: In Detail&lt;/em&gt; by Nicolai Josuttis, he goes into this topic in much more depth than I can here. Based on my own conclusion from reading his book, &lt;code&gt;const&lt;/code&gt; is probably too dangerous to use safely with ranges until a bunch of problems get fixed in versions later than C++20, which is a shame because of the benefits of &lt;code&gt;const&lt;/code&gt;.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <title>It&#39;s okay to suffer a little bit</title>
        <link href="https://anthony-calandra.com/b/its-okay-to-suffer-a-little-bit/" />
        <updated>2024-08-18T00:00:00Z</updated>
        <id>https://anthony-calandra.com/b/its-okay-to-suffer-a-little-bit/</id>
        <content type="html">&lt;h1 id=&quot;its-okay-to-suffer-a-little-bit&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://anthony-calandra.com/b/its-okay-to-suffer-a-little-bit/#its-okay-to-suffer-a-little-bit&quot;&gt;#&lt;/a&gt; It&#39;s okay to suffer a little bit&lt;/h1&gt;
&lt;p&gt;Sometimes it&#39;s good to suffer for a bit, whether it be a problem you don&#39;t know how to solve, a bug you can&#39;t figure out, or even trying to find a job. Problem-solving is one of those core life skills we should be developing endlessly. If you always look for others when you get stuck, you become dependent on them. Struggling is when we start thinking outside the box, trying &lt;em&gt;anything&lt;/em&gt; we can to make it work. You know you&#39;re in the trenches when you need to stop what you&#39;re doing, clear your mind, and sink deep into thought about how to approach next steps. Commonly for me this is when I&#39;m recompiling some code and thinking &amp;quot;if this isn&#39;t the fix then I don&#39;t know what is...&amp;quot; When I say that to myself then I know I&#39;m really in deep.&lt;/p&gt;
&lt;p&gt;Often I end up figuring it out. Other times that&#39;s when I had to learn to ask others for help.&lt;/p&gt;
&lt;p&gt;An example of this in my life is when I was a university student looking for my first internship. It was Spring 2014 and my skills as a software developer were mostly PHP, SQL, JavaScript and some HTML/CSS. I developed these skills working in mostly open-source developing forum software plugins, and even did a few freelancing gigs on the side. So given my experience, I was extremely confident that I would be hired by a prestigious company in the first round.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Everyone has a plan until they get punched in the mouth.&amp;quot; - Mike Tyson&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Instead I didn&#39;t get &lt;strong&gt;any&lt;/strong&gt; job in my field, spending the summer working in customer service. I was devastated.&lt;/p&gt;
&lt;p&gt;Despite feeling at my lowest it was a big boost for my growth. Because of this situation, I reassessed my skills and decided to learn some of the &amp;quot;hot&amp;quot; new tech at the time which was server-side JavaScript (NodeJS). I spent all summer developing my skills and working on side-projects to make myself more employable. During the next co-op cycle––Spring 2015––I interviewed with a few companies and chose to begin my career as a full-stack developer intern at SugarCRM in the Bay Area. Looking back, I&#39;m glad I didn&#39;t get a job during that first year.&lt;/p&gt;
&lt;p&gt;It&#39;s okay to suffer a little bit.&lt;/p&gt;
</content>
    </entry>
</feed>
