kdgwill
kdgwill

Reputation: 2199

Clang unknown class name 'exception'

For some odd reason I am having difficulties throwing an exception in C++. I throw without catching std::invalid_argument from the stdexcept header file. I have no real intention of catching as i want the application to fail anyway if the error occurs.

It seemed to be working fine until I #included the function definition class into the namespace of the header declaration. It was added outside of the namespace prior since they are template definitions and I wanted to separate the header from its definition; however, I realized this caused a subtle issue that I did not realized until only recently.

Is their something I am missing? I am using clang btw

Project Compilation
.
.
.
.
.
Compiling CPP file TrieTest.cpp ...
In file included from TrieTest.cpp:4:
In file included from ./Trie.hpp:62:
In file included from ./Trie.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/stdexcept:55:30: error: unknown class name 'exception'; did you mean
      '::std::exception'?
  class logic_error : public exception 
                             ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/exception:60:9: note: '::std::exception' declared here
  class exception
        ^
In file included from TrieTest.cpp:4:
In file included from ./Trie.hpp:62:
In file included from ./Trie.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/stdexcept:112:32: error: expected class name
  class runtime_error : public exception 
                               ^
2 errors generated.

EDIT: A bit of the src Also I compile with clang++ -Wall -Wextra -g -std=c++11 TrieTest.cpp -o TrieTest;

"Trie.h"

#ifndef COM_WORDGAME_UTILITY_TRIE_HPP
#define COM_WORDGAME_UTILITY_TRIE_HPP
#include <string>
using std::string;

namespace wordgame_utility{
template<typename value>
class Trie{

      ...Trie Function Declarations

};

//The compiler may not complain initialliy however
//Templates cause visibility issues with user code and is normally defined in the header
//this is a work around 
#include "Trie.cpp"
}

#endif

"Trie.cpp" head -n 8

#include "Trie.hpp"
#include <stdexcept>

using namespace wordgame_utility;

template<typename value>
using TrieNode = typename Trie<value>::TrieNode;
...Trie Function Definitions

Upvotes: 0

Views: 2770

Answers (1)

Matthieu M.
Matthieu M.

Reputation: 300159

You have a cyclic include in your code.

Trie.hpp includes Trie.cpp which includes Trie.hpp. This is not meant to work in C++, where include is a literal inclusion (think, copy/pasting the included file at the point of the #include directive).

You need to define template methods into the header, or into a third file, that's all there is.


What is the effect of this cycle ? In general, poor error messages, as you can see by yourself.

In your case... let's play preprocessor ourselves:

// begin #include "Trie.hpp"
#define COM_WORDGAME_UTILITY_TRIE_HPP

// begin #include <string>
namespace std {
    ...
}
// end #include <string>

using std::string;

namespace wordgame_utility{
    template<typename value>
    class Trie{

      ...Trie Function Declarations

    };

    //The compiler may not complain initialliy however
    //Templates cause visibility issues with user code
    // and is normally defined in the header
    //this is a work around 

// begin #include "Trie.cpp"

// begin #include "Trie.hpp"
// -- empty because of the include guards --
// end #include "Trie.hpp"

// begin #include <stdexcept>
    namespace std {
        class logic_exception: public exception { };
    }
// end #include <stdexcept>

    using namespace wordgame_utility;

    template<typename value>
    using TrieNode = typename Trie<value>::TrieNode;
    ...Trie Function Definitions

// end #include "Trie.cpp"

} // namespace wordgame_utility

// end #include "Trie.hpp"

As you can see, it's a mess. The combination of using #include within an open namespace and having cyclic includes is downright ugly.

Fortunately, in the (near ?) future, this will be improved if modules are adopted, which are just a much saner alternative to textual inclusion.

Upvotes: 4

Related Questions