0

I'm trying to create a header file, implementation file and main file for a simple c++ program that returns the systems hostname using gethostname().

my header file that declares my class, data, and methods

//hostname.h
#pragma once                                                                                              

namespace hostnamespace
{
  class hostname_class
  {
    public:
      hostname_class();
      void to_string();

    private:
      char *name;
  };  
}

my implementation file that defines my class and methods

//hostname_class.cpp
#include "hostname.h"                                                                                     
#include <iostream>
#include <unistd.h>
#include <limits.h>

using namespace hostnamespace;
using namespace std;

class hostname_class{
  private:
    char *name;
  public:
    hostname_class(){
      gethostname(name, HOST_NAME_MAX);
    }   
    void to_string(){
      cout << "Hostname:" << &name << endl;
    }   
};

my main program file

//hostname_main.cpp
#include "hostname.h"                                                                                     
#include <iostream>

using namespace hostnamespace;

int main() {
  hostname_class host;
  host.to_string();
  return 0;
}

when I try and run g++ -o main hostname_main.cpp hostname_class.cpp

I get this error

/bin/ld: /tmp/ccGfbyuu.o: in function `main':
hostname_main.cpp:(.text+0x1f): undefined reference to `hostnamespace::hostname_class::hostname_class()'
/bin/ld: hostname_main.cpp:(.text+0x2b): undefined reference to `hostnamespace::hostname_class::to_string()'
collect2: error: ld returned 1 exit status

any help would be appreciated.

3
  • 2
    You're replicatring the class declaration of hostname_class in both the header and cpp. Don't do that. Just implement the members in the cpp . In case you're wondering how on earth this compiled to the point of link failure, you have two hostname_class classes: one in the hostnamespace namespace, and one in the global namespace. The code in hostname_class.cpp implements the one in the global namespace, while the using namespace hostnamespace; in main.cpp pulls in the other one (which you never defined). Commented Sep 26, 2018 at 1:17
  • Try to first make it work without adding a namespace to complicate things. For that matter, you don't need a class to complicate things, either. All you need is a function. Commented Sep 26, 2018 at 1:18
  • 1
    gethostname doesn't work this way because C arrays and strings don't work this way. Commented Sep 26, 2018 at 1:52

1 Answer 1

4

You are redeclaring the hostname_class in the global namespace instead of defining it within the namespace you intended.

A sample structure of how your hostname_class.cpp file could be written.

#include <iostream>
#include <unistd.h>
#include <limits.h>
#include "hostname.h"

using namespace std;

namespace hostnamespace
{

    hostname_class::hostname_class() {
        gethostname(name, HOST_NAME_MAX);
    }   

    void hostname_class::to_string() {
      cout << "Hostname:" << name << endl;
    }   
};

One side note - I literally copied your method implementations verbatim. It will compile. But name is certainly uninitialized and pointing to an undefined memory address when you pass it into gethostname. That's probably not good.

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

Comments

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.