Undefined Internal Linkage and Undefined Symbols Error - c++

I tried compiling a simple program on Xcode and got the following messages:
function<anonymous namespace>::Initialize' has internal linkage but is not defined
function<anonymous namespace>::HandleBadInput' has internal linkage but is not defined
Undefined symbols for architecture x86_64:
"(anonymous namespace)::Initialize()", referenced from:
_main in main.o
"(anonymous namespace)::HandleBadInput()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The header file looks like this:
#ifndef WJKErrorHandling
#define WJKErrorHandling
namespace WJKErrorHandling{
void Initialize(void);
int HandleBadInput(void);
}
#endif // defined(WJKErrorHandling)
the implementation file looks like this:
#include <iostream>
#include "WJKErrorHandling.h"
namespace WJKErrorHandling{
void Initialize(void){
std::cin.exceptions(std::cin.failbit);
}
int HandleBadInput(void){
std::cerr << "Input Error: wrong type?\n";
std::cin.clear();
char BadInput[5];
std::cin >> BadInput;
return 1;
}
}
and main.cpp looks like this:
#include <iostream>
#include "WJKErrorHandling.h"
void Prompt (void){
//Prompts the user to begin entering numbers
std::cout << "Begin entering numbers: \n";
}
float GetNumber (void){
std::cout << "Number: \n";
float Number;
std::cin >> Number;
return Number;
}
std::string GetString (void){
std::cout << "String: \n";
std::string String;
std::cin >> String;
return String;
}
int main()
{
Prompt();
WJKErrorHandling::Initialize();
int ReturnCode = 0;
try{
float Number = GetNumber();
std::cout << Number;
std::string String = GetString();
std::cout << String;
std::cout << "SUCCESS!!!!\n";
}
catch(...){
ReturnCode = WJKErrorHandling::HandleBadInput();
}
return ReturnCode;
}
I've tried finding an answer so far, but I haven't understood any of the posts that I've found. I'm new with C++, so any help would be greatly appreciated!

Your #define Guard is causing name lookup issue.
change to below style should fix the issue:
#ifndef WJK_ERROR_HANDLING_H
#define WJK_ERROR_HANDLING_H

You could also use the non-standard but more idiomatic #pragma once, according to its wikipedia page it is supported by all major compilers.
Since many compilers have optimizations to identify include guards, there is no speed advantage between the two. For myself I see the following advantages of #pragma once:
It has only one meaning (whereas defines serve different purposes) and will not clash with other things (e.g. a namespace as in your case).
It is little to type and simple to remember.
You cannot have errors due to a typo (WJKERRORHANDLNG_H, ups and I is missing), because you started the header as a copy of another and forgot to change the include guard, which gives you rather nasty bughunting sessions.

This turns out to be a bad include guard:
#ifndef WJKErrorHandling
#define WJKErrorHandling
because you later try to use WJKErrorHandling as a namespace, but the macro makes it go away.
Change your include guard to something like:
#ifndef WJKERRORHANDLING_H
#define WJKERRORHANDLING_H
which is probably more idiomatic and less likely to conflict with something.

Related

C++ Unix and Windows support

I want to make my project available for Linux.
Therefore, I need to substitute functions from windows.h library.
In my terminal.cpp I highlight error messages in red. This step I only want to do in windows OS (ANSI don't work for my console, so i don't have a cross-platform solution for this).
On windows it works, but on Linux i get the following error:
/usr/bin/ld: /tmp/ccvTgiE8.o: in function `SetConsoleTextAttribute(int, int)':
Terminal.cpp:(.text+0x0): multiple definition of `SetConsoleTextAttribute(int, int)'; /tmp/cclUawx7.o:main.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
In my main.cpp file I do nothing but include terminal.h and run it.
terminal.cpp
if (OS_Windows)
{
SetConsoleTextAttribute(dependency.hConsole, 4);
cout << "Error: " << e.getMessage() << endl;
SetConsoleTextAttribute(dependency.hConsole, 7);
}
else
{
cout << "Error: " << e.getMessage() << endl;
}
terminal.h
#ifdef _WIN32
#define OS_Windows 1
#include "WindowsDependency.h"
#else
#define OS_Windows 0
#include "UnixDependency.h"
#endif
WindowsDependency.h
#pragma once
#include <Windows.h>
class Dependency
{
public:
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
};
UnixDependency.h
#pragma once
class Dependency
{
public:
int hConsole = 0;
};
void SetConsoleTextAttribute(int hConsole, int second) {};
Header files are supposed to contain declarations. By adding the {} you made a definition and C++ does not allow multiple definitions of the same function with identical signatures.
Either remove the {} and provide a definition in a separately-compiled .cpp file, OR by marking the function as inline.

Codelite linker undefined reference error

I'm new to codelite and c++. I'm using Linux and the g++ compiler. I've set up a simple project with two source files just to play around with linker errors. The files look like so:
Main.cpp:
#include <iostream>
void Log(const char*);
static int Multiply (int a, int b)
{
Log("Multiply");
return a * b;
}
int main()
{
std::cout << Multiply(5, 8) << std::endl;
std::cin.get();
}
Log.cpp:
#include <iostream>
void Log(const char* message)
{
std::cout << message << std::endl;
}
As you can see, Log.cpp simply specifies a function called in main. Both files are in the same directory, "src". So far all my settings are pretty much default, still I get an "undefined reference to `Log(..." error when I try to build this project.
Also, if I comment out the declaration of the Log function at the top of main.cpp, I would expect a compilation error since an undeclared function being called. Yet if I try to compile main.cpp I get no errors.
This is what my workspace looks like
Project settings
Compiler settings
Linker settings
Am I correct to expect the behaviors described above? Is there some setting I have to manually configure?

Xcode: linker command failed with exit code 1 (use -v to see invocation) [C++]

I am running a c++ programs with multiple files (2)
goofing_around.cpp
add.cpp
goofing_around.cpp:
//
// goofing_around.cpp
// new
//
// Created by Chirag Maheshwari on 14/08/18.
// Copyright © 2018 Chirag Maheshwari. All rights reserved.
//
#include <iostream>
int add(int x,int y);
int doubleNumber(int n)
{
return 2*n ;
}
int main()
{
int x;
std::cout << "Enter the number to be doubled: ";
std::cin >> x;
std::cout << doubleNumber(x)<<std::endl;
std::cout << add(3,2) << std::endl;
return 0;
}
add.cpp:
#include <iostream>
int add(int x,int y){
return x+y;
}
And yet I get an error which goes like this:
duplicate symbol _main in:
/Users/chirag/Library/Developer/Xcode/DerivedData/new-hapneuayvrpdonefrpnervwkxysx/Build/Intermediates.noindex/new.build/Debug/new.build/Objects-normal/x86_64/goofing_around-5915963FFFEE024.o
/Users/chirag/Library/Developer/Xcode/DerivedData/new-hapneuayvrpdonefrpnervwkxysx/Build/Intermediates.noindex/new.build/Debug/new.build/Objects-normal/x86_64/goofing_around-93C433489854664D.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Edit: This was weird.The error was there even before I added the add.cpp file.But then I deleted the projects and tried again.And after rewriting all the code,and adding the add file,I deleted the .h file.But only this time it worked,with the exact same code,and including the same function prototype.I did not have to include the add.cpp files either.
Super weird,but does anyone know why?
The problem is that you are not linking well the add method. You have implemented it in add.cpp but you don't add the link to it in the main code. You should include another "include" in goofing_around.cpp, something like
#include "add.cpp";
It should work.
Another observation: there is no need to print the name of the method "add" in the main code, since these things are done in the header files (if you have any). If not, there no sense to write that since you can just link your main code to the add.cpp.

Program keeps on giving such LNK errors

header.h
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
using namespace std;
//vector <Account> bankAccounts; this is taken out.
extern vector <Account> bankAccounts; //edited
struct Account {
int accountNumber;
string lastName;
string firstName;
double accountbalance;
};
void menu(int*);
void makeAccount(vector <Account>&);
cpp
#include "Header.h"
void menu(int*);
void makeAccount(vector <Account>&);
vector <Account> bankAccounts; //edited
int main() {
int input = 0;
int *inputPtr = &input;
menu(inputPtr);
switch (input) {
case 1:
makeAccount(bankAccounts);
}
}
another cpp
#include "Header.h"
vector <Account> bankAccounts; edited;
void menu(int *inputPtr) {
int select = 0;
cout << "Welcome to MadeUp Banking. Select options below: \n";
cout << "\t 1. Make new account. \n";
cout << "\t 2. Display to an account. \n";
cout << "\t 3. Deposit to an account. \n";
cout << "\t 4. Withdraw from an account. \n";
cout << "\t 5. Print account. \n";
cout << "\t 6. Delete an account. \n";
cout << "\t 7. Quit. \n";
cout << "Selection: ";
cin >> select;
*inputPtr = select;
}
void makeAccount(vector <Account> bankAccounts) {
//edited vector <Account> bankAccounts within makeAccount()
return;
}
When program is ran, the error gives:
main_file.obj : error LNK2005: "class std::vector > bankAccounts" (?bankAccounts##3V?$vector#UAccount##V?$allocator#UAccount###std###std##A) already defined in function_file.obj
1>main_file.obj : error LNK2019: unresolved external symbol "void __cdecl makeAccount(class std::vector > &)" (?makeAccount##YAXAAV?$vector#UAccount##V?$allocator#UAccount###std###std###Z) referenced in function _main
How do I go about fixing this error?
Sorry I'm a rookie coder, if more details are needed, then please tell me and I will edit accordingly. Thank you for the help in advance.
1. bankAccounts already defined in function_file.obj.
You should define bankAccounts in your cpp file. Because if you define it in header file, when you include your header in multiple cpp files, there would be multiple definition of backAccounts.
If you needs it in multiple cpp files, use extern to declare(not define) it in your header file:
extern vector <Account> bankAccounts;
And in one of your cpp file, define it as:
vector <Account> bankAccounts;
2. unresolved external symbol void makeAccount()
Definition of makeAccount() should be like:
void makeAccount(vector <Account>&)
{
// do something
}
While you are defining it as void makeAccount(vector<Account>). Please notice the difference. In your declaration, parameter is reference to a vector, while in your definition, parameter is vector object.
The error message of the first error, which can be abridged to:
main_file.obj : error LNK2005: std::vector<Account> bankAccounts already defined in function_file.obj
The reason for this error is that included files are copy-pasted in place of #include. That way, the std::vector<Account> bankAccounts is defined in both files (and they are, completely separate objects!), so the linker complains because of the multiple-definitions.
To solve this, in the header file, declare the global variable as extern std::vector<Account> bankAccounts, and then define it, in one of the .cpp files as std::vector<Account> bankAccounts. extern, only declares that there will be such a variable defined, at some point, and since you will be defining a global variable once, the linker won't see multiple definitions of said variable.
The second error is just like it sounds: you declared (and tried to call a function with signature void makeAccount(vector <Account>&);, however, you defined a function with signature void makeAccount();, leaving the function void makeAccount(vector <Account>&); undefined. Fix the definition of a function to include the parameter, present in its declarations:
void makeAccount(vector <Account>&) {
return;
}
Unrelated to your issues, but I felt that I should mention several more things:
Don't use using namespace std;, especially in the header files, it is considered a bad practice.
How is your code even reaching the linker stage? It shouldn't even compile, because Account is declared after the void makeAccount(vector <Account>&);, and at the point of such function declaration - struct Account is not known to the compiler.

.txt function not linking to main function [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
I am making a program with a list of baby names but I've decided to make a seperate function to open the file, this is what I have got so far.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void open_file(ifstream& in, char fileName[]);
void find_name(ifstream& in, string name, int numNames);
int main() {
const int NUMNAMES = 1000;
ifstream inStream;
char fileName[30];
string name;
cout << "Enter the name of the file that contains the names: " << endl;
open_file(inStream, fileName);
cout << "Enter the name to search for (capitalize first letter): " << endl;
cin >> name;
find_name(inStream, name, NUMNAMES);
inStream.close();
}
void open_file(ifstream& ) {
string line;
ifstream myfile ("babyNames.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
}
myfile.close();
}
else cout << "I/O failure opening file babyNames";
}
Does anyone know why I am getting so many error messages:
Undefined symbols for architecture x86_64:
"find_name(std::__1::basic_ifstream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int)", referenced from:
_main in Untitled-1b6d2e.o
"open_file(std::__1::basic_ifstream<char, std::__1::char_traits<char> >&, char*)", referenced from:
_main in Untitled-1b6d2e.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Does anyone know what I am doing wrong, I feel like it is relatively close I'm just fairly new to streams in c++.
The shown code declares and calls the following functions:
void open_file(ifstream& in, char fileName[]);
void find_name(ifstream& in, string name, int numNames);
Unfortunately, the shown code does not define any of these two functions, and the two linking errors are the result of that.
The shown code does define some function that's also called open_file(), but it's a completely different function because it takes different parameters. The shown code does not define any function called find_name().
You cannot simply declare a function like:
void open_file(ifstream& in, char fileName[]);
And then expect the code for this function to automatically appear somewhere. You have to define, and write the contents of this function. The parameters in this function, when you define it, must be the same as what you declared here.