static variable inside function vs static class variable in c++ - c++

For a unique id for some object I can create a counter in two ways but I don't know which one is better while they are quite different in code (though maybe not in byte code, I have no idea).
The first way would be to have some function which uses a static variable:
Header:
unsigned int GetNextID();
cpp:
unsigned int GetNextID()
{
static unsigned id{0};
return id++;
}
The other option:
Header:
class UniqueIdGenerator
{
public:
static unsigned int GetNextID();
private:
static unsigned int mID;
}
cpp:
unsigned int UniqueIdGenerator::mID = 1;
unsigned int UniqueIdGenerator::GetNextID()
{
return ++mID;
}
FYI, I've read that the former is not thread safe, but I don't see why the latter would be either. If anything, I like the simple function more as it's simpler & shorter.

To make it thread-safe you should change to std::atomic<unsigned> mID, and write your function as
return mID.fetch_add(1);
Which version you choose shouldn't matter, although in my opinion the free function would be the one I'd prefer as it's not possible to access the variable outside of the function.

The difference is scope/visibility of the static variable. A class member can be shared by more than one method, the variable in the method cannot.
On the principle that data should be as private as possible, the static variable in the method is safer if it meets your needs.
For a discussion of thread safety when initializing the variable, see this question., but using the variable is not thread safe unless you take some steps to insure that it is protected (either use and atomic (preferred for a simple value), or protect it with a mutex (if there is more than one piece of data that should be protected))

Related

How do I assign to a const variable using an out parameter in C++?

In a class header file Texture.h I declare a static const int.
static const int MAX_TEXTURE_SLOTS;
In Texture.cpp I define the variable as 0.
const int Texture::MAX_TEXTURE_SLOTS = 0;
Now in Window.cpp class's constructor I attempt to assign to the variable using an out parameter, however this obviously does not compile as &Texture::MAX_TEXTURE_SLOTS points to a const int* and not an int* .
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &Texture::MAX_TEXTURE_SLOTS);
I have tried using const_cast, but am greeted with a segmentation fault on runtime.
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, const_cast<int*>(&Texture::MAX_TEXTURE_SLOTS));
I have also tried directly casting to an int * but once again, seg fault.
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (int*)&Texture::MAX_TEXTURE_SLOTS);
Many thanks.
EDIT 2: So since you're trying to abstract OpenGL contexts, you'll have to let go of the "traditional" constructor/destructor idioms. And just for your information (unrelated to this question): OpenGL contexts are not tied to windows! As long as a set of windows and OpenGL contexts are compatible with each other, you may mix and match any way you like. But I digress.
The standard idiom to deal with a situation like yours is to use preinitializing factory functions. Like this:
class MyOpenGLContextWrapper {
public:
// Yes, shared_ptr; using a unique_ptr here for objects that are kind
// of a nexus for other things -- like an OpenGL context -- just creates
// a lot of pain and misery. Trust me, I know what I'm talkink about.
typedef std::shared_ptr<MyOpenGLContextWrapper> ptr;
struct constdata {
NativeGLContextType context;
// ...
GLint max_texture_image_units;
// ...
};
static ptr create();
protected:
MyOpenGLContextWrapper(constdata const &cdata) : c(cdata) {};
virtual ~MyOpenGLContextWrapper();
constdata const c;
}
MyOpenGLContextWrapper::ptr MyOpenGLContextWrapper::create()
{
struct object : public MyOpenGLContextWrapper {
object(MyOpenGLContextWrapper::constdata const &cdata) : MyOpenGLContextWrapper(cdata) {}
~object(){}
};
MyOpenGLContextWrapper::constdata cdata = {};
// of course this should all also do error checking and failure rollbacks
cdata.context = create_opengl_context();
bind_opengl_context(cdata.context);
// ...
glGetInteger(GL_MAX_TEXTURE_IMAGE_UNITS, &cdata.max_texture_image_units);
return std::make_shared<object>(cdata);
}
EDIT: I just saw that you intend to use this to hold on to a OpenGL limit. In that case you can't do this on a global scope anyway, since those values depend on the OpenGL context in use. A process may have several OpenGL contexts, each with different limits.
On most computer systems you'll encounter these days, variables declared const in global scope will be placed in memory that has been marked as read only. You literally can't assign to such a variable.
The usual approach to implement global scope runtime constants is by means of query functions that will return from an internal or otherwise concealed or protected value. Like
// header.h
int runtime_constant();
#define RUNTIME_CONSTANT runtime_constant()
// implementation.c / .cpp
int runtime_constant_query(){
static int x = 0;
// NOTE: This is not thread safe!
if( !x ){ x = determine_value(); }
return x;
}
You can then fetch the value by calling that function.
Provided that glGetIntegerv doesn't depend on other gl* functions being called before, you may use an immediately-invoked lambda:
// Texture.cpp
const int Texture::MAX_TEXTURE_SLOTS = []
{
int maxTextureSlots{0}:
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureSlots);
return maxTextureSlots;
}();
You don't.
You can't assign to a const outside of its definition. Also, using a const variable where the const has been const_casted away is UB. This also means you can't directly initialize a const variable with an output parameter. For trivial types, just output to another variable and make a const copy if you so wish.
If you were the author of the function you're calling, you would do well not to use out parameters, and then you could assign to const variables directly, perhaps using structured bindings if you want to name multiple of the outputs at a time. But here, you're not.

What are the implications of using a static member function with pthread_create()?

I'm helping a student with their homework, which is a basic threading exercise. Unfortunately, though they're required to use C++11, they're forbidden from using std::thread. I don't see the rationale, but it's not my homework.
Here's the class:
class VaccineInfo {
public:
VaccineInfo(const std::string &t_input_filename):
input_filename(t_input_filename)
{ }
VaccineInfo() = delete;
static void *count_vaccines(void *t_vi);
int v1_count() { return vaccine_count["v1"]; }
int v2_count() { return vaccine_count["v2"]; }
int v3_count() { return vaccine_count["v3"]; }
private:
std::string input_filename;
std::map<std::string, int> vaccine_count {
{ "v1", 0 },
{ "v2", 0 },
{ "v3", 0 }
};
};
void *VaccineInfo::count_vaccines(void *t_vi) {
VaccineInfo *vi = reinterpret_cast<VaccineInfo*>(t_vi);
std::ifstream input_file;
std::string input_line;
input_file.open(vi->input_filename);
if (!input_file.good()) {
std::cerr << "No such file " << vi->input_filename << std::endl;
return nullptr;
}
while (std::getline(input_file, input_line)) {
vi->vaccine_count[input_line]++;
}
return nullptr;
}
And here's where pthreads comes in.
std::vector<std::string> filenames = find_filenames(".");
std::vector<pthread_t> thread_handles;
std::vector<VaccineInfo> vi_vector;
vi_vector.reserve(filenames.size());
for(const std::string &filename : filenames) {
pthread_t tid;
thread_handles.push_back(tid);
vi_vector.emplace_back(VaccineInfo(filename));
pthread_create(
&thread_handles.back(), nullptr, &VaccineInfo::count_vaccines,
static_cast<void*>(&vi_vector.back()));
}
for (const pthread_t tid : thread_handles) {
pthread_join(tid, nullptr);
}
It's a pretty basic exercise, except for how much fluff you have to do to get the old and the new to play nice. And that's what's got me wondering - does using a static member method as the start_routine argument to pthread_create have any undesirable side effects? I know static member variables and functions don't "belong" to any objects, but I normally think of static variables as being one-per-class, regardless of the number of objects. If there's only one copy of the static member function, as well, that seems like you'd be shooting yourself in the foot for parallelization.
Would it just be better, in this case, to make vaccine_count public and make count_vaccines() a global function?
Do hit me with whatever detail you can muster; I'm very curious. =) And, as always, thank you all for your time and effort.
except for how much fluff you have to do to get the old and the new to play nice.
Well, in the STL, that's essentially what the std::thread is actually doing. If you create a thread and force it to cause a stack unwinding, and if you look at said stack, you'll see a lot of weird pointer arithmetic happening with this and pthread_create (or CreateThread on Windows).
That being said, it's not unusual in any way to use a static function of a class that then calls a private member of that class on an object instance, even with the std::thread, it really just depends on what you need those functions to do.
does using a static member method as the start_routine argument to pthread_create have any undesirable side effects?
No. At least not from the perspective of functionality; that is, creating a thread on a static member won't cause any UB or crashes directly just because you are using a static function.
You do have to account for the fact that your operating on a static member function, but that's no different from having to account for constructors/destructors or any function of the language itself. Since this is a homework assignment, it's likely the professor is trying to teach "how things work" less than "how to use C++11".
Would it just be better, in this case, to make vaccine_count public and make count_vaccines() a global function?
Yes and no. Having vaccine_count as a private member then means that count_vaccines must be a friend or static function, and given that vaccine_count seems like an "important" data point that you wouldn't want a "user of the code" inadvertently setting, it's probably better to keep it private.
You could add getters and setters, but that might complicate the code unnecessarily.
You could also just make it a public variable if you trust the users of the code to protect that variable (unlikely), and you could also just make count_vaccines a free/global function, but then you need to have the function after the class declaration. And if the class is a complex class (maybe has templates or some other C++ notion), then it can really complicate the code in how you operate on the class.
So yes, it could go that way, but the professor is likely trying to teach the idea of what a static function is, how threads operate on the class and how pointers work within the constructs of this exercise, among other things.
If you have a static member variable, all objects access that variable.
That's not what static means in this context. The static keyword in C++ simply means that you do not need an object reference to call that code. So a static member variable can be accessed, not just by any object, but by any code, take this example:
class Data {
public:
static int x_val;
int y_val;
};
int Data::x_val; // have to declare it since it's static
int main(int argc, char* argv[]) {
Data::x_val = 10; // works because it's static.
Data::y_val = 10; // error: accessing a non-static member
Data obj;
obj.y_val = 10; // ok because it's a member variable
obj.x_val = 20; // this works as the complier ultimately translates this to `Data::x_val = 20`
// BUT, referencing a static member/function on an object instance is "bad form"
return 0;
}
If you have a static member function... can it be called on more than one core simultaneously?
The static keyword has no effect on which core, or thread, said function is called on or if can be done in parallel.
A CPU core can only execute 1 machine level instruction per clock cycle (so essentially, just 1 assembly instruction), when a C++ program is compiled, linked and assembled, it is these "assembled" set of instructions base on the syntax you wrote that are executed on the core (or cores) of your CPU, not the static functions.
That static function is just an address in memory that gets called on any number of threads on any CPU core that the OS determines at any given time in your program.
Yes, you could call an OS API that pins that thread of execution calling that function to a specific core, but that's a different subject.
And for a last little bit of fun for you, on an assembly level, C++ functions basically get compiled into C-like functions (an extreme over simplification, but merely for demonstration):
C++
class Data {
public:
void increment() {
this->y_val += 1024;
}
private:
int y_val;
};
int main() {
Data obj;
obj.y_val = 42;
obj.increment(); // obj.y_val == 1066
return 0;
}
C
struct Data {
int y_val;
};
void Data_increment(Data* this) {
this->y_val += 1024;
}
int main() {
Data obj;
obj.y_val = 42;
increment(&obj); // obj.y_val == 1066
return 0;
}
Again, an over simplification, but the point is to illustrate how it all builds to assembly and what the assembly does.

How do I set constant configuration parameters at run-time

I am trying to achieve the following. I want to store some of the system information in a set of variables.
Say the variables are:
std::string GPU;
std::string CPU;
std::string OS;
I want these variables to have global scope, but only for reading (they should not be modified). Normally for this one would simply append const to the declaration. However for some of these variables I need to find the information at runtime after main has executed.
The issues is thus that I cannot simply initialize them statically as one normally would, I need to wait until some processing has been made to set them.
Overall I need the variables to be initialized once and exactly once by a function and then just be readable.
Is this achievable at all?
Why not hide required constants behind private static scope of a struct? In multithreaded environment you may even add a conditional variable and wait for initialization.
struct globals {
static const std::string& GPU() {assert(is_inited_); return gpu_;}
static init(std::string GPU, ...) {gpu_ = std::move(GPU); ...; is_inited_ = true;}
private:
std::string gpu_;
std::string cpu_;
std::string os_;
book is_inited_;
};
int main() {
...
// initialize consts at some point
globals::init();
...
// access consts
globals::GPU();
}
// initial values
std::string globals::gpu_;
...
bool globals::is_inited_ = false;

C++ global extern constant defined at runtime available across multiple source files

I have an integer constant that is to be defined at runtime. This constant needs to be available globally and across multiple source files. I currently have the following simplified situation:
ClassA.h declares extern const int someConstant;
ClassA.cpp uses someConstant at some point.
Constants.h declares extern const int someConstant;
main.cpp includes ClassA.h and Constants.h, declares const int someConstant, and at some point during main() tries to initialize someConstant to the real value during runtime.
This works flawlessly with a char * constant that I use to have the name of the program globally available across all files, and it's declared and defined exactly like the one I'm trying to declare and define here but I can't get it to work with an int.
I get first an error: uninitialized const ‘someConstant’ [-fpermissive] at the line I'm declaring it in main.cpp, and later on I get an error: assignment of read-only variable ‘someConstant’ which I presume is because someConstant is getting default initialized to begin with.
Is there a way to do what I'm trying to achieve here? Thanks in advance!
EDIT (per request from #WhozCraig): Believe me: it is constant. The reason I'm not posting MCVE is because of three reasons: this is an assignment, the source is in Spanish, and because I really wanted to keep the question as general (and reusable) as possible. I started out writing the example and midway it striked me as not the clearest question. I'll try to explain again.
I'm asked to build a program that creates a process that in turn spawns two children (those in turn will spawn two more each, and so on). The program takes as single argument the number of generations it will have to spawn. Essentially creating sort of a binary tree of processes. Each process has to provide information about himself, his parent, the relationship with the original process, and his children (if any).
So, in the example above, ClassA is really a class containing information about the process (PID, PPID, children's PIDs, degree of relation with the original process, etc). For each fork I create a new instance of this class, so I can "save" this information and print it on screen.
When I'm defining the relationship with the original process, there's a single point in which I need to know the argument used when calling the program to check if this process has no children (to change the output of that particular process). That's the constant I need from main: the number of generations to be spawned, the "deepness" of the tree.
EDIT 2: I'll have to apologize, it's been a long day and I wasn't thinking straight. I switched the sources from C to C++ just to use some OO features and completely forgot to think inside of the OO paradigm. I just realized while I was explaining this that I might solve this with a static/class variable inside my class (initialized with the original process), it might not be constant (although semantically it is) but it should work, right? Moreover I also realized I could just initialize the children of the last generation with some impossible PID value and use that to check if it is the last generation.
Sorry guys and thank you for your help: it seems the question was valid but it was the wrong question to ask all along. New mantra: walk off the computer and relax.
But just to recap and to stay on point, it is absolutely impossible to create a global constant that would be defined at runtime in C++, like #Jerry101 says?
In C/C++, a const is defined at compile time. It cannot be set at runtime.
The reason you can set a const char *xyz; at runtime is this declares a non-const pointer to a const char. Tricky language.
So if you want an int that can be determined in main() and not changed afterwards, you can write a getter int xyz() that returns a static value that gets initialized in main() or in the getter.
(BTW, it's not a good idea to declare the same extern variable in more than one header file.)
As others have mentioned, your variable is far from being constant if you set it only at run-time. You cannot "travel back in time" and include a value gained during the program's execution into the program itself before it is being built.
What you can still do, of course, is to define which components of your program have which kind of access (read or write) to your variable.
If I were you, I would turn the global variable into a static member variable of a class with a public getter function and private setter function. Declare the code which needs to set the value as a friend.
class SomeConstant
{
public:
static int get()
{
return someConstant;
}
private:
friend int main(); // this should probably not be `main` in real code
static void set(int value)
{
someConstant = value;
}
static int someConstant = 0;
};
In main:
int main()
{
SomeConstant::set(123);
}
Anywhere else:
void f()
{
int i = SomeConstant::get();
}
You can further hide the class with some syntactic sugar:
int someConstant()
{
return SomeConstant::get();
}
// ...
void f()
{
int i = someConstant();
}
Finally, add some error checking to make sure you notice if you try to access the value before it is set:
class SomeConstant
{
public:
static int get()
{
assert(valueSet);
return someConstant;
}
private:
friend int main(); // this should probably not be `main` in real code
static void set(int value)
{
someConstant = value;
valueSet = true;
}
static bool valueSet = false;
static int someConstant = 0;
};
As far as your edit is concerned:
Nothing of this has anything to do with "OO". Object-oriented programming is about virtual functions, and I don't see how your problem is related to virtual functions.
char * - means ur creating a pointer to char datatype.
int - on other hand creates a variable. u cant declare a const variable without value so i suggest u create a int * and use it in place of int. and if u are passing it into functions make it as const
eg: int *myconstant=&xyz;
....
my_function(myconstant);
}
//function decleration
void my_function(const int* myconst)
{
....
}
const qualifier means variable must initialized in declaration point. If you are trying to change her value at runtime, you get UB.
Well, the use of const in C++ is for the compiler to know the value of a variable at compile time, so that it can perform value substitution(much like #define but much more better) whenever it encounters the variable. So you must always assign a value to a const when u define it, except when you are making an explicit declaration using extern. You can use a local int to receive the real value at run time and then you can define and initialize a const int with that local int value.
int l_int;
cout<<"Enter an int";
cin>>l_int;
const int constNum = l_int;

Avoid creating multiple copies of code in memory

I'm new to developing on embedded systems and am not used to having very little program memory (16kB in this case) to play with. I would like to be able to create global variables, arrays, and functions that I can access from anywhere in the program while only existing in one place in memory. My current approach is to use static class members and methods that I can use by simply including the header file (e.g. #include "spi.h").
What is the best approach for what I'm trying to do?
Here is an example class. From what I understand, variables such as _callback and function definitions like call() in the .cpp will only appear in spi.o so they will appear only once in memory, but I may be mixed up.
spi.h:
#ifndef SPI_H_
#define SPI_H_
#include "msp430g2553.h"
class SPI {
public:
typedef void (*voidCallback)(void);
static voidCallback _callback;
static char largeArray[1000];
static __interrupt void USCIA0TX_ISR();
static void call();
static void configure();
static void transmitByte(unsigned char byte, voidCallback callback);
};
#endif /* SPI_H_ */
spi.cpp:
#include "spi.h"
SPI::voidCallback SPI::_callback = 0;
char SPI::largeArray[] = /* data */ ;
void SPI::configure() {
UCA0MCTL = 0;
UCA0CTL1 &= ~UCSWRST;
IE2 |= UCA0TXIE;
}
void SPI::transmitByte(unsigned char byte, voidCallback callback) {
_callback = callback;
UCA0TXBUF = byte;
}
void SPI::call() {
SPI::_callback();
}
#pragma vector=USCIAB0TX_VECTOR
__interrupt void SPI::USCIA0TX_ISR()
{
volatile unsigned int i;
while (UCA0STAT & UCBUSY);
SPI::call();
}
The data members and the member functions of the class you wrote will only be defined once in memory. And if they're not marked static, the member functions will still only be defined once in memory. Non-static data members will be created in memory once for each object that you create, so if you only create one SPI object you only get one copy of its non-static data members. Short version: you're solving a non-problem.
As per Pete, static won't affect code doubling up, only member vars. In your example, there is 0 difference between static non static memory usage except perhaps for the _callback var (which you call out as an error.) And that one variable would only double up if the class were created more than once.
If you want code to not exist in memory when not in use, look into overlays or some sort of dynamic linking process. DLL type code will probably be major overkill for 16K, but overlays with compressed code might help you out.
Also, beware of extra linked in code from libraries. Closely examine your .map files for code bloat from innocuous function calls. For instance, a single printf() call will link in all sorts of vargs stuff if it is the only thing using it. Same for software floating point (if you don't have a FP unit by default.)