Definition or redeclaration not allowed inside a function [duplicate] - c++

This question already has answers here:
How to define a const double inside a class's header file?
(3 answers)
Closed 7 years ago.
Something.h
1 class Something
2 {
3 private:
4 static int s_nIDGenerator;
5 int m_nID;
6 static const double fudgeFactor; // declaration - initializing here will be warning
7 public:
8 Something() { m_nID = s_nIDGenerator++; }
9
10 int GetID() const { return m_nID; }
11 };
foo.cpp
1 #include <iostream>
2 #include "Something.h"
3
4 // This works!
5 //const double Something::fudgeFactor = 1.57;
6
7 int main()
8 {
9 Something cFirst;
10 Something cSecond;
11 Something cThird;
12
13 const double Something::fudgeFactor = 3.14;
14
15 using namespace std;
16 cout << cFirst.GetID() << endl;
17 cout << cSecond.GetID() << endl;
18 cout << cThird.GetID() << endl;
19 return 0;
20 }
When trying to define the value of the static member variable of Class Something inside main, I encounter a compiler error as given below. Assigning a value outside the main() works fine. I understand that static member variables can be given a value only once, but why does assigning it outside a function versus inside a function matter?
$ clang++ foo.cpp
foo.cpp:13:29: error: definition or redeclaration of 'fudgeFactor' not allowed
inside a function
const double Something::fudgeFactor = 3.14;
~~~~~~~~~~~^
1 error generated.

You are not assigning the variable inside the function; you are defining it (and initializing it). You can't do that inside the function because of scope rules. The variable is declared in the global (namespace) scope; therefore it also has to be defined in the namespace scope. It is not a local variable.
By the way, for static const variables, recent C++ standards allow you to initialize them at the point of declaration (as in your .h file) but you still have to define them, but this time without the initializer:
const double Something::fudgeFactor;

Static data members of a class needs to have external linkage. By this rule, the static members must be defined in namespace scope.

Related

What effect does `static` have on a method in a namespace? [duplicate]

This question already has answers here:
Error in calling a static function in a namespace
(2 answers)
Static function vs Static member functions C++
(1 answer)
The static keyword and its various uses in C++
(9 answers)
Closed 6 months ago.
Does static mean anything on func2 in the context of a namespace? Both methods appear to be equivalent.
// MyHeader.h
namespace TestNameSpace
{
int func1() { return 1; }
static int func2() { return 2; }
}
// SomeFile.cpp
#include "MyHeader.h"
// ...
int test1 = TestNameSpace::func1(); // 1
int test2 = TestNameSpace::func2(); // 2
static functions (which are not member of classes) are only visible in the compilation unit they are defined in. Apart from that there should not be any difference between those two

Wrong symbols linked. Why? [duplicate]

This question already has answers here:
C++ Multiple Definition of Struct
(2 answers)
Why is there no multiple definition error when you define a class in a header file?
(3 answers)
Closed 1 year ago.
C++ translator seems uses correct declared structs of the same name, but then linker mismatches them without any warning or error! And this also leads to UB, because at least inappropriate ctor/dtor are used for the memory region.
Here is minimal sandbox code. Each struct Test should be treated as some internal non-public structure used only in one own .cpp file.
file1.cpp
#include <iostream>
using namespace std;
void someFunc();
struct Test
{
Test() { std::cout << "1 "; }
~Test() { std::cout << "~1" << std::endl; }
};
int main()
{
{
Test test;
}
someFunc();
return 0;
}
file2.cpp
#include <iostream>
struct Test {
Test() { std::cout << "2 "; }
~Test() { std::cout << "~2" << std::endl; }
};
void someFunc() {
Test test;
}
(Downloadable and buildable CMake-project just in case: https://file.io/dzafv409B2t0)
Output will be:
1 ~1
1 ~1
So, I expected:
Successful build with output: 1 ~1 2 ~2
Or failed build with multiple definition error
Yes, I can resolve the problem if:
Rename the struct
Put the struct into anonymous namespace - force internal linkage
...but this doesn't answer the main question:
Why linker behaves so? Why does it silently links to first available matching symbol (among several) instead of reporting multiple definition error?
Update: As I understood, this mechanism allows to include header with class declaration (with inline code) into several different source files without multiple definition problem.

how does the inline function work in C++?

now I have 2 c++ source files: test9.cpp test10.cpp, they both have a inline function with the same name.
test9.cpp:
1 #include <iostream>
2 using namespace std;
3 void test();
4 inline void f1()
5 {
6 cout << "inline f1 in test9.cpp" << endl;
7 }
8 int main()
9 {
10 f1();
11 test();
12 return 0;
13 }
test10.cpp:
1 #include <iostream>
2 using namespace std;
3 inline void f1()
4 {
5 cout << "inline f1 in test10.cpp" << endl;
6 }
7 void test()
8 {
9 f1();
10 }
now compile them with g++: g++ test9.cpp test10.cpp ./a.out I get the following result:
inline f1 in test9.cpp
inline f1 in test9.cpp
what's wrong? I thought it would be: "inline f1 in test9.cpp inline f1 in test10.cpp"
who can tell me why? how does the g++ compiler treats the inline function?
While the compiler will allow you (nay, require you!) to redefine functions marked inline, the default of external linkage still applies, so you are breaking the One Definition Rule. This results in undefined behaviour and the outcome that you are seeing.
[C++11: 7.1.2/4]: An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2). [..]

Access static variable from static function [duplicate]

This question already has answers here:
Unresolved external symbol on static class members
(6 answers)
Closed 10 years ago.
It is very important that my function is static, I need to access and modify another static/non-static class member in order to print it out later. How can I do that?
Flow
Class is initiated
Constructor sets variable to something using internal function that must be static
Some time later I print that variable
Example code
#include <iostream>
class MyClass
{
public:
static int s;
static void set()
{
MyClass::s = 5;
}
int get()
{
return MyClass::s;
}
MyClass()
{
this->set();
}
};
void main()
{
auto a = new MyClass();
a->set(); // Error
std::cout << a->get() << std::endl; // Error
system("pause");
}
Error
LNK2001: unresolved external symbol "public: static int MyClass::s" (?s#MyClass##2HA)
LNK1120: 1 unresolved externals
You have declared your static variable, but you have not defined it.
Non-static member variables are created and destroyed as the containing object is created and destroyed.
Static members, however, need to be created independently of object creation.
Add this code to create the int MyClass::s:
int MyClass::s;
Addendum:
C++17 adds inline variables, allowing you code to work with a smaller change:
static inline int s; // You can also assign it an initial value here
^^^^^^

Compilation failed, c++ program with static variable as private member variable [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
undefined reference to static member variable
What is an undefined reference/unresolved external symbol error and how do I fix it?
#include<iostream>
using namespace std;
class abc {
private:
static int a ;
public:
abc(int x) {
a = x;
}
void showData() {
cout<<"A = "<<a<<endl;
}
};
int main() {
abc a1(4);
abc a2(5);
a1.showData();
a2.showData();
return 0;
}
When I try to compile this function on Ubuntu with GCC compiler. I get the following error.
/tmp/ccCKK2YN.o: In function `main':
static1.cpp:(.text+0xb): undefined reference to `Something::s_nValue'
static1.cpp:(.text+0x14): undefined reference to `Something::s_nValue'
collect2: ld returned 1 exit status
Compilation failed.
Where as the following code runs fine
#include<iostream>
using namespace std;
class Something
{
public:
static int s_nValue;
};
int Something::s_nValue = 1;
int main()
{
Something cFirst;
cFirst.s_nValue = 2;
Something cSecond;
std::cout << cSecond.s_nValue;
return 0;
}
Is this because Static member variables needs to initialized explicitly before accessing them via objects.Why so ?
static int s_nValue; doesn't allocate any storage to store the int, it just declares it.
You allocate somewhere in memory to store the variable with:
int Something::a=0;
The declaration of a static data member in the member list of a class is not a definition. You must define the static member outside of the class declaration, in namespace scope.
See this thread.
In short, the static member needs to be initialized somewhere in a .cpp file so that the compiler allocates space for it. The declaration would look like this:
int abc::a = 0;
That happens because since static members are shared between all instances of a class, they need to be declared in one single place.
If you define the static variable inside the class declaration then each include to that file would have a definition to that variable (which is against to the static meaning).
Because of that you have to define the static members in the .cpp.