diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc
index 99d1cc32319de23aa472da2ba535c7d83a5b9c65..42150333f9e18efe1a225c29b6f4d09d764de9d9 100644
--- a/src/macro/Directives.cc
+++ b/src/macro/Directives.cc
@@ -189,10 +189,7 @@ void
 EchoMacroVars::interpret(ostream& output, Environment& env,
                          [[maybe_unused]] vector<filesystem::path>& paths)
 {
-  if (save)
-    env.print(output, vars, location.begin.line, true);
-  else
-    env.print(cout, vars);
+  env.print(save ? output : cout, vars, location.begin.line, save);
   printEndLineInfo(output);
 }
 
diff --git a/src/macro/Environment.cc b/src/macro/Environment.cc
index 34686c9cfc7e573875eda973d80a560e2dfaf557..46519e6c1253de2e10d33470fe3e8b0474e388c8 100644
--- a/src/macro/Environment.cc
+++ b/src/macro/Environment.cc
@@ -103,11 +103,10 @@ Environment::isFunctionDefined(const string& name) const noexcept
 }
 
 void
-Environment::print(ostream& output, const vector<string>& vars, const optional<int>& line,
-                   bool save) const
+Environment::print(ostream& output, const vector<string>& vars, int line, bool save) const
 {
   if (!save && !variables.empty())
-    output << "Macro Variables:" << endl;
+    output << "Macro Variables (at line " << line << "):" << endl;
 
   // For sorting the symbols in a case-insensitive way, see #128
   auto case_insensitive_string_less = [](const string& a, const string& b) {
@@ -130,7 +129,7 @@ Environment::print(ostream& output, const vector<string>& vars, const optional<i
         printVariable(output, it, line, save);
 
   if (!save && !functions.empty())
-    output << "Macro Functions:" << endl;
+    output << "Macro Functions (at line " << line << "):" << endl;
 
   if (vars.empty())
     {
@@ -150,11 +149,9 @@ Environment::print(ostream& output, const vector<string>& vars, const optional<i
 }
 
 void
-Environment::printVariable(ostream& output, const string& name, const optional<int>& line,
-                           bool save) const
+Environment::printVariable(ostream& output, const string& name, int line, bool save) const
 {
-  assert(!save || line);
-  output << (save ? "options_.macrovars_line_" + to_string(*line) + "." : "  ") << name << " = ";
+  output << (save ? "options_.macrovars_line_" + to_string(line) + "." : "  ") << name << " = ";
   getVariable(name)->eval(const_cast<Environment&>(*this))->print(output, save);
   if (save)
     output << ";";
@@ -162,12 +159,10 @@ Environment::printVariable(ostream& output, const string& name, const optional<i
 }
 
 void
-Environment::printFunction(ostream& output, const string& name, const optional<int>& line,
-                           bool save) const
+Environment::printFunction(ostream& output, const string& name, int line, bool save) const
 {
-  assert(!save || line);
   auto [func_signature, func_body] = getFunction(name);
-  output << (save ? "options_.macrovars_line_" + to_string(*line) + ".function." : "  ");
+  output << (save ? "options_.macrovars_line_" + to_string(line) + ".function." : "  ");
   if (save)
     {
       func_signature->printName(output);
diff --git a/src/macro/Environment.hh b/src/macro/Environment.hh
index 4a807cdd9213db14419cd65f26f5df41781890c5..5345b8e4f843c0cda8c7901be2b69793cdeca164 100644
--- a/src/macro/Environment.hh
+++ b/src/macro/Environment.hh
@@ -55,12 +55,9 @@ public:
   {
     return isVariableDefined(name) || isFunctionDefined(name);
   }
-  void print(ostream& output, const vector<string>& vars, const optional<int>& line = nullopt,
-             bool save = false) const;
-  void printVariable(ostream& output, const string& name, const optional<int>& line,
-                     bool save) const;
-  void printFunction(ostream& output, const string& name, const optional<int>& line,
-                     bool save) const;
+  void print(ostream& output, const vector<string>& vars, int line, bool save) const;
+  void printVariable(ostream& output, const string& name, int line, bool save) const;
+  void printFunction(ostream& output, const string& name, int line, bool save) const;
   [[nodiscard]] size_t
   size() const noexcept
   {