C++ variable equals not variable - c++

generate = !generate;
I saw this in the generateGaussianNoise function here: https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
double generateGaussianNoise(double mu, double sigma)
{
static const double epsilon = std::numeric_limits<double>::min();
static const double two_pi = 2.0*3.14159265358979323846;
thread_local double z1;
thread_local bool generate;
generate = !generate;
I don't understand the logic of this: variable = !variable;
coming from a Python background. Can someone explain?
One specific question: I would expect generate = True to be somewhere here bbut I don't see it.
Two specific question:
if (!generate)
return z1 * sigma + mu;
How can this code work if z1 is not assigned until AFTER this piece of code?

According to this reference
Variables declared at block scope with the specifier ... thread_local (since C++11) have ... thread (since C++11) storage duration but are initialized the first time control passes through their declaration
[Emphasis mine]
So when the function is called the first time, the generate variable will be default initialized which for thread_local variables means zero initialization. Zero initialization for a bool variable means it will be set to false, and for a double it will be 0.0.

It's a quick way to flip a bool variable from true to false and vice versa. It avoids having to write:
if (generate)
generate = false;
else
generate = true;
As for the initialization of generate, thread-local variables get default-initialized. For a bool that means false.

thread_local is type of storage duration; new to C++11. It's the same as static except you get a new instance of the variable per-thread.
Like static, a thread_local bool type is initialised automatically to false.
generate = !generate; flips that value, and that value is retained on a per-thread basis for a subsequent invocation of that function.
I wouldn't recommend generating Guassian random numbers in this manner though - the technique is painfully slow (sampling with rejection is faster). The code in the link you cite is terrible - for starters rand() is not thread safe so all this thread_local stuff is a nonsense. And the use of std::numeric_limits<...>::min() for an "epsilon" shows minimal understanding of floating point properties.
There's no need to program at this low level; C++11 has Box-Muller built in to it's much-improved random number libraries.

generate is acting as a flag variable, which toggles as per need. It is analogous to
if (generate == True)
generate = False
else
generate = True
For the second part of the code, where
How can this code work if z1 is not assigned until AFTER this piece of code?
As it is a return statement, this must be a part of some function or so, and hence z1 must be defined in the calling function and its value passed to the called function.

Related

Initializing a variable with a function that takes that variable as an argument

I was recently reviewing some code and I came across something that I was confused about. Say I have a functions, int getNewNumber(int num, int dir), implemented like this:
int getNewNumber(int num, int dir) {
int newNum = num;
if(dir == 1) {
newNum++;
} else {
newNum--;
}
return newNum;
}
Now, when calling the function, I have something like this:
int number = getNewNumber(number, 1);
Is it initialized to 0 before being passed into newNum? I'm confused about how you can use the variable as an argument when it's being initialized.
Is it initialized to 0 before being passed into newNum?
Maybe. It depends on context. If the variable is a global static, then it is zero initialized before dynamic initialization.
If it is an automatic variable, then the value passed into getNewNumber is indeterminate and using that value has undefined behaviour. A decent compiler will warn you.
I'm confused about how you can use the variable as an argument when it's being initialized.
If the variable wasn't initialized statically, then you can't use its value in its own initialization in a way that would have defined behaviour.
If the variable was zero initialized before dynamic initialization, then you can use the value, but you might as well use literal zero, and that would be clearer to the reader of the program. I don't think there is any useful way to use the value of a variable in its own initialization.
I really think it depends on the compiler. In general I'd call it unsafe - in the best case you'll get a a value, that has the same type, or can be converted to this type. In the worst case - the program will simply crash.

C++ initialization of reference variable

I spotted a "mistake" in my code today... But I'm not sure if the "mistake" actually changes the resulting compiled code.
Consider initialization of the following reference to a double, x.
double &x{*_data->x_double}; // x_double is a member variable of the struct
// _data, it is a pointer to another double
// eg, I have this somewhere else...
struct data
{
double *x_double;
};
data *_data = new data; // edit: duh, this has to be a pointer...
double another_x = 10.0;
_data->x_double = &another_x; // edit: pointer here too!
However I made the following "mistake"... (notice the extra = sign)
double &x={*_data->x_double};
This code is a minimal example copied from my actual code, in which I don't have references to doubles, but references to large objects such as std::vector's.
The reason for the reference variables is that they are used in an algorithm, and the variable names are very long, so I create shorted aliases for those variables using references. Hope it makes sense why I did that...
So, I've "corrected" the "mistake" but has my output compiled code actually changed?
They're both list initialization. For your cases:
double &x={*_data->x_double};
Is :
6) initialization of a named variable with a braced-init-list after an
equals sign
And
double &x{*_data->x_double};
Is :
1) initialization of a named variable with a braced-init-list (that
is, a possibly empty brace-enclosed list of expressions or nested
braced-init-lists)
Their effects are in this case exactly the same.

What do the standards (C++) say about compile time initialization?

In other words, when is a "static const" equivalent to a "#define"?
I searched a lot and can't find anything.
This is very relevant for global initialization dependencies (I know, globals are evil, but life is evil too!).
I am sure the standard does not force, but it probably mentions it.
E.g.:
static const int a = 2; // Always seen it as compile time
static const int b = 2 * a; // Compile time
static const float c = 3.14; // Compile time
static const float d = c * 1.1 ; // I know the evils of compile time here, but I've seen it both ways (compile and run time)
static const char e = 'p' ; // Compile time
static const int *f = NULL; // Never really tried it :)
This is specified by C++11 3.6.2: constant initialization is performed...
if an object with static or thread storage duration is not initialized by a constructor call and if every full-expression that appears in its initializer is a constant expression.
This is your situation, except for d: int and float don't have constructors, and the initializer is a literal, which is a constant expression. Constant initialization is part of static initialization, and:
Static initialization shall be performed before any dynamic initialization takes place.
The standard doesn't explicitly prescribe an implementation, but there is no ordering of static initializations, and it is understood that the initial values are essentially provided at load time, and no code executes in order to get those global variables to have their initial values.
The variable d does not meet these criteria since its initializer is not a constant expression (because c is not a constant expression). The standard allows d to be initialized either dynamically or statically.
Answering: 'In other words, when is a "static const" equivalent to a "#define"?'
Never, the first is part of the programming language, the latter is a preprocessor text processing directive.
Declaring static const vs a define are two different things. A value replaced by define can non-const and non-static.
#MY_VAR 9
static const int a = MY_VAR;
int b = MY_VAR;
Defines essentially precompile time string replacement. Static and const keywords work all together different.

Constant value calculation

I have an hpp file with following code:
const float PixelsPerMeter = ConfigManager->Get<float>("koef", 100.0f);
inline const float Meters2Pixels(float meters) { return meters * PixelsPerMeter; }
inline const float Pixels2Meters(float pixels) { return pixels / PixelsPerMeter; }
const float ScreenArea = Pixels2Meters(ScreenSizeX) * Pixels2Meters(ScreenSizeY);
It worked before, but now ScreenArea = inf somehow. I use it from static function. I put a breakpoint in that function and print out the value of PixelsPerMeter(100.0), ScreenSizeX and ScreenSizeY. Everything is okay, but ScreenArea is calculated wrong.
When I write directly Pixels2Meters(ScreenSizeX) * Pixels2Meters(ScreenSizeY) instead of using ScreenArea constant everything works.
How it could be?
I think, the problem is with your global variable, to be precise with its initialization.
If by the time the variable has not been dynamically initialized when you call Pixels2Meters(), the variable PixelsPerMeter is statically initialized to zero, so the function Pixels2Meters() returns inf which very much implies PixelsPerMeter is zero.
But you put break points, the story could be slightly different; it is analogous to Heisenberg uncertainty principle, in the sense that when you want to see the value of PixelsPerMeter by putting breakpoints, it shows you different value than the value when there is no breakpoints.
Also note that since the variable is declared const, without extern keyword, the variable has internal linkage, which means you will have different copy of this variable in each translation unit, in case if it declared in a header file which you include in several source files. The variable's behavior is as if it is declared static.
Another important point to be noted is that this variable is initialized twice: the first initialization is called static initialization which happens at compile-time, and second initialization is called dynamic initialization which happens at runtime. In case of static initialization, the variable is initialized to zero, and that is the value which is being used which is causing the problem. To know more about it, read this:
What is dynamic initialization of object in c++?
You should also read about this:
static initialization order fiasco
When the static function is initialised is a bit complicated and may depend on system/compiler.
You probably have an issue that the ConfigManager() isn't initialised before the static function you are using it in.

Why do some const variables referring to some exported const variables get the value 0?

Consider the following. I have two exported constants as follows:
// somefile.h
extern const double cMyConstDouble;
extern const double cMyConstDouble2;
and
// somefile.cpp
const double cMyConstDouble = 3.14;
const double cMyConstDouble2 = 2.5*cMyConstDouble;
These constants are now referenced some place else to define two static (locally visible) constants:
// someotherfile.cpp
#include "somefile.h"
static const double cAnotherDouble = 1.1*cMyConstDouble;
static const double cAnotherDouble2 = 1.1*cMyConstDouble2;
printf("cAnotherDouble = %g, cAnotherDouble2 = %g\n",
cAnotherDouble, cAnotherDouble2);
Which yields the following output:
cAnotherDouble = 3.454, cAnotherDouble2 = 0
Why is the second double 0? I'm using .NET 2003 C++ compiler (13.10.3077).
I'm not going to dip my toe into the issues of extern here, but why do you simply not place the consts in the appropriate header files and forget about "exporting" them using extern? This is how consts are supposed to be used in C++, and why they have internal linkage.
In other words:
// someheader.h
const double cMyConstDouble = 3.14;
const double cMyConstDouble2 = 2.5*cMyConstDouble;
and #include that file wherever you need them.
Because cMyConstDouble is declared as extern, compiler is not able to assume its value and does not generate a compile time initialization for cMyConstDouble2. As the cMyConstDouble2 is not compile time initialized, its order of initialization relative to cAnotherDouble2 is random (undefined). See static initialization fiasco for more information.
This is dangerous thing to do as your one static variable in one source file depends upon the another static variable in another cpp file. Check static initialization fiasco for more information.
If you change the initialization of cMyConstDouble2 to this here:
const double cMyConstDouble2 = 2.5*3.14;
Then your program should behave correct. The reason for this is that variables that
Have POD type
Are initialized with constant expressions (1)
are initialized at static initialization time. These initializations include
Zero initialization of all objects having static storage duration
Initializations of PODs initialized with constant expressions
Of your shown variables, only cMyConstDouble satisfies both conditions of being fully initialized at static initialization time. However, cMyConstDouble2 does not, since its initializer does not satisfy the requirements of a constant expression. In particular, it includes a variable that doesn't have integral type (here, it has floating point type). However, floating point literals are allowed in arithmetic constant expressions. That is why 2.5*3.14 is an arithmetic constant expression. And that is why changing the initializer to that will require it to be statically initialized.
What will happen with cMyConstDouble2 if you stay with the non-constant expression? The answer is, you don't know. The Standard allows that variable to be statically initialized, but does not require it to do so. In your case, it was dynamically initialized - thus its value just after static initialization time was still zero. To get a feeling for how complicated that is, here is an example:
inline double fd() { return 1.0; }
extern double d1;
double d2 = d1; // unspecified:
// may be statically initialized to 0.0 or
// dynamically initialized to 1.0
double d1 = fd(); // may be initialized statically to 1.0
If the dynamic initialization doesn't change any other static storage variable (satisfied in your code) and when the static initialization would produce the same value as would be produced by dynamic initialization when all objects not required to be statically initialized would be initialized dynamically (also satisfied in your code) - then the variable is allowed to be initialized statically. These two conditions are also satisfied in the above code for both variables d2 and d1:
Analysis of d2
= d1 does not change any other static storage variable
When both d2 and d1 are initialized dynamically, then d2 would be initialized to 0.0, because d2 is defined before d1, and dynamic initialization of d2 would grab the value of d1 as of the state just after static initialization (where only zero initialization of d1 took place).
Analysis of d1
= fd() does not change any other static storage variable
When both d2 and d1 are initialized dynamically, then = fd() will initialize d1 to 1.0.
So, the compiler may initialize d1 statically to 1.0, because both conditions for optional-static-initialization are met.
If the compiler decides to initialize d1 and d2 dynamically, then d2 will be initialized to 0.0, since it will grab the value of d1 as it was just after zero initialization.
However, if the compiler decides to initialize d1 statically and d2 dynamically, then d2 will be initialized to 1.0, since the dynamic initialization of d2 will grab the fully initialized value of d1 as it was just after static initialization.
I'm not sure what the value of d2 is when d1 and d2 is initialized statically, though. That is, whether d2 is supposed to grab the 0.0 or the 1.0, since there is no order defined for static initialization.
(1) Constant expressions include arithmetic constant expressions too (not only integral constant expressions), when considering initialization order of objects with static storage duration.