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 :)
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.
You can use Clang instead of GCC as a compiler for any package by overriding stdenv , which contains the compilation toolchain, with: stdenv = pkgs.
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.
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.
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.
operator>>
is defined for istringstream
. Try to include #include <sstream>
file in your source before wherever namespace english
is defined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With