Why static member can't be defined in headerfile with #pragma once - c++

Staitc member has to defined in a sourcefile(.cpp) because it will cause error due to duplicate definitions since headerfile(.h) is shared with many sourcefiles. However, if i type '#pragma once
at the beginning of the heaerfile (or use #ifndef, #endif). it will only run the headerfile once. Then why we still need to initialize static member in a sourcefile?
// This is string1.h
#pragma once
#include <cstring> // string.h for some
using std::ostream;
using std::istream;
static int num_strings=1; //why this still gives multiple definiton error even with #proagma once at top?
class String
{
private:
static int num_strings; // number of objects
}

#pragma once does not stop a header file from being compiled multiple times.
If you have two .cpp files and each includes a header file, then that header file will be compiled twice. It cannot be any other way because C++ uses separate compilation for each .cpp file. So what happens in one compilation cannot affect what happens in another compilation.
What #pragma once does is stop a header file being compiled twice during a single compilation. So your won't get errors if you include a header twice in the same .cpp file. This happens more often than you might think. For instance a .cpp file could include two different header files, but each of those header files includes a third common header file. So indirectly the common header file is being included twice in the .cpp file. It's this problem that #pragma once is designed to fix.

Your line of reasoning is wrong. Header guards are to prevent including the header more than once in a single translation unit. Suppose you have two source files:
// foo.cpp
#include "theheader.h"
// bar.cpp
#include "theheader.h"
#include "someotherheader.h"
Then those two will be compiled seperately, each has the contents of the header. The header guard only prevents to include "theheader.h" twice if for example the other header is
// someotherheader.h
#include "theheader.h"
To summarize, I allow myself to steal from a comment: "Include guards avoid that file is included multiple time in same translation unit, not across several translation unit"

Since C++17 you can get around the ODR violation by making the variable inline:
static inline int num_strings=1;
class String
{
private:
static inline int num_strings{}; // number of objects
}
See this for more information.
Btw, those are two distinct variables. One is num_strings and the other is String::num_strings.

Related

Use header-only (+implementation .h files) across multiple files in C++ project [duplicate]

I have a c++ header file containing a class.
I want to use this class in several projects, bu I don't want to create a separate library for it, so I'm putting both methods declarations and definitions in the header file:
// example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
namespace test_ns{
class TestClass{
public:
void testMethod();
};
void TestClass::testMethod(){
// some code here...
}
} // end namespace test_ns
#endif
If inside the same project I include this header from more than one cpp file, I get an error saying "multiple definition of test_ns::TestClass::testMethod()", while if I put the method definition inside the class body this does not happen:
// example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
namespace test_ns{
class TestClass{
public:
void testMethod(){
// some code here...
}
};
} // end namespace test_ns
#endif
Since the class is defined inside a namespace, shouldn't the two forms be equivalent? Why is the method considered to be defined twice in the first case?
Inside the class body is considered to be inline by the compiler.
If you implement outside of body, but still in header, you have to mark the method as 'inline' explicitly.
namespace test_ns{
class TestClass{
public:
inline void testMethod();
};
void TestClass::testMethod(){
// some code here...
}
} // end namespace test_ns
Edit
For myself it often helps to solve these kinds of compile problems by realizing that the compiler does not see anything like a header file. Header files are preprocessed and the compiler just sees one huge file containing every line from every (recursively) included file. Normally the starting point for these recursive includes is a cpp source file that is being compiled.
In our company, even a modest looking cpp file can be presented to the compiler as a 300000 line monster.
So when a method, that is not declared inline, is implemented in a header file, the compiler could end up seeing void TestClass::testMethod() {...} dozens of times in the preprocessed file. Now you can see that this does not make sense, same effect as you'd get when copy/pasting it multiple times in one source file.
And even if you succeeded by only having it once in every compilation unit, by some form of conditional compilation ( e.g. using inclusion brackets ) the linker would still find this method's symbol to be in multiple compiled units ( object files ).
These are not equivalent. The second example given has an implicit 'inline' modifier on the method and so the compiler will reconcile multiple definitions itself (most likely with internal linkage of the method if it isn't inlineable).
The first example isn't inline and so if this header is included in multiple translation units then you will have multiple definitions and linker errors.
Also, headers should really always be guarded to prevent multiple definition errors in the same translation unit. That should convert your header to:
#ifndef EXAMPLE_H
#define EXAMPLE_H
//define your class here
#endif
Don't put a function/method definition in an header file unless they are inlined (by defining them directly in a class declaration or explicity specified by the inline keyword)
header files are (mostly) for declaration (whatever you need to declare). Definitions allowed are the ones for constants and inlined functions/methods (and templates too).
Actually it is possible to have definitions in a single header file (without a separate .c/.cpp file) and still be able to use it from multiple source files.
Consider this foobar.h header:
#ifndef FOOBAR_H
#define FOOBAR_H
/* write declarations normally */
void foo();
void bar();
/* use conditional compilation to disable definitions when necessary */
#ifndef ONLY_DECLARATIONS
void foo() {
/* your code goes here */
}
void bar() {
/* your code goes here */
}
#endif /* ONLY_DECLARATIONS */
#endif /* FOOBAR_H */
If you use this header in only one source file, include and use it normally.
Like in main.c:
#include "foobar.h"
int main(int argc, char *argv[]) {
foo();
}
If there're other source files in your project which require foobar.h, then #define ONLY_DECLARATIONS macro before including it.
In use_bar.c you may write:
#define ONLY_DECLARATIONS
#include "foobar.h"
void use_bar() {
bar();
}
After compilation use_bar.o and main.o can be linked together without errors, because only one of them (main.o) will have implementation of foo() and bar().
That's slightly non-idiomatic, but it allows to keep definitions and declarations together in one file. I feel like it's a poor man's substitute for true modules.
Your first code snippet is falling foul of C++'s "One Definition Rule" - see here for a link to a Wikipedia article describing ODR. You're actually falling foul of point #2 because every time the compiler includes the header file into a source file, you run into the risk of the compiler generating a globally visible definition of test_ns::TestClass::testMethod(). And of course by the time you get to link the code, the linker will have kittens because it will find the same symbol in multiple object files.
The second snippet works because you've inlined the definition of the function, which means that even if the compiler doesn't generate any inline code for the function (say, you've got inlining turned off or the compiler decides the function is too big to inline), the code generated for the function definition will be visible in the translation unit only, as if you'd stuck it in an anonymous namespace. Hence you get multiple copies of the function in the generated object code that the linker may or may not optimize away depending on how smart it is.
You could achieve a similar effect in your first code snippet by prefixing TestClass::testMethod() with inline.
//Baseclass.h or .cpp
#ifndef CDerivedclass
#include "Derivedclass.h"
#endif
or
//COthercls.h or .cpp
#ifndef CCommonheadercls
#include "Commonheadercls.h"
#endif
I think this suffice all instances.

Multiple definition exception in C++

I am starting to learn C++ and am getting this compilation error from my IDE (CodeBlocks). I don't understand why this is happening.
|2|multiple definition of `parser::parseFile()'
|2|first defined here|
I don't see how this could happen. This is my entire code base.
main.cpp
#include "parser/parser.cpp"
int main()
{
return 0;
}
parser/parser.cpp
namespace parser {
void parseFile() {
}
}
Assuming you compiled both main.cpp and parser/parse.cpp you clearly have two definitions of parser::parseFile(): the #include directive just become replaced by the content of the named file (you can use the -E flag with your compiler to see the result).
You probably meant to declare parser::parseFile() in a header file (typically with a suffix .h or .hpp or something like that):
// file: parser/parser.hpp
#ifndef INCLUDED_PARSER_PARSER
#define INCLUDED_PARSER_PARSER
namespace parser {
void parseFile();
}
#endif
... and to include this header file into both translation units.
Your program have violated the One Definition Rule (also known as ODR).
In short, parser::parseFile function have been defined in both of your .cpp files, because on the compiler level, #include <header.h> simply means substituting the entire file contents in place.
Solution to your problem depends on your actual program, though. If you want to solve the ODR rule for class definitions, you can do either of:
1) Add a #pragma once at the beginning on a header. This, although being supported by all major compilers, is not standardized way of protecting from double-including a header.
2) Add an include guard:
#ifndef MY_HEADER_GUARD
#define MY_HEADER_GUARD
// your header contents go here
#endif
If you want to solve the ODR problem for functions and data variables, the above approach won't work because you can still have them defined multiple times in different .cpp files.
For this, you still have 2 options:
1) define your function somewhere outside, namely, in some .cpp file, only leaving its declaration in the header:
// header.h
namespace parser {
void func();
}
// file.cpp
void parser::func() { ... }
2) Declare your function as inline, as inline function are allowed to have multiple definitions by the C++ standard (however, they must be strictly identical up to lexem level):
// header.h
namespace parser {
inline void func() { ... }
}
To sum it up, I'd strongly recommend you go both directions by protecting your header from double inclusion and making sure your function is either inline or gets defined in a .cpp file. With the latter, if your function implementation changes, you won't have to recompile all the files that include your header, but only the one that has the functon definition.
Header files ending with .h(usually) is often used to separate class and function declaration from their implementation.
In Code::Blocks you can add header files by right clicking on your project name -> 'Add files' -> create a new file with .h extension. Following good practise, you should also create a .cpp file with the same name where the implementation is written.
As already answered, in your header file you can first write an include guard followed by your include's (if any) and also your function declarations. And in your 'parser.cpp' & 'main.cpp' you will have to #include "parser.h" since the files depend on eachother.

Should I repeat inclusions in .cpp and .h?

Scenario:
foo.h:
#include <vector>
class foo {
public:
std::vector<int>* getVector();
/* ... other methods declarations ... */
}
foo.cpp:
#include "foo.h"
#include <vector>
/* ... other methods definitions using std::vector ... */
std::vector<int>* foo::getVector() {
return new std::vector<int>();
}
I want .cpp to be independent of any possible future changes in the header. If for whatever reason the interface of the class changes and the dependency from <vector> can be eliminated, I risk that other methods in the .cpp also lose that inclusion.
Is it correct to repeat the inclusion of <vector> in both the .cpp and .h? Does this practice make sense or should I just rely on the inclusions made in the header?
Include what you need, and nothing more.
Including the same header file across multiple .h files and multiple .cpp files is not a problem in itself. Header guards are effective at mitigating problems from including files multiple times.
If you start trying to avoid including the same file multiple times, it can actually be negative as it usually leads to a "mega-include file" which includes everything you need in the entire project. This is bad, because one change to any header file causes everything to re-compile.
If you are worried about a .h/.cpp file both including the same file, then follow these guidelines:
If the include is not needed in the header file, only include it in the CPP
If a class declaration is needed in the header file (but not used), use forward declaration in the .h file and include it in the CPP file.
If you actually use the include within the header file, include it in the header file and not the CPP.
In .cpp file, it is enough to include only things specific for implementation (what .cpp file in fact is), without repeating stuff you already included in header. This way, when somebody is looking at your code, he also gets a better and cleaner understanding of your code.
It can be very useful to know which dependencies are specific only to implementation, for example when you are upgrading/replacing it with another one (while preserving the interface).
Include as few files in the header as possible, and only include them in the .cpp files that need them. Your foo.h header file might be included in many other .cpp files that do not need the declarations from the other header file(s) (in this case vector.h), which in the long run leads to longer compilations and less clear code.
No, you shouldn't. It serves no purpose. Redundant lines are cost without benefit.
Each file should include what it needs and no more. In your specific case of a header and its implementation, the redundant declaration in the .cpp doesn't help. If the header changed enough that the function no longer needed to return a vector you would need to revisit the .cpp anyway.

What is a guard block for a header file in C++?

I'm trying to make a C++ class using the Code::Blocks IDE and there is a field called "Guard block." I've done a search and haven't been able to find any useful information. What is this field for? Thanks.
Guard blocks are used to protect against the inclusion of a header file multiple times by the same compilation unit (c++ file). They look something like this:
// Foo.h
#ifndef INCLUDE_FILE_NAME_HERE_H_
#define INCLUDE_FILE_NAME_HERE_H_
class Foo
{
};
#endif
If you include the same file multiple files, you will end up with multiple definition error. Using of include guards isn't necessary in small projects but becomes critical in any medium to large sized projects. I use it routinely on any header files I write.
Guard blocks are used to prevent a header file being included multiple times in a single translation unit. This is often a problem when you include a number of header files that in turn include common standard header files.
The problem with multiple inclusions of the same file is that it results in the same symbol being defined multiple times.
Guard clauses can be handled with #define and #ifdef statements but are much simpler with the non-standard, but universal, #pragma once.
// foo.h
#pragma once
int foo(void);
// etc.

Purpose of Header guards

In C++ what is the purpose of header guard in C++ program.
From net i found that is for preventing including files again and again but how do header guard guarantee this.
The guard header (or more conventionally "include guard") is to prevent problems if header file is included more than once; e.g.
#ifndef MARKER
#define MARKER
// declarations
#endif
The first time this file is #include-ed, the MARKER preprocessor symbol will be undefined, so the preprocessor will define the symbol, and the following declarations will included in the source code seen by the compiler. On subsequent #include's, the MARKER symbol will be defined, and hence everything within the #ifnde / #endif will be removed by the preprocessor.
For this to work properly, the MARKER symbol needs to be different for each header file that might possibly be #include-ed.
The reason this kind of thing is necessary is that it is illegal in C / C++ to define a type or function with the same name more than once in a compilation unit. The guard allows you to #include a header file without worrying if has already been included. Without the guard, multiple inclusions of the same header file would lead to unwanted redeclarations and compilation errors. This is particularly helpful when header files need to #include other header files.
In short, it doesn't prevent you from #include-ing a file again and again. Rather, it allows you to do this without causing compilation errors.
The purpose of header guards is to prevent issues where some code may appear only once per translation unit.
One example is a struct. You cannot redefine a struct even if the second definition is identical. So, if you try to compile the following:
struct foo { int x; };
struct foo { int x; };
The compiler will fail because of the redefinition.
It can be hard to guarantee you only include a header one time (this happens when headers include other headers). If your header has struct definition, this will cause the compile to fail. Header guards are the easy trick so that even if a header is included multiple times, it's contents only appear a single time.