I don't understand this error...

I'm not sure if this is the correct place to be posting this, but I made a similiar post on Stack Overflow recently to which no one actually answered my question and continued to down-vote me until my question disappeared from the forums. I really hope someone on this site will be able to help me and give some constructive criticism without all of the attitude. The following is the error message the compiler (g++) is throwing and my code.

------------------Error------------------

1
2
3
4
5
6
7
8
Undefined symbols for architecture x86_64:
  "Block::getHash()", referenced from:
      _main in main-67a34d.o
  "Block::Block(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned short, 
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
      _main in main-67a34d.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


------------------block.h------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef BLOCK_H
#define BLOCK_H

#include <string>
#include <ctime>

using namespace std;

class Block {
  public:
    Block(string _data, const unsigned short int blockNum, string _prevHash);
    string getHash();


  private:
    unsigned short int blockNum;
    string data;
    string hash(string data, unsigned short int blockNum, string prevHash, time_t timestamp);
    string prevHash;
    time_t timestamp;
};

#endif 


------------------block.cpp------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <string>
#include <sstream>
#include <ctime>
// #include "sha512.h"
#include "block.h"

Block::Block(string _data, unsigned short int _blockNum, string _prevHash) {
  data = _data;
  blockNum = _blockNum;
  prevHash = _prevHash;
  timestamp = time(NULL);
}

// Block::~Block() {}

string Block::hash(string data, unsigned short int blockNum, string prevHash, time_t timestamp) {
  char *_timestamp = ctime(&timestamp);
  stringstream _blockNum;
  _blockNum << blockNum;
  string hashContents = data + _blockNum.str() + prevHash + string(_timestamp);

 //  return sha512(hashContents);
  return hashContents; // Debugging purposes
}

string Block::getHash() {
  return hash(data, blockNum, prevHash, timestamp);
}


------------------main.cpp------------------

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>
#include "block.h"

using namespace std;

int main() {
  Block testBlock("Some Data", 1, "Genesis");
  cout << testBlock.getHash() << endl;
  return 0;
}
Last edited on
Yes, Stack Overflow upholds a higher standard than here.

I attempted to convert your code into an compileable example,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#ifndef BLOCK_H
#define BLOCK_H

#include <string>
#include <ctime>

using namespace std;

class Block {
public:
    Block(string _data, const unsigned short int blockNum, string _prevHash);
    string getHash();

private:
    unsigned short int blockNum;
    string data;
    string hash(string data, unsigned short int blockNum, string prevHash, time_t timestamp);
    string prevHash;
    time_t timestamp;
};

#endif

//
// block.cpp
//
#include <string>
#include <ctime>
//#include "sha512.h"
//#include "block.h"

Block::Block(string _data, unsigned short int _blockNum, string _prevHash) {
    data = _data;
    blockNum = _blockNum;
    prevHash = _prevHash;
    timestamp = time(NULL);
}

string Block::hash(string data, unsigned short int blockNum, string prevHash, time_t timestamp) {
    char *_timestamp = ctime(&timestamp);
    string hashContents = data + to_string(blockNum) + prevHash + to_string(_timestamp);
    //return sha512(hashContents);
    return "";
}

string Block::getHash() {
    return hash(data, blockNum, prevHash, timestamp);
}

//
// main.cpp
//
#include <iostream>
#include <string>
//#include "block.h"

using namespace std;

int main() {
    Block testBlock("Some Data", 1, "Genesis");
    cout << testBlock.getHash() << endl;
    return 0;
}


The compilation error I get is:
 In member function 'std::string Block::hash(std::string, short unsigned int, std::string, time_t)':
41:87: error: call of overloaded 'to_string(char*&)' is ambiguous


This is referring to your call to to_string(_timestamp).

https://www.techonthenet.com/c_language/standard_library_functions/time_h/ctime.php
http://www.cplusplus.com/reference/string/to_string/

You're attempting to convert what I hope is a null-terminated c-style string into a C++ std::string.

Just do std::string(_timestamp).
See constructor (4): http://www.cplusplus.com/reference/string/string/string/


Also, what version of g++ are you using, and what operating system?
Also... are you using g++ or clang? Your output mentions clang.

Edited with corrections.
Last edited on
Most likely, you
a.) never saved block.cpp; or
b.) never recompiled block.cpp; or
c.) never passed block.o to the linker.

What steps are you taking to build your program?
Last edited on
Ganado, first I would like to say I love your name. I was attempting to cast the timestamp which is of the output from ctime into a string. I initially didn't do it that way, but was told I should use the "to_string" method by people on Stack Overflow. I tried changing the casting method from "to_string()" to just "string()", but got the same error message as I previously posted. I am using the g++ compiler on a Macbook running OSX. I tried to get the version of it by typing "g++ -v" (not sure if that's the correct command or not) and got this as output:

1
2
3
4
5
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Last edited on
Mbozzi, I have saved all files and block.cpp is a class so only the main.cpp needs to be compiled. Also what do you mean by block.o and linker? There is no "block.o" file nor have I ever heard of such a thing. When you mention linker are you referring to the compiler because out of all my years writing code in other languages I've never once heard the term "linker".
only the main.cpp needs to be compiled

No, all of your source files need to be compiled, either together or separately, save header files, which are compiled as part of the translation units that include them. The results of such separate compilation is object code (generally in the form of .o files), which are collectively passed to the linker to form the resulting program.

out of all my years writing code in other languages I've never once heard the term "linker".

https://lmgtfy.com/?q=linker

In effect, compilation is a three-step process: preprocessing, compilation, and linking. There's different ways to break those phases down, but those will do as search keywords.

It's one of those things that I could use that I don't want to write. The information exists in any decent textbook, however, and if you just wanted a language-technical reference, you could read about C++'s phases of translation at:
https://en.cppreference.com/w/cpp/language/translation_phases
Essentially, it is phases 1-5, 6-8, and 9, that correspond conceptually with the three steps I referenced above.

There's plenty of information on the internet, as well. See, for instance:
https://stackoverflow.com/questions/6264249/how-does-the-compilation-linking-process-work
Last edited on
You guys were right, it was not code-related. I was typing "g++ main.cpp" thinking it would compile everything completely, the code ran successfully upon using the following command: "g++ *.cpp -o executable", where "executable" is the name of the compiled executable.
Glad to hear you got it working, good luck!
Topic archived. No new replies allowed.