How to parse error message LNK2005

Bryan Kelly 486 Reputation points
2022-10-28T19:43:22.417+00:00

Windows 11, Visual Studio 2019, C++
The goal is to learn how to use a Base58 encoding function. Below is the code I found and put into a console app. A console app was created just for this one function. The below code was edited into a dot cpp file and included in the main file. I have not yet written any code to call it.
Building the process solicits two sets of error messages. I have tried copy paste the error message into Notepad then break it up into segments and try to understand it. I cannot derive a simple explanation other than something is declared twice. I cannot determine where in the code the error is found. Here is the function followed by the two error messages.
What are the critical parts of the error message?
If the first does not make this obvious then how can I trace this back a particular line in the source code?
Thank you for your time.

#include <iostream>  
#include <string.h>  
#include <vector>  
  
  
// BK removed inline statement for VS 2019  
//inline static constexpr const uint8_t base58map[] = {  
  
static constexpr const uint8_t base58map[] = {  
	'1', '2', '3', '4', '5', '6', '7', '8',  
	'9', 'A', 'B', 'C', 'D', 'E', 'F', 'G',  
	'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q',  
	'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',  
	'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',  
	'h', 'i', 'j', 'k', 'm', 'n', 'o', 'p',  
	'q', 'r', 's', 't', 'u', 'v', 'w', 'x',  
	'y', 'z' };  
  
   // BK my description of the arguments:  
   // data: The string to be encoded to base 58  
   // mappoing: Look up the binary values of the input string and the array  
   // provides the characters to be used for each value.  
  
std::string EncodeBase58(const std::vector<uint8_t>& data, const uint8_t* mapping)  
{  
	std::vector<uint8_t> digits((data.size() * 138 / 100) + 1);  
	size_t digitslen = 1;  
	for (size_t i = 0; i < data.size(); i++)  
	{  
		uint32_t carry = static_cast<uint32_t>(data[i]);  
		for (size_t j = 0; j < digitslen; j++)  
		{  
			carry = carry + static_cast<uint32_t>(digits[j] << 8);  
			digits[j] = static_cast<uint8_t>(carry % 58);  
			carry /= 58;  
		}  
		for (; carry; carry /= 58)  
			digits[digitslen++] = static_cast<uint8_t>(carry % 58);  
	}  
	std::string result;  
	for (size_t i = 0; i < (data.size() - 1) && !data[i]; i++)  
		result.push_back(mapping[0]);  
	for (size_t i = 0; i < digitslen; i++)  
		result.push_back(mapping[digits[digitslen - 1 - i]]);  
	return result;  
}  

First error message

1> LINK : E:\WX\base_58_encode_tests\Debug\base_58_encode_tests.exe not found or not built by the last incremental link; performing full link
1> HetDerwel_may_2020.obj : error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl EncodeBase58(class std::vector<unsigned char,class std::allocator<unsigned char> > const &,unsigned char const *)" (?EncodeBase58@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@Abv ?$vector@EV?$allocator@E@std@@@2@Peter Bertels @Z) already defined in base_58_encode_tests.obj
1> E:\WX\base_58_encode_tests\Debug\base_58_encode_tests.exe : fatal error LNK1169: one or more multiply defined symbols found
1>Done building target "Link" in project "base_58_encode_tests.vcxproj" -- FAILED.

Second error message

1>HetDerwel_may_2020.obj : error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl EncodeBase58(class std::vector<unsigned char,class std::allocator<unsigned char> > const &,unsigned char const *)" (?EncodeBase58@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@Abv ?$vector@EV?$allocator@E@std@@@2@Peter Bertels @Z) already defined in base_58_encode_tests.obj
1>E:\WX\base_58_encode_tests\Debug\base_58_encode_tests.exe : fatal error LNK1169: one or more multiply defined symbols found

Developer technologies | C++
0 comments No comments
{count} votes

Accepted answer
  1. WayneAKing 4,931 Reputation points
    2022-10-29T02:54:14.687+00:00

    As a general rule, you don't #include .cpp files.
    Typically only *.h files (or similar) are #included.

    When you use an #include statement the precompiler adds
    all of the code from the .cpp file to the file with the #include
    directive.

    When you have a source file named

    HetDerwel_may_2020.cpp

    in the project, and then #include that same file in another
    source file - base_58_encode_tests.cpp - then you are compiling
    the same source code in two different .cpp files in the project.
    Then the linker sees both *.obj files from the compiles have
    duplicate definitions, etc.

    • Wayne
    0 comments No comments

5 additional answers

Sort by: Most helpful
  1. RLWA32 49,536 Reputation points
    2022-10-28T20:41:27.473+00:00

    The error messages refer to two modules -- HetDerwel_may_2020.obj and base_58_encode_tests.obj.

    So it seems that your project is either linking with a library that contains the identified function or contains another source file (.cpp) that contains the function.

    0 comments No comments

  2. Bryan Kelly 486 Reputation points
    2022-10-29T00:15:43.597+00:00

    That code has three includes:

    include <iostream>

    include <string.h>

    include <vector>

    Nothing else is included. Other than the boilerplate for a console project, that is the entire project.
    So what library do you suspect the error is coming from? And why do you select that library?


  3. Bryan Kelly 486 Reputation points
    2022-10-29T02:34:20.12+00:00

    I created a console app, standard with no changes. It is named: base_58_encode_tests.cpp
    The goal is to get some Base58 functions working on my computer.

    I created a new empty file: HetDerwel_may_2020.cpp The name indicates where I found the code.
    The code posted was pasted into the file, with a few comments at the top and I think a few includes that were omitted.

    In the console app, file base_58_encode_tests.cpp I added:

    include HetDerwel_may_2020.cpp

    And that is it. There is nothing else but what was just mentioned.
    I do not have the expertise to know it there is a configuration problem in Visual Studio 2019.

    While this exchange is going on, I am adding a new file with different code to do Base58 encode/decode.

    0 comments No comments

  4. WayneAKing 4,931 Reputation points
    2022-10-29T03:02:55.13+00:00

    As an aside, I notice that the code you posted has

    #include <string.h>  
      
      
    

    that is the C RTL header used for functions such as strcmp()
    strlen(), etc. It is usually not needed in C++ code.

    However, as you are using std::string in the code you SHOULD have

    #include <string>  
      
    

    which is the C++ header required for std strings.

    • Wayne
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.