How can I amend the code to make static double work in this context?
I researched and found I could use inline in 17 version of C++.
I'm into pre-17, so i'm asking for your advise.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#define SAVINGS_H
class Savings
{
public:
staticdouble annualInterestRate = 0.04;
explicit Savings(double );
void calculateMonthlyInterest ();
private:
double savingsBalance; // probably should be static
};
there is no need for this to be static since it is a constant. Static keeps the current value connected for all instances of the class, but as a constant, they are always the same anyway. No harm to do it, but clutter to make it static.
non-static const member variables are assigned separate memory locations for each instance. static const members use the same memory address for each instance. Consider:
There has to be a way to have no memory used for a constant, just injected at compile time in place as its value. Something is off there, IMHO, with the optimizer.
I would assume that any decent compiler will "eliminate" a const (or constexpr) variable, regardless of whether it is static or not, and simply "inline" the actual value wherever the const variable is used in the code – provided that the value can already be determined at compile-time. In fact, the compiler may do this with non- const variables just as well, provided that the compiler can deduce that they're "effectivelyconst".
(By printing the address of the const variable, you're probably "forcing" the compiler to not optimize it out)
Except in a trivial situation, storage for const member objects can't be optimised away (by a conforming implementation). Computations on those const members may be performed at compile time (typically on const objects).
#include <numeric>
#include <iterator>
struct A
{
constint c1 = 99 ;
constint c2[4] { 0, 1, 2, 3 } ;
};
// the object representation of A includes those of the const member objects
static_assert( sizeof(A) >= ( sizeof(constint) * 5 ) ) ;
externconst A ca ;
const A ca ; // const, but storage for ca can't be optimised away (extern)
A ma ; // non-const, storage for ma can't be optimised away
int sum_const()
{
// compute 99 + 0 + 1 + 2 + 3 + sizeof(A) at compile time; return 125
return ca.c1 + std::accumulate( std::begin(ca.c2), std::end(ca.c2), 0 ) + sizeof(ca) ;
}
int sum_mutable()
{
// compute sum of members + sizeof(A) at run time
return ma.c1 + std::accumulate( std::begin(ma.c2), std::end(ma.c2), 0 ) + sizeof(ma) ;
}
There has to be a way to have no memory used for a constant, just injected at compile time in place as its value. Something is off there, IMHO, with the optimizer.
From what I've heard untested. Constexpr will use different memory addresses across different modules. (I've heard this about static aswell) from my understanding to use minimal amount of resources the Constexpr need to be marked as inline. If I was to make a claim as to no memory usage I would say preprocessor directives namely #define's.
@jonin... I disagree. I think that might be the case if it the variable was born and died in the same stack frame and wasn't part of an object. The only way to know would be to poke around in the assembly. My assumption is that when an object is instantiated it needs to live somewhere and the compiler isn't going to look at every possible scenario to see if its possible for something to be done with that pointer at runtime. For the example that might seem like an easy task but there's layers and layers of stuff happening behind the scenes that it has to sift though. Even using cout pushes that variable to the iostream library where it needs to decide what to do with it based on the type and if it's a lvalue or an rvalue. << is an operator overload that will make a implicit copy of the rvalue if no temp reference exists. That being said even doing cout<<69; will make a copy of 69 bc if it has no reference it can't travel.
I had thought about the containment for sure. It's just one of those things to where unless you're only doing relatively simplistic comparisons with a variable its not going anywhere but once you send it into a template library.... its getting sent all over the place. Have you ever looked at a function tree of a program? Even something with only a few lines of code looks damn near incomprehensible. I give those guys credit on their work bc im not sure how they'd ever have time to do anything else. Write something simple compile it and decompile it with ida or equivalent.... the decompiled code will show you if it thinks it's an object or a hard-coded value. It will take you awhile to figure out what you actually wrote strings are usually kinda easy way to determine your code. But you'll still probably bounce around 50-100 functions b4 you find what you wrote.
In practice, even with whole program optimisation, the memory layout of class objects is not optimised. Since strict aliasing is permitted, it is not easy for an optimiser to do very much in this case.