title: How to validate Lua table keys from C++
body: <p>I am trying to use Lua for the configuration of a C++ application and am having trouble generating helpful messages when something is wrong in the configuration, not the the Lua syntax.</p>
  
  <p>For example, suppose the following is a valid configuration:</p>
  
  <pre><code>foo = { a = 0, b = 'bar' }
  </code></pre>
  
  <p>but the user actually typed this:</p>
  
  <pre><code>foo = { a = 0, c = 'bar' }
  </code></pre>
  
  <p>Now, the app knows that foo can have fields a and b.  It can load foo and get the value of a.  It can even tell that b is not set and use a default.  But I want to detect that c is present and report a warning.</p>
  
  <p>Here is an extract of my attempt at that which blows up:</p>
  
  <pre><code>static void check_table(lua_State* L)
  {
      lua_pushnil(L);
  
      while ( lua_next(L, -2) )
      {
          // key at -2 and value at -1
          if ( lua_isstring(L, -2) )
          {
              const char* key = lua_tostring(L, -2);
              // validate here; just printing key for now
              cout &lt;&lt; key &lt;&lt; endl;
          }
          lua_pop(L, 1);
      }
  }
  </code></pre>
  
  <p>This works fine as long as the table is not actually an array.  When I hit one of those, it dies on the second iteration with this:</p>
  
  <pre><code>...
  1
  PANIC: unprotected error in call to Lua API (invalid key to 'next')
  </code></pre>
  
  <p>which I attribute to this from the Lua reference page:</p>
  
  <pre><code>"If the value is a number, then lua_tolstring also changes the actual value in the
   stack to a string. (This change confuses lua_next when lua_tolstring is applied to
   keys during a table traversal.)"
  </code></pre>
  
  <p>Any way around this?  I am open to alternate approaches.  Ideally a message could be emitted like:</p>
  
  <p>WARNING: conf.lua line 18: table foo does not use key 'c', ignored</p>
  
  <p>(The Lua debug API doesn't give the file name and line number either, but that is a different topic.)</p>
  
  <p>PS: I know, c could benign, but it could also be a typo.  In a large configuration, ignoring such things could lead to hours of head scratching.</p>