Cannot call read function!

Discussion in 'C++' started by davee, Oct 3, 2009.

  1. davee

    davee Guest

    I am trying to use the code posted here:

    http://www.senzee5.com/2008/02/java-style-properties-files-in-c.html


    I use it like this:


    #include "propertyutil.h"
    int main(){

    PropertyUtil properties;
    typedef PropertyUtil::propertyMapT MapType;
    MapType bob;
    properties.read(config_path.c_str(), bob);

    return 0;
    }

    but I get the error:


    main.cpp:(.text+0xc29): undefined reference to `PropertyUtil::read(char
    const*, std::map<std::basic_string<char, std::char_traits<char>,
    std::allocator<char> >, std::basic_string<char, std::char_traits<char>,
    std::allocator<char> >, std::less<std::basic_string<char,
    std::char_traits<char>, std::allocator<char> > >,
    std::allocator<std::pair<std::basic_string<char, std::char_traits<char>,
    std::allocator<char> > const, std::basic_string<char,
    std::char_traits<char>, std::allocator<char> > > > >&)'




    'read' is:



    class PropertyUtil {
    enum { DEBUG = 0 };

    public:
    typedef std::map<std::string, std::string> PropertyMapT;
    typedef PropertyMapT::value_type value_type;
    typedef PropertyMapT::iterator iterator;

    static void read(const char *filename, PropertyMapT &map);
    ...
    ...



    What am I doing wrong here?
     
    davee, Oct 3, 2009
    #1
    1. Advertising

  2. On 3 Ott, 17:05, davee <> wrote:
    > I am trying to use the code posted here:
    >
    > http://www.senzee5.com/2008/02/java-style-properties-files-in-c.html
    >
    > I use it like this:
    >
    > #include "propertyutil.h"
    > int main(){
    >
    >    PropertyUtil properties;
    >    typedef PropertyUtil::propertyMapT MapType;
    >    MapType bob;
    >    properties.read(config_path.c_str(), bob);
    >
    >    return 0;
    >
    > }
    >
    > but I get the error:
    >
    > main.cpp:(.text+0xc29): undefined reference to `PropertyUtil::read(char
    > const*, std::map<std::basic_string<char, std::char_traits<char>,
    > std::allocator<char> >, std::basic_string<char, std::char_traits<char>,
    > std::allocator<char> >, std::less<std::basic_string<char,
    > std::char_traits<char>, std::allocator<char> > >,
    > std::allocator<std::pair<std::basic_string<char, std::char_traits<char>,
    > std::allocator<char> > const, std::basic_string<char,
    > std::char_traits<char>, std::allocator<char> > > > >&)'
    >
    > 'read' is:
    >
    > class PropertyUtil {
    >      enum { DEBUG = 0 };
    >
    > public:
    >      typedef std::map<std::string, std::string> PropertyMapT;
    >      typedef PropertyMapT::value_type           value_type;
    >      typedef PropertyMapT::iterator             iterator;
    >
    >      static void read(const char *filename, PropertyMapT &map);
    > ..
    > ..
    >
    > What am I doing wrong here?


    An error telling "undefined reference to [whatever]" comes from the
    linker. It means that no available compilation unit defined that thing
    - it is just _declared_, in that header.

    In this very case, find out what library you need, download it and add
    it to your linker references.

    When you get the same kind of errors with your very names, that would
    mean that you forgot to define those names (that is, you just declared
    them, as it happened above).

    Have good time,
    Francesco
    --
    Francesco S. Carta, hobbyist
    http://fscode.altervista.org
     
    Francesco S. Carta, Oct 3, 2009
    #2
    1. Advertising

  3. davee

    davee Guest

    Francesco S. Carta wrote:
    > On 3 Ott, 17:05, davee <> wrote:
    >> I am trying to use the code posted here:
    >>
    >> http://www.senzee5.com/2008/02/java-style-properties-files-in-c.html
    >>
    >> I use it like this:
    >>
    >> #include "propertyutil.h"
    >> int main(){
    >>
    >> PropertyUtil properties;
    >> typedef PropertyUtil::propertyMapT MapType;
    >> MapType bob;
    >> properties.read(config_path.c_str(), bob);
    >>
    >> return 0;
    >>
    >> }
    >>
    >> but I get the error:
    >>
    >> main.cpp:(.text+0xc29): undefined reference to `PropertyUtil::read(char
    >> const*, std::map<std::basic_string<char, std::char_traits<char>,
    >> std::allocator<char> >, std::basic_string<char, std::char_traits<char>,
    >> std::allocator<char> >, std::less<std::basic_string<char,
    >> std::char_traits<char>, std::allocator<char> > >,
    >> std::allocator<std::pair<std::basic_string<char, std::char_traits<char>,
    >> std::allocator<char> > const, std::basic_string<char,
    >> std::char_traits<char>, std::allocator<char> > > > >&)'
    >>
    >> 'read' is:
    >>
    >> class PropertyUtil {
    >> enum { DEBUG = 0 };
    >>
    >> public:
    >> typedef std::map<std::string, std::string> PropertyMapT;
    >> typedef PropertyMapT::value_type value_type;
    >> typedef PropertyMapT::iterator iterator;
    >>
    >> static void read(const char *filename, PropertyMapT &map);
    >> ..
    >> ..
    >>
    >> What am I doing wrong here?

    >
    > An error telling "undefined reference to [whatever]" comes from the
    > linker. It means that no available compilation unit defined that thing
    > - it is just _declared_, in that header.
    >
    > In this very case, find out what library you need, download it and add
    > it to your linker references.
    >
    > When you get the same kind of errors with your very names, that would
    > mean that you forgot to define those names (that is, you just declared
    > them, as it happened above).
    >
    > Have good time,
    > Francesco
    > --
    > Francesco S. Carta, hobbyist
    > http://fscode.altervista.org


    Ah I just needed to add:

    #include "propertyutil.cpp"

    in the end of the propertyutil.h file, seems a bit wierd though. But
    since I am using it in a "header only" library this might be the
    explanation.
     
    davee, Oct 3, 2009
    #3
  4. On 3 Ott, 17:34, davee <> wrote:
    > Francesco S. Carta wrote:
    > > On 3 Ott, 17:05, davee <> wrote:
    > >> I am trying to use the code posted here:

    >
    > >>http://www.senzee5.com/2008/02/java-style-properties-files-in-c.html

    >
    > >> I use it like this:

    >
    > >> #include "propertyutil.h"
    > >> int main(){

    >
    > >> PropertyUtil properties;
    > >> typedef PropertyUtil::propertyMapT MapType;
    > >> MapType bob;
    > >> properties.read(config_path.c_str(), bob);

    >
    > >> return 0;

    >
    > >> }

    >
    > >> but I get the error:

    >
    > >> main.cpp:(.text+0xc29): undefined reference to `PropertyUtil::read(char
    > >> const*, std::map<std::basic_string<char, std::char_traits<char>,
    > >> std::allocator<char> >, std::basic_string<char, std::char_traits<char>,
    > >> std::allocator<char> >, std::less<std::basic_string<char,
    > >> std::char_traits<char>, std::allocator<char> > >,
    > >> std::allocator<std::pair<std::basic_string<char, std::char_traits<char>,
    > >> std::allocator<char> > const, std::basic_string<char,
    > >> std::char_traits<char>, std::allocator<char> > > > >&)'

    >
    > >> 'read' is:

    >
    > >> class PropertyUtil {
    > >> enum { DEBUG = 0 };

    >
    > >> public:
    > >> typedef std::map<std::string, std::string> PropertyMapT;
    > >> typedef PropertyMapT::value_type value_type;
    > >> typedef PropertyMapT::iterator iterator;

    >
    > >> static void read(const char *filename, PropertyMapT &map);
    > >> ..
    > >> ..

    >
    > >> What am I doing wrong here?

    >
    > > An error telling "undefined reference to [whatever]" comes from the
    > > linker. It means that no available compilation unit defined that thing
    > > - it is just _declared_, in that header.

    >
    > > In this very case, find out what library you need, download it and add
    > > it to your linker references.

    >
    > > When you get the same kind of errors with your very names, that would
    > > mean that you forgot to define those names (that is, you just declared
    > > them, as it happened above).

    >
    > > Have good time,
    > > Francesco
    > > --
    > > Francesco S. Carta, hobbyist
    > > http://fscode.altervista.org

    >
    > Ah I just needed to add:
    >
    > #include "propertyutil.cpp"
    >
    > in the end of the propertyutil.h file, seems a bit wierd though. But
    > since I am using it in a "header only" library this might be the
    > explanation.


    If you _really_ added
    -------
    #include "propertyutil.cpp"
    -------
    to the _end_ of "propertyutil.h", you must have removed
    -------
    #include "propertyutil.h"
    -------
    from "propertyutil.cpp"

    If you didn't remove that line, you must have had your preprocessor
    chocking on inclusion's nesting level - otherwise, you didn't add it
    at the end of the file but before of "#endif".

    But apart of that, no, you shouldn't really include implementation
    files into headers that way.

    A header-only library is plainly that: a library that consists only of
    headers.
    That propertyutil thing isn't header-only at all.

    You should either add that cpp file to your project (assuming you're
    working within an IDE) otherwise you should explicitly pass it to your
    compiler (assuming you're working in a shell/console).

    Another way consists of making a separate library out of it, but maybe
    you want to postpone a bit these arguments.

    To include an implementation file in a header file - assuming you
    _really_ need to do so, which isn't this case at all - you need to do
    it conscientiously, otherwise you can end up having multiple
    definitions and your program won't compile.

    Consider this case:

    Content of foo_header.h:
    -------
    #ifndef FOO_HEADER_H
    #define FOO_HEADER_H

    void foo(); // declaration

    #endif

    // inclusion after the #endif
    #include "foo_implementation.cpp"
    -------

    Content of module1.cpp
    -------
    #include "foo_header.h"

    // use foo()
    -------

    Content of module2.cpp
    -------
    #include "foo_header.h"

    // use foo()
    -------

    And apart, not compiled,
    inside of foo_implementation.cpp:
    -------
    void foo() {
    // definition
    }
    -------

    Given all the above, you'll end up with _one_ declaration of foo and
    with _two_ definitions of the same, and your compilation will fail.

    The right way to include it is like this:

    -------
    #ifndef FOO_HEADER_H
    #define FOO_HEADER_H

    void foo();

    // inclusion _before_ the #endif
    #include "foo_implementation.cpp"

    #endif
    -------

    Such inclusion is really needed if and only if:
    - foo is a template
    AND
    - your compiler doesn't support the "export" keyword

    In all the other cases, including a non-header file within another
    file is just the wrong way of doing things.

    Hope this wasn't too messy of an explanation. Feel free to ask if you
    need, although you can find tons of informations hanging around, in
    the CLC++ FAQ for starters.

    --
    Francesco S. Carta, hobbyist
    http://fscode.altervista.org
     
    Francesco S. Carta, Oct 3, 2009
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. grbgooglefan
    Replies:
    2
    Views:
    432
    Pascal Bourguignon
    Jan 30, 2008
  2. grbgooglefan
    Replies:
    4
    Views:
    447
    Kenny McCormack
    Jan 30, 2008
  3. grbgooglefan
    Replies:
    0
    Views:
    399
    grbgooglefan
    Jan 30, 2008
  4. Alok
    Replies:
    3
    Views:
    255
  5. THAKUR PRASHANT SINGH

    Class Function call vs Normal Function call

    THAKUR PRASHANT SINGH, Feb 26, 2010, in forum: Ruby
    Replies:
    7
    Views:
    195
    THAKUR PRASHANT SINGH
    Feb 27, 2010
Loading...

Share This Page