When is a `static thread_local` global variable useful? - c++

Some codebases like skia define a static thread_local global variable. What is the point of having this as opposed to just a thread_local variable at a namespace scope?
// From: https://github.com/google/skia/blob/main/src/sksl/SkSLPool.cpp
namespace SkSL {
static thread_local MemoryPool* sMemPool = nullptr;
static MemoryPool* get_thread_local_memory_pool() {
return sMemPool;
}
static void set_thread_local_memory_pool(MemoryPool* memPool) {
sMemPool = memPool;
}
}
What will happen if we remove static.

Related

I have error in program to count total number of objects with static variable [duplicate]

This question already has answers here:
Member function with static linkage
(3 answers)
Closed 6 years ago.
using namespace std;
class Sample
{ int x;
static int count;
public:
void get();
static void showCount();
};
void Sample::get()
{
cin>>x;
++count;
}
static void Sample::showCount(){
cout<<"Total No. of Objects :"<<count;
}
int main()
{ Sample s1,s2;
s1.get();
s2.get();
Sample::showCount();
return 0;
}
Compilation Error :[Error] cannot declare member function 'static void Sample::showCount()' to have static linkage[-fpermissive]
Remove static keyword
void Sample::showCount(){
cout<<"Total No. of Objects :"<<count;
}
static keyword in a class member function declaration has a different meaning to static keyword in a function definition. The former tells that the function doesn't need an instance of the class (doesn't get this pointer), the later defines static linkage: local to the file, the function is accessible in this particular file only.
You are also missing definition of count. You need a line somewhere before main:
int Sample::count = 0;
...
main() {
...
}
class Sample
{ ...
static void showCount();
};
static void Sample::showCount(){
cout<<"Total No. of Objects :"<<count;
}
// You can void instead of static, because you are not returning anything.
This is incorrect. You don't need 2nd static.
When declaring static member functions in C++, you only declare it as static inside the class definition. If you implement the function outside the class definition (like you have), don't use the static keyword there.
Outside of a class definition, the static keyword on a function or variable means that the symbol should have "static linkage." This means that it can only be accessed within the source file (translation unit) that it's in. static symbols aren't shared when all of your compiled source files are linked together.
See this SO question if you aren't familiar with the term "translation unit."
You have one other problem, which Saurav Sahu mentioned: you declared the static variable static int count; but never defined it. Add this outside of the class definition:
int Sample::count = 0;
#include <iostream>
using namespace std;
class Sample
{
int x;
public:
static int count;
void get();
static void showCount();
};
int Sample::count = 0;
void Sample::get()
{
cin >> x;
++count;
}
void Sample::showCount(){
cout << "Total No. of Objects :" << count;
}
int main()
{
Sample s1, s2;
s1.get();
s2.get();
Sample::showCount();
return 0;
}

static struct in anonymous namespace

that this snippet of code actually do?
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
void test();
namespace {
static struct StaticStruct {
StaticStruct() {
test();
}
} TheStaticSupport;
}
int main(void) {
return 0;
}
void test() {
printf("testing function\n");
}
why does the test function actually get called? and why use the "anonymous" namespace? I found this piece of code in an open source project...
This:
static struct StaticStruct {
StaticStruct() {
test();
}
} TheStaticSupport;
Is equivalent to this:
struct StaticStruct {
StaticStruct() {
test();
}
};
static StaticStruct TheStaticSupport;
It defines a type named StaticStruct and an instance of the type named TheStaticSupport with internal linkage (though, since it is declared in an unnamed namespace, the static is redundant).
The constructor for TheStaticSupport is called before main() is entered, to construct the object. This calls the test() function.
The anonymous namespace gives the contained objects internal linkage, as their fully qualified name can never be known to anyone outside the translation unit. It's the sophisticated man's version of the old static in C.
Note that you do declare a global object of type StaticStruct, and its constructor (which runs before main() is called) calls test().

Static member in C++ programming

I'm trying to create a C++ class which can work as a holder for my project, so have implemented my class members and functions static, but I don't know why compiler can recognize the _nTriggerMode inside the setTriggerMode.
Here is my header file:
#pragma once
class GrabberOptions
{
private:
static int _nTriggerMode;
static int _nExposureInMicroSec;
static double _dFramesPerSecond;
static int _nExsysncOn;
public:
GrabberOptions(void);
~GrabberOptions(void);
static void setTriggerMode(int triggerMode);
static void setExposureInMicroSec(int exposureMicroSec);
static void setFramePerSecond(double framePerSec);
static void setExsysncOn(int exsysncOn);
static int getTriggerMode();
static int getExposureInMicroSec();
static double getFramePerSecond();
static int getExsysncOn();
};
And here is the .ccp file:
#include "StdAfx.h"
#include "GrabberOptions.h"
int GrabberOptions::_nTriggerMode;
int GrabberOptions::_nExposureInMicroSec;
double GrabberOptions::_dFramesPerSecond;
int GrabberOptions::_nExsysncOn;
GrabberOptions::GrabberOptions(void)
{
_nTriggerMode = GRABBER_CONTROLLED;
_nExposureInMicroSec = 20;
_dFramesPerSecond = 1000;
_nExsysncOn = 1;
}
GrabberOptions::~GrabberOptions(void)
{
}
void setTriggerMode(int triggerMode){
_nTriggerMode=triggerMode;
}
Please give me some idea of how to use static.
static class member variables must be defined outside of the class definition:
// .h file
class GrabberOptions
{
private:
static double _dFramesPerSecond; // declaration
// .cpp file
double GrabberOptions::_dFramesPerSecond = 1000; // definition
You need to initialize the static outside the class definition, in a single translation unit (usually your corresponding implementation file):
#include "StdAfx.h"
#include "GrabberOptions.h"
double GrabberOptions::_dFramesPerSecond; //initializes to 0
//double GrabberOptions::_dFramesPerSecond = 1337; //if you want a different value
GrabberOptions::GrabberOptions(void)
{
// _nTriggerMode = GRABBER_CONTROLLED;
// _nExposureInMicroSec = 20;
_dFramesPerSecond = 1000;
// _nExsysncOn = 1;
}
GrabberOptions::~GrabberOptions(void)
{
}
The static member variables of a class are shared by all instances of a class. They are occasionally useful, but this is probably not an example. Static member functions can only access static member variables.
Your class design shown by the commented out code has no per-instance data; everything is static. That is essentially never a good design in C++.

C++ - Initialize and modify a static class member

I don't know how to initalize a static class member without creating an object of this class.
Here is my code:
namespace {
class CPassant : public thread
{
private:
static unsigned LastID;
public:
CPassant (unsigned pDelaiArr = 0, unsigned pDelaiDep = 0)
{
(blabla)
}
static void setLastID (unsigned Valeur)
{
LastID = Valeur;
/* error : undefined reference to `(anonymous
namespace)::CPassant::LastID' */
} // setLastID ()
}; // class CPassant
} // anonym namespace
int main ()
{
CPassant::CPassant ().setLastID(0);
// doesn't work too:
// unsigned CPassant::LastID = 0;
return 0;
}
Thanks
NB: I've already looked at those answers, but none of them worked:
stackoverflow.com/ initialize-a-static-member-an-array-in-c
stackoverflow.com/ how-to-initialize-a-static-member
Do this in your cpp file:
unsigned CPassant::LastID = 0;
This is called defining the static class member, If you dont do this you will end up getting linker errors. You just declared the static member but did not define it.
Note that access specifiers do not matter here while defining the static member.
You have declared, but not defined, the static member. You must define it. Here is one way:
namespace {
/* ... */
unsigned CPassant::LastID = 0;
}; // anonym namespace
you have to do
unsigned CPassant::LastID = 0;
in the .cpp file..
The problem with your initialization of LastID is that it's outside of the namespace you declared it. Put it in the same namespace and it will work.

How to access static members of a class?

I am starting to learn C++ and Qt, but sometimes the simplest code that I paste from a book results in errors.
I'm using g++4.4.2 on Ubuntu 10.04 with QtCreator IDE. Is there a difference between the g++ compiler syntax and other compilers? For example when I try to access static members something always goes wrong.
#include <iostream>
using namespace std;
class A
{
public:
static int x;
static int getX() {return x;}
};
int main()
{
int A::x = 100; // error: invalid use of qualified-name 'A::x'
cout<<A::getX(); // error: : undefined reference to 'A::x'
return 0;
}
I think it's exactly the same as declared here and here (isn't it?). So what's wrong with the above code?
You've declared the static members fine, but not defined them anywhere.
Basically what you've said "there exists some static member", but never set aside some memory for it, you need:
int A::x = 100;
Somewhere outside the class and not inside main.
Section [9.4.2]
Static Data Members
The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator
You need to define the static member variable of the class outside the class as static member variables require declaration as well as definition.
#include <iostream>
using namespace std;
class A
{
public:
static int x;
static int getX() {return x;}
};
int A::x; // STATIC MEMBER VARIABLE x DEFINITION
int main()
{
A::x = 100; // REMOVE int FROM HERE
cout<<A::getX();
return 0;
}
Try:
#include <iostream>
using namespace std;
class A
{
public:
// This declares it.
static int x;
static int getX(){return x;}
};
// Now you need an create the object so
// This must be done in once source file (at file scope level)
int A::x = 100;
int main()
{
A::x = 200;
// Notice no 'int' keyword before A::x on this line. You can modify A::x
cout<<A::getX(); // Should work
return 0;
}
The definition of static member variables must live at file scope, i.e. outside all functions, etc.
Try this example:
#include<iostream>
using namespace std;
class check
{
static int a;
public:
void change();
} ;
int check::a=10;
void check::change()
{
a++;
cout<<a<<"\n";
}
int main()
{
int i,j;
check c;
check b;
c.change();
b.change();
return 0;
}
Now you have worked out how to use static class members I will advise you that you should generally use them only in the following circumstances:
For use in templates. So in your example you could have GetX() in different classes and in a template somewhere you would use
template< typename T >
int func()
{
return T::GetX();
}
although obviously more elaborate. But here your static function being in a class serves a purpose.
Where the function needs access to the class, i.e. to private members. You could make it a friend but you may as well make it static. Often the case in callbacks.
The rest of the time you can probably use compilation-unit level functions and variables which has the advantage of taking your members out of the header (particularly if they are private). The less implementation detail you give the better.
You can use the inline keyword since c++ 17 in front of static members to avoid a definition outside of class scope. Your code should now look like this:
#include <iostream>
using namespace std;
class A
{
public:
inline static int x;
static int getX() {return x;}
};
int main()
{
A::x = 100; //Works now
cout<<A::getX()<<'\n';
return 0;
}
Case 1: static variable
As we all know, defining a static variable inside a class which will throw compilation error. E.g. below
class Stats
{
public:
static int AtkStats[3];
*static int a =20;* // Error: defining a value for static variable
};
int Stats::AtkStats[3] = {10, 0, 0};
Output:
error: ISO C++ forbids in-class initialization of non-const static member 'Stats::a'
Case 2: const static variable
For const static variable, we can define a value either inside a class or Outside class.
class Stats
{
public:
static const int AtkStats[3];
static const int a =20; // Success: defining a value for a const static
};
const int Stats::AtkStats[3] = {10, 0, 0};
const int Stats::a = 20; // we can define outside also
Output:
Compilation success.