Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot compile code with clang, but works with gcc

Tags:

c++

xcode

clang++

I am trying to fix some bugs in an open source C++ project and the original author is currently too busy with his academic life to help. The code compiles just fine with gcc-4.9 installed via macports. And I have been debugging with lldb on the command line. However, if possible, I would like to get the code to compile with clang since that would let me use Xcode and lldb together and make the bug easier to isolate.

When I try to compile the code with clang, I get the following error:

In file included from ./src/include/hash.h:25:
./src/include/hash_stream.h:18:11: error: call to function 'operator>>' that is neither visible in the template definition
  nor found by argument-dependent lookup
  iss >> table[key] ;
      ^
./src/common/tagger/implementations/collins/tagger.h:118:9: note: in instantiation of function template specialization
  'operator>><CWord, english::CTag>' requested here
  i >> (*m_TopTags);
    ^
./src/english/tags.h:29:23: note: 'operator>>' should be declared prior to the call site or in namespace 'english'
inline std::istream & operator >> (std::istream &is, english::CTag &tag) {
                  ^
1 error generated.
make: *** [obj/english.postagger.o] Error 1

This error occurs in this file which is basically trying to read a key, a :, and a value separated by spaces into a custom hash map. I have read the relevant section in the clang compatibility guide but I cannot figure out what I need to change to get this to compile.

EDIT: Per @m-s, I modified src/common/tagger/implementations/collins/tagger_include.h to move tags.h above hash_stream.h and that seemed to fix that error. However, I now run into a new error:

In file included from ./src/common/conparser/implementations/muhua/weight.cpp:13:
In file included from ./src/common/conparser/implementations/muhua/weight.h:13:
In file included from ./src/common/conparser/weight_base.h:13:
In file included from ./src/common/conparser/base_include.h:10:
In file included from ./src/english/tags.h:43:
In file included from ./src/english/pos/penn_morph.h:15:
In file included from ./src/include/knowledge/tagdict.h:15:
In file included from ./src/include/hash.h:25:
./src/include/hash_stream.h:15:11: error: call to function 'operator>>' that is neither visible in the template definition
      nor found by argument-dependent lookup
      iss >> key;
          ^
./src/include/learning/perceptron/hashmap_score_packed.h:282:7: note: in instantiation of function template specialization
      'operator>><std::__1::pair<unsigned long, unsigned long>, CPackedScore<double, 2048> >' requested here
   is >> static_cast< CHashMap< K, CPackedScore<SCORE_TYPE, PACKED_SIZE> > &>(score_map) ;
      ^
./src/common/conparser/implementations/muhua/weight.cpp:48:27: note: in instantiation of function template specialization
      'operator>><std::__1::pair<unsigned long, unsigned long>, double, 2048>' requested here
   iterate_templates(file >>,;);
                          ^
./src/common/conparser/implementations/muhua/weight.h:133:4: note: expanded from macro 'iterate_templates'
   left(m_mapS0cmN0tm)right\
   ^
./src/include/pair_stream.h:16:16: note: 'operator>>' should be declared prior to the call site
std::istream & operator >> (std::istream &is, std::pair<T1, T2> &p) {
               ^
1 error generated.
make: *** [obj/english.conparser/weight.o] Error 1

I tried to include pair_stream.h before hash.h but that doesn't seem to work and I am stumped again. Any help would be much appreciated.

EDIT 2: I actually thought about things and took another stab at this and now it all works. Thanks, everyone! StackOverflow is awesome :)

like image 655
DesiLinguist Avatar asked Jun 24 '15 20:06

DesiLinguist


People also ask

Is Clang compatible with GCC?

Yes, for C code Clang and GCC are compatible (they both use the GNU Toolchain for linking, in fact.) You just have to make sure that you tell clang to create compiled objects and not intermediate bitcode objects. C ABI is well-defined, so the only issue is storage format.

Can I use Clang instead of GCC?

You can use Clang instead of GCC as a compiler for any package by overriding stdenv , which contains the compilation toolchain, with: stdenv = pkgs.

Is GCC better than Clang?

Clang is much faster and uses far less memory than GCC. Clang aims to provide extremely clear and concise diagnostics (error and warning messages), and includes support for expressive diagnostics. GCC's warnings are sometimes acceptable, but are often confusing and it does not support expressive diagnostics.

How do you compile with Clang?

2.4. To compile a C++ program on the command line, run the clang++ compiler as follows: $ scl enable llvm-toolset-6.0 'clang++ -o output_file source_file ...' This creates a binary file named output_file in the current working directory. If the -o option is omitted, the clang++ compiler creates a file named a.


2 Answers

As the error message states, std::istream & operator >> (std::istream &is, english::CTag &tag) is defined in src/english/tags.h. But since the template in src/include/hash_stream.h which calls it is declared before that file is included, the error occurs.

The documentation already provides the solution:

Make sure the function you want to call is declared before the template that might call it. This is the only option if none of its argument types contain classes. You can do this either by moving the template definition, or by moving the function definition, or by adding a forward declaration of the function before the template.

So either make sure this file is included before including src/include/hash_stream.h, or apply any of the solutions provided by the documentation.

like image 59
m.s. Avatar answered Oct 10 '22 13:10

m.s.


operator>> is defined for istringstream. Try to include #include <sstream> file in your source before wherever namespace english is defined.

like image 32
JamesWebbTelescopeAlien Avatar answered Oct 10 '22 13:10

JamesWebbTelescopeAlien