I am looking at a code for a least square method, and I came across the following few lines:
static double one = 1.0;
static double p1 = 0.1;
static double p5 = 0.5;
...
and I was wondering why someone would define a static
for 1.0
. I can understand having something for pi
, for example, but for trivial mathematical values like 1.0
and 0.1
, etc.? I think it will make the code less readable, but it might have some other benefit(s) that I'm missing.
So, is there a reason for these definitions? or, if it is not being used with modern codes, were there any reasons for this with old compilers? I know that the code that I'm looking at was translated to C/C++ from FORTRAN. Were there any reasons for this in FORTRAN?
I know that the code that I'm looking at was translated to C/C++ from FORTRAN. Were there any reasons for this in FORTRAN?
FORTRAN uses pass-by-reference for all subroutine parameters. However, unlike other languages with pass-by-reference, it still lets you pass “rvalues” as parameters. Behind the scenes, the FORTRAN compiler converts code like:
CALL SUBFOO(X + Y, 4)
to code like
TEMP1 = X + Y
TEMP2 = 4
CALL SUBFOO(TEMP1, TEMP2)
And this is exactly what your C++ code is doing: Creating variables in order to pass a pointer (or reference) to a subroutine FORTRAN-style.
Of course, this is not idiomatic C or C++. Normally, you'd pass a double
by value.
(Code samples copied from my answer to this question.)
Use of
static double one = 1.0;
static double p1 = 0.1;
static double p5 = 0.5;
does not make much sense to me. It would make sense had the variables been named with something more meaningful. I see the value of something like:
static double defaultCoefficient = 1.0;
static double defaultRateOfIncrease = 0.1;
static double defaultRatio = 0.5;
In the second set, use of the variables in code is a lot more meaningful than using the corresponding constants.
It would be more meaningful to make them constant.
static double const defaultCoefficient = 1.0;
static double const defaultRateOfIncrease = 0.1;
static double const defaultRatio = 0.5;
I know that the code that I'm looking at was translated to C/C++ from FORTRAN.
If the translation was done by a program, it's understandable why the variables are named the way they are.
If the translation was done by a human, they probably followed some guideline on how to move things fast, and not necessarily create meaningful variable names by understanding the code.
One case where I've seen this used is on some (older, embedded) platforms using a Harvard architecture.
Say I have a (external library) function that takes a pointer as argument:
void Foo(double *Bar);
If i want to pass a constant to this function I obviously cannot write it directly. I have to do it like in the opening post so I can take the address of one
for example.
Foo(&one);
On some Harvard platforms const
values are put in program ROM or flash memory instead of RAM, so that would not work as you'd be taking the ROM address instead of the required RAM address.
Making it a global (static) variable is then done so it is initialized once in the startup code (value copied from ROM to RAM once) in stead of every time it is needed by making it a automatic variable.
A niche use case I admit.
No, that constant is silly. If for no other reason than it's not actually a constant.
There actually is a good reason to do this, and it involves the software development process itself.
Let's say you have a translation unit that invokes some function with some numeric parameter, naturally you'd make it a constant:
static const double epsilon = 1.e-3;
Nice, clean code. But now you realize that the epsilon you set isn't all that good and you need a better one. You don't really have a sure way to determine what it should be, so you go for some trial and error:
static const double epsilon = 1.e-4;
You rebuild you program. And it still isn't good. If you change it again you'd have to wait for the build to finish, and it can take a while on some non-trivial projects. What to do?
Well, debuggers let you change the value of variables, so long as they reside in memory (and not eliminated like true constants are). So we do the following:
static double epsilon = 1.e-4;
Now we set a breakpoint somewhere in that file. And we can modify epsilon
without rebuilding our program every time. We end up saving precious development time. And we find a proper value in no-time.
Do we leave it non-const
? No. This is a constant, and therefore we mark it as const
before checking our code in. Leaving it non-const is a code smell. There is no further purpose to this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With