0

I did try to find my specific issue, but the closest I found was this question where the issue was with global variables.

I need make a lexer header file along with it's cpp file to use in main.cpp. here are the two lexer files:

// lexer.hpp
#ifndef LEXER_HPP
#define LEXER_HPP
// Some include files, not really relevant

namespace interpreter
{
    namespace lex
    {
        enum class TokType : char;
        typedef std::vector<std::pair<TokType, std::string>> TokenList;
        typedef std::pair<TokType, std::string> Token;
        TokenList tokenizeString(std::string tokStr);
    } // namespace lex
} // namespace interpreter

#endif
/* --------------------------------------*/
// lexer.cpp
// Again, some not-really-necessary include files
#include "lexer.hpp"
using namespace interpreter::lex;

enum class TokType : char {/* Stuff */};
TokenList tokenizeString(std::string tokStr) {/* Stuff*/};

When I use this stuff in main.cpp and compile, I get the following error:

/usr/bin/ld: /tmp/cc3XtuwW.o: in function `main':
main.cpp:(.text+0x7d): undefined reference to `interpreter::lex::tokenizeString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
collect2: error: ld returned 1 exit status

Clearly, something is wrong with my function, but I cannot for the life of me figure out what is actually wrong.

Here's some other information if you need it:

  • I turned my lexer.cpp into a .o file. Whether I use the .cpp file or the .o file does not make a difference, though.
  • How I compiled main.cpp: g++ -o main main.cpp lexer.o
  • lexer.hpp, lexer.cpp, lexer.o and main.cpp are all in the same directory.
2
  • You have declared tokenizeString and the compiler have found it. But have you actually defined the function in a .cpp file that is linked in? Commented Jan 31, 2021 at 13:28
  • Yes, the definition is in lexer.cpp which I compile along with main.cpp Commented Jan 31, 2021 at 13:30

1 Answer 1

1

Do this

TokenList interpreter::lex::tokenizeString(std::string tokStr)
{
    /* Stuff*/
}

or this

namespace interpreter { namespace lex {
    TokenList tokenizeString(std::string tokStr)
    {
        /* Stuff*/
    }
} }

Although you've said using namespace interpreter::lex; that doesn't mean that newly defined names get added to the interpreter::lex namespace.

Sign up to request clarification or add additional context in comments.

2 Comments

I generally don't like using using namespace, the only reason I did this time was that I needed to use the enum values a lot and writing interpreter::lex::TokType::Thing made code really long. Thanks for the help.
@mediocrevegetable1 use either of the two options I've given above. They are compatible with using namespace ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.