diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc
index 98c6fe98e94d0a578de9abf4907f92ec30799eb9..3fa42a6742e7c13f6b603b839889f2e12da1a47e 100644
--- a/src/macro/Directives.cc
+++ b/src/macro/Directives.cc
@@ -55,9 +55,9 @@ Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path>
       ifstream incfile(filename, ios::binary);
       if (incfile.fail())
         {
-          for (auto & file : paths)
+          for (const auto & dir : paths)
             {
-              incfile = ifstream(file / filename, ios::binary);
+              incfile = ifstream(dir / filename, ios::binary);
               if (incfile.good())
                 break;
             }
@@ -65,7 +65,7 @@ Include::interpret(ostream &output, bool no_line_macro, vector<filesystem::path>
             {
               ostringstream errmsg;
               errmsg << "   * " << current_path().string() << endl;
-              for (auto & dir : paths)
+              for (const auto & dir : paths)
                 errmsg << "   * " << absolute(dir).string() << endl;
               error(StackTrace("@#includepath", "Could not open " + filename.string() +
                                ". The following directories were searched:\n" + errmsg.str(), location));
@@ -228,7 +228,7 @@ For::interpret(ostream &output, bool no_line_macro, vector<filesystem::path> &pa
         }
 
       bool printLine = true;
-      for (auto & statement : statements)
+      for (const auto & statement : statements)
         {
           if (printLine)
             {
@@ -275,7 +275,7 @@ void
 If::interpretBody(const vector<DirectivePtr> &body, ostream &output, bool no_line_macro, vector<filesystem::path> &paths)
 {
   bool printLine = !no_line_macro;
-  for (auto & statement : body)
+  for (const auto & statement : body)
     {
       if (printLine)
         {
diff --git a/src/macro/Driver.cc b/src/macro/Driver.cc
index 5ad37aa05ad7875d0598e6944b30c296c93c3d11..e1f18cdc4fffe0766ffaf6142a06bdac86566ec7 100644
--- a/src/macro/Driver.cc
+++ b/src/macro/Driver.cc
@@ -69,7 +69,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
 
   // Interpret parsed statements
   bool printLine = true;
-  for (auto & statement : statements)
+  for (const auto & statement : statements)
     {
       if (printLine)
         {
diff --git a/src/macro/Environment.cc b/src/macro/Environment.cc
index 6cdabc1c16a0b54143eead34bbdf5dafcec107c0..87cd033d2582ebc205ad1f33edcfb21d3da1d82e 100644
--- a/src/macro/Environment.cc
+++ b/src/macro/Environment.cc
@@ -107,7 +107,7 @@ Environment::print(ostream &output, const vector<string> &vars, int line, bool s
     output << "Macro Variables:" << endl;
 
   if (vars.empty())
-    for (auto & it : variables)
+    for (const auto & it : variables)
       printVariable(output, it.first, line, save);
   else
     for (const auto & it : vars)
diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc
index ad305e24cbd70207f532c7707383f2c5c1fb168a..d48683b595eee03ea573486c5913257706d4f3da 100644
--- a/src/macro/Expressions.cc
+++ b/src/macro/Expressions.cc
@@ -355,7 +355,7 @@ Array::minus(const BaseTypePtr &btp) const
   /* Highly inefficient algorithm for computing set difference
      (but vector<T> is not suited for that...) */
   vector<ExpressionPtr> arr_copy;
-  for (auto & it : arr)
+  for (const auto & it : arr)
     {
       auto itbtp = dynamic_pointer_cast<BaseType>(it);
       auto it2 = btp2->arr.cbegin();
@@ -376,8 +376,8 @@ Array::times(const BaseTypePtr &btp) const
   if (!btp2)
     throw StackTrace("Type mismatch for operands of * operator");
 
-  for (auto & itl : arr)
-    for (auto & itr : btp2->getValue())
+  for (const auto & itl : arr)
+    for (const auto & itr : btp2->getValue())
       {
         vector<ExpressionPtr> new_tuple;
         if (dynamic_pointer_cast<Real>(itl) || dynamic_pointer_cast<String>(itl))
@@ -390,7 +390,7 @@ Array::times(const BaseTypePtr &btp) const
         if (dynamic_pointer_cast<Real>(itr) || dynamic_pointer_cast<String>(itr))
           new_tuple.push_back(itr);
         else if (dynamic_pointer_cast<Tuple>(itr))
-          for (auto & tit : dynamic_pointer_cast<Tuple>(itr)->getValue())
+          for (const auto & tit : dynamic_pointer_cast<Tuple>(itr)->getValue())
             new_tuple.push_back(tit);
         else
           throw StackTrace("Array::times: unsupported type on rhs");
@@ -445,13 +445,13 @@ Array::set_union(const BaseTypePtr &btp) const
     throw StackTrace("Arguments of the union operator (|) must be sets");
 
   vector<ExpressionPtr> new_values = arr;
-  for (auto & it : btp2->arr)
+  for (const auto & it : btp2->arr)
     {
       bool found = false;
       auto it2 = dynamic_pointer_cast<BaseType>(it);
       if (!it2)
         throw StackTrace("Type mismatch for operands of in operator");
-      for (auto & nvit : new_values)
+      for (const auto & nvit : new_values)
         {
           auto v2 = dynamic_pointer_cast<BaseType>(nvit);
           if (!v2)
@@ -476,12 +476,12 @@ Array::set_intersection(const BaseTypePtr &btp) const
     throw StackTrace("Arguments of the intersection operator (|) must be sets");
 
   vector<ExpressionPtr> new_values;
-  for (auto & it : btp2->arr)
+  for (const auto & it : btp2->arr)
     {
       auto it2 = dynamic_pointer_cast<BaseType>(it);
       if (!it2)
         throw StackTrace("Type mismatch for operands of in operator");
-      for (auto & nvit : arr)
+      for (const auto & nvit : arr)
         {
           auto v2 = dynamic_pointer_cast<BaseType>(nvit);
           if (!v2)
@@ -499,7 +499,7 @@ Array::set_intersection(const BaseTypePtr &btp) const
 BoolPtr
 Array::contains(const BaseTypePtr &btp) const
 {
-  for (auto & v : arr)
+  for (const auto & v : arr)
     {
       auto v2 = dynamic_pointer_cast<BaseType>(v);
       if (!v2)
@@ -514,7 +514,7 @@ RealPtr
 Array::sum() const
 {
   double retval = 0;
-  for (auto & v : arr)
+  for (const auto & v : arr)
     {
       auto v2 = dynamic_pointer_cast<Real>(v);
       if (!v2)
@@ -563,7 +563,7 @@ Tuple::is_equal(const BaseTypePtr &btp) const
 BoolPtr
 Tuple::contains(const BaseTypePtr &btp) const
 {
-  for (auto & v : tup)
+  for (const auto & v : tup)
     {
       auto v2 = dynamic_pointer_cast<BaseType>(v);
       if (!v2)
@@ -639,7 +639,7 @@ Variable::eval()
       ArrayPtr map = dynamic_pointer_cast<Array>(indices->eval());
       vector<ExpressionPtr> index = map->getValue();
       vector<int> ind;
-      for (auto it : index)
+      for (const auto & it : index)
         // Necessary to handle indexes like: y[1:2,2]
         // In general this evaluates to [[1:2],2] but when subscripting we want to expand it to [1,2,2]
         if (auto db = dynamic_pointer_cast<Real>(it); db)
@@ -650,7 +650,7 @@ Variable::eval()
             ind.emplace_back(*db);
           }
         else if (dynamic_pointer_cast<Array>(it))
-          for (auto it1 : dynamic_pointer_cast<Array>(it)->getValue())
+          for (const auto & it1 : dynamic_pointer_cast<Array>(it)->getValue())
             if (db = dynamic_pointer_cast<Real>(it1); db)
               {
                 if (!*(db->isinteger()))
@@ -1033,7 +1033,7 @@ ExpressionPtr
 Tuple::clone() const noexcept
 {
   vector<ExpressionPtr> tup_copy;
-  for (auto & it : tup)
+  for (const auto & it : tup)
     tup_copy.emplace_back(it->clone());
   return make_shared<Tuple>(tup_copy, env, location);
 }
@@ -1042,7 +1042,7 @@ ExpressionPtr
 Array::clone() const noexcept
 {
   vector<ExpressionPtr> arr_copy;
-  for (auto & it : arr)
+  for (const auto & it : arr)
     arr_copy.emplace_back(it->clone());
   return make_shared<Array>(arr_copy, env, location);
 }
@@ -1051,7 +1051,7 @@ ExpressionPtr
 Function::clone() const noexcept
 {
   vector<ExpressionPtr> args_copy;
-  for (auto & it : args)
+  for (const auto & it : args)
     args_copy.emplace_back(it->clone());
   return make_shared<Function>(name, args_copy, env, location);
 }
@@ -1091,7 +1091,7 @@ string
 Function::to_string() const noexcept
 {
   string retval = name + "(";
-  for (auto & it : args)
+  for (const auto & it : args)
     retval += it->to_string() + ", ";
   return retval.substr(0, retval.size()-2) + ")";
 }
diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy
index b84009af4dd727985b8ee7d869efdadddfb68b63..b6bf3893a6204a03fa717f1c1f0eb6f463586ad6 100644
--- a/src/macro/Parser.yy
+++ b/src/macro/Parser.yy
@@ -176,7 +176,7 @@ for : FOR { driver.pushContext(); } expr IN expr for_when EOL statements ENDFOR
         if (tmpv)
           vvnp.emplace_back(tmpv);
         else if (tmpt)
-          for (auto & it : tmpt->getValue())
+          for (const auto & it : tmpt->getValue())
             {
               auto vnp = dynamic_pointer_cast<Variable>(it);
               if (!vnp)