Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Alex_H_6
Beginner
247 Views

Incomplete Type with Forward Declaration on Intel C++ Compiler 16.0 (Works fine in MinGW, Clang, GCC, VS 14 2015)

Google provides a regular expression library open source, which can be found here.

The library successfully compiles, and works in compilation units using GCC (I believe 4.8 and above), Clang, and MSVC 14 2015. (I've personally tested all of the above). However, it does not work with Intel's C++ Compiler, producing the following error multiple times:

...\re2\re2/re2.h(363): error : incomplete type is not allowed
        return Apply(FullMatchN, text, re, Arg(std::forward<A>(a))...);
                                           ^

...\re2\re2/re2.h(368): error : incomplete type is not allowed
        return Apply(PartialMatchN, text, re, Arg(std::forward<A>(a))...);
                                              ^

...\re2\re2/re2.h(373): error : incomplete type is not allowed
        return Apply(ConsumeN, input, re, Arg(std::forward<A>(a))...);

...\re2\re2/re2.h(378): error : incomplete type is not allowed
        return Apply(FindAndConsumeN, input, re, Arg(std::forward<A>(a))...);

Now, in this header, they define the incomplete type as follows:

class RE2 {
 public:
  // We convert user-passed pointers into special Arg objects
  class Arg;

/** Skipping many lines
 * ......................
 */

 public:
  // In order to allow FullMatch() et al. to be called with a varying number
  // of arguments of varying types, we use two layers of variadic templates.
  // The first layer constructs the temporary Arg objects. The second layer
  // (above) constructs the array of pointers to the temporary Arg objects.

  template <typename... A>
  static bool FullMatch(const StringPiece& text, const RE2& re, A&&... a) {
    return Apply(FullMatchN, text, re, Arg(std::forward<A>(a))...);
  }

  template <typename... A>
  static bool PartialMatch(const StringPiece& text, const RE2& re, A&&... a) {
    return Apply(PartialMatchN, text, re, Arg(std::forward<A>(a))...);
  }

  template <typename... A>
  static bool Consume(StringPiece* input, const RE2& re, A&&... a) {
    return Apply(ConsumeN, input, re, Arg(std::forward<A>(a))...);
  }

  template <typename... A>
  static bool FindAndConsume(StringPiece* input, const RE2& re, A&&... a) {
    return Apply(FindAndConsumeN, input, re, Arg(std::forward<A>(a))...);
  }

}

class RE2::Arg {
 public:
  // Empty constructor so we can declare arrays of RE2::Arg
  Arg();

  // Constructor specially designed for NULL arguments
  Arg(void*);
}

For some reason, the Intel C++ compiler does not seem to recognize the forward declaration and raises an error. I'm hoping this can be fixed soon, as this is an excellent library.

 

 

0 Kudos
1 Reply
James_Burgess
Beginner
247 Views

Hi,

 We've just run into this as well with icc 17.0 update 4 on Windows (only). There is the new rule about template arguments in c++11 needing to be fully defined before defined but given that clang (Xcode7+), gcc (4.8+), msvc (14+) and icc on non-windows platforms all accept this code I suspect there is an exception if the argument is declared in the same scope? Anyway, this seems weird and unnecessarily different.

FWIW in this specific case if you move the definition of Arg inside the RE2 class, then re2 will compile on all compilers.

- James

 

Reply