This question already has answers here:
When should I write the keyword 'inline' for a function/method?
(16 answers)
Closed 2 years ago.
nice to meet you, Stack overflow residents! Have a question:
I'm using Visual Studio 2019 that says me that I've defined some methods multiple times.
I have a header file (for example):
// header.hpp
#ifndef HEADER_HPP
#define HEADER_HPP
#include <iostream>
struct a {
a();
};
#include "degradation.inl"
#endif HEADER_HPP
And the .inl file for definitions (for example):
// degradation.inl
a::a() {
cout << "the hopless one\n";
}
So, the problem is, when I include this with #include <header.hpp> (that is, I've configured the include paths), have something that looks like that (for example):
error LNK2005: "public: __cdecl a::a(void)" (s0mEsтR#njeSуМb0ls) already defined in helpme.obj
Well, it's not the actual code (you can find the actual code here: GitHub), but I think that this code is a good example.
A #include is logically equivalent to inserting the entire contents of the included file into the file that includes it. It's exactly as if the contents of the included file were present in the file that included it. And this applies recursively.
If you work out, on paper and pencil, what happens here, this means that every .cpp that #includes what's shown will define a::a(), and compile it as part of the .cpp.
That is the reason for your duplicate symbol when linking. The simplest solution is to simply move the definition of a::a() into its own, separate, .cpp file. Don't #include it from any header, just compile and link it together with the rest of your .cpp files.
Just change
a::a() {
cout << "the hopless one\n";
}
to
inline a::a() {
cout << "the hopless one\n";
}
If you define functions in header files they should be inline (templates are an exception).
Related
This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 2 years ago.
I was researching in depth about C ++ header files after I often received the LNK2005 error in the Visual Studio compilation, and realized that the error was that I was declaring a variable twice, in the header file and in main.cpp, and I also found several users giving the solution how to use the extern type variable_name; in the header file as a solution to this, and reading the answers, 3 questions came to my mind:
1st - Do you really need to use extern to declare variables of any type in a header file? If so, why is it not used in declaring a class in a header file, for example?
2nd - Is it a good practice to use extern in the header file? Or is there something better to use that doesn't give me the error I received above?
3rd - From what I read, the use of extern requires that I re-declare the variable also in the .cpp file, but if it is already declared in the header file, why can't I just set its value in .cpp?
PS: Here are the reasons why I have thoroughly researched header files and generated this question here:
toast_notification.h:
#pragma once
bool dollar_value_was_changed;
bool toast_notification_was_created;
void show_toast_notification(), create_and_initialize_toast_notification(), set_toast_notification();
bool is_windows_10();
toast_notification.cpp:
#include "toast_notification.h"
#include <Windows.h>
#include <VersionHelpers.h>
#include <wintoast/wintoastlib.h>
void show_toast_notification()
{
if (is_windows_10())
{
if (!toast_notification_was_created)
create_and_initialize_toast_notification();
}
}
bool is_windows_10()
{
if (IsWindows10OrGreater())
return true;
else
{
MessageBox(NULL, L"Teste", L"Título da janela?", MB_OK);
return false;
}
}
void create_and_initialize_toast_notification()
{
WinToastLib::WinToast::instance()->setAppName(L"Toast Dollar");
WinToastLib::WinToast::instance()->setAppUserModelId(WinToastLib::WinToast::configureAUMI(L"Teste", L"Toast Dollar"));
WinToastLib::WinToast::instance()->initialize();
toast_notification_was_created = true;
}
void set_toast_notification()
{
WinToastLib::WinToastTemplate toast_notification = WinToastLib::WinToastTemplate(WinToastLib::WinToastTemplate::Text02);
toast_notification.setTextField(L"Teste", WinToastLib::WinToastTemplate::FirstLine);
}
main.cpp:
#include "toast_notification.h"
#include <iostream>
int main()
{
std::cout << "Hello World!\n";
show_toast_notification();
system("pause");
}
Don't pay too much attention to the code, I ask you to turn your attention to the variable toast_notification_was_created, which in my head, as it was already declared in the header file, I could set it in .cpp, in addition to it, the variable dollar_value_was_changed (which was not used) also generated the error that made me ask this question
The errors:
1> toast_notification.obj: error LNK2005: "bool dollar_value_was_changed" (?dollar_value_was_changed ## 3_NA) already defined in main.obj
1> toast_notification.obj: error LNK2005: "bool toast_notification_was_created" (?doast_notification_was_created ## 3_NA) already defined in main.obj```
In C++ a variable declaration at namespace scope is a definition unless it is declared extern. The extern prevents the declaration from being a definition. You can define a variable only once within a program (unless you make it inline). As headers are normally included in multiple translation units you’d get multiple definitions.
Note: I do not recommend to make variables inline! The primary use of inline “variable” definitions is for constexpr objects. In general I advise against non-const global data.
This question already has answers here:
Is it a good practice to place C++ definitions in header files?
(17 answers)
Closed 2 years ago.
I'm wondering if it's a good practice to store C++ regular functions, not methods(the ones in classes) inside header files.
Example:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
And Use it like this:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Is this a good a good practice?
Thanks in advance!
If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.
Then when you build, you first compile the source files to object files, and then you link the object files into the final executable.
Example code:
Header file
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b); // Function prototype, its declaration
#endif
First source file
#include "functions.h"
// Function definition
int add(int a, int b)
{
return a + b;
}
Second source file
#include <iostream>
#include "functions.h"
int main()
{
std::cout << "add(1, 2) = " << add(1, 2) << '\n';
}
How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.
If you are building from the command line in, for example, Linux or OSX, then you do:
$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program
The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).
No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.
Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.
If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.
If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.
Adding to what is said above, a function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function , is implicitly an inline function. So you do not need to explicitly write inline for the mentioned situations.
No. If you import the same header from two files, you get redefinition of function.
However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.
It's also OK to define member functions inside the class in header as C++ standard considers them as inline.
This question already has answers here:
Is it a good practice to place C++ definitions in header files?
(17 answers)
Closed 2 years ago.
I'm wondering if it's a good practice to store C++ regular functions, not methods(the ones in classes) inside header files.
Example:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
And Use it like this:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Is this a good a good practice?
Thanks in advance!
If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.
Then when you build, you first compile the source files to object files, and then you link the object files into the final executable.
Example code:
Header file
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b); // Function prototype, its declaration
#endif
First source file
#include "functions.h"
// Function definition
int add(int a, int b)
{
return a + b;
}
Second source file
#include <iostream>
#include "functions.h"
int main()
{
std::cout << "add(1, 2) = " << add(1, 2) << '\n';
}
How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.
If you are building from the command line in, for example, Linux or OSX, then you do:
$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program
The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).
No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.
Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.
If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.
If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.
Adding to what is said above, a function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function , is implicitly an inline function. So you do not need to explicitly write inline for the mentioned situations.
No. If you import the same header from two files, you get redefinition of function.
However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.
It's also OK to define member functions inside the class in header as C++ standard considers them as inline.
This question already has answers here:
C++ Header Files, Code Separation
(4 answers)
Closed 8 years ago.
I've been writing in C++ lately and I'm getting confused with .cpp vs .h — when to use them and what should go in them. I've been reading that you should put function definitions in a separate .cpp file, and headers should be used for declarations, but how do I use the separate .cpp file? Do I #include it or what? I'm looking for clarification on .h and .cpp and what should go where and how to include separate .cpp files.
You should use .h file for function prototype and data type declarations and also for pre-processor directives, and .cpp files for definitions. For example, test.h might be look like
#define CONSTANT 123 // pre-processor directive
void myfunction(char* str);
and your test.cpp might look like
#include <stdio.h>
#include "test.h"
int main(int argc char **argv)
{
myfunction("Hello World");
return 0;
}
void myfunction (char* str)
{
printf("%s and constant %d", str, CONSTANT);
return;
}
Usually the class declaration goes into the (.h) header file, and the implementation goes in the .cpp file.
You include the header file in the cpp file, so all the functions will be recognized, and you should remember to use #ifndef in the header file to avoid errors (includes loops)
hey everyone, i got code like this:
//a.h
#ifndef SB
#define SB
namespace A{ int a = 10; int b = 10;}
#endif
however, if I imported the a.h in a.cpp file, the compiler would complain:
error LNK2005: "int A::a" (?a#A##3HA) already defined in a.obj
It looks like compiler would combine .h file and .cpp file together without explicit "import" statement. But it doesn't make sense to me that it would happen with the macro guard defined.
I use Visual C++
#include guards prevent one file from including the same .h file multiple times. They don't prevent multiple files from each including the same .h file once, which is what I assume is happening to you. Move your definitions into a single .cpp file and leave just a declaration here:
namespace A {
extern int a;
extern int b;
}
which tells the compiler that these variables exist somewhere, but their definitions can be found elsewhere.
Chances are you have a cyclic #include statement some where that is putting the header file into both object files and then trying to link the object files together gets the duplicate entries.
Remember that when you #include what the compiler is doing is cut/pasting the contents of the .h file in place of the line the include is on.
You will want to declare prototypes in the .h file, not the actual declaration of those objects and their values.
If you want a and b to have constant values, you can do this:
//a.h
#ifndef SB
#define SB
namespace A{const int a = 10; const int b = 10;}
#endif
and it will not be a problem to include it in several places.
If you need the values to change, you should follow dfan's advice.