c++gccgperf

Avoid 'warning: declaration UserSuppliedStruct does not declare anything' in gperf output file


Given such a gperf file with User-supplied struct:

%define class-name Table
%define lookup-function-name m

%struct-type
%language=C++

%{
#include <cstring>
#include <cstdio>
// defination of LookupTableElement is put to a header file in the real project and included in
namespace bar {
  struct LookupTableElement {
    const char *name;
    void (*func) ();
  };
}

// a handler
void ack() {
  puts("you said hello");
}

// namespace bar {
%}
struct bar::LookupTableElement;//gperf needs the declaration
%%
######
hello,     ack
######
%%
// } // end namespace bar
int main() {
  auto p = Table::m("hello", sizeof("hello") - 1);
  if (!p) return 1;
  p->func();
  return 0;
}

To compile:

$ gperf foo.gperf > foo.cc && g++ -std=c++0x foo.cc

makes g++ (gcc 4.7.3 and 4.8.2 tested) warn:

foo.gperf:26:13: warning: declaration ‘struct bar::LookupTableElement’ does not declare anything [enabled by default]
struct bar::LookupTableElement;//declare look up table's element
            ^

If namespace bar is removed, there will be no warning anymore.

What's the best way to avoid the warning?

  1. Should I define bar::LookupTableElement in each gperf file (there are more than one gperf using the struct)?
  2. Or use something like (haven't found the switch to turn it off in GCC manual)?
  3. Uncommment // namespace bar { and // } // end namespace bar and change struct bar::LookupTableElement to struct LookupTableElement. But in this way we will drag a lot of stuff into the namespace (have a look at the generated foo.cc you'd know that).
  4. Any other idea?

Solution

  • There is an option to gperf:

       -T, --omit-struct-type
              Prevents  the  transfer  of  the type declaration to the output file. Use
              this option if the type is already defined elsewhere.
    

    So, without any namespaces tricks,

    struct bar::LookupTableElement;
    

    and this option it generates completely acceptable code (e.g. gperf -T foo.gperf > foo.gperf.cpp).