Likely default value of an undefined variable

I have the following equation:

ecc    = 1.736d57 * fcc * gcc * density

The thing is, the variable fcc is never defined in terms of a value; it is never assigned anything.
The code runs and yet, how?
What is the likely default value of fcc?
I have checked and this value has been present since I first got this code and only now am I finding it (actually, I found it a little while back but I haven’t been involved too seriously in this part of the model until now).
I will find out what it SHOULD be, but interested in why this model works, despite this not being assigned any value.

Are you familiar with the -Wunitialized flag (also included with -Wall) in gfortran?

~/fortran$ cat maybe_uninitialized.f90 
double precision :: gcc, density, ecc
gcc = 2.0d0
density = 1.0d0
ecc    = 1.736d57 * fcc * gcc * density
print *, ecc
end
~/fortran$ gfortran -Wall maybe_uninitialized.f90 
maybe_uninitialized.f90:4:39:

    4 | ecc    = 1.736d57 * fcc * gcc * density
      |                                       ^
Warning: 'fcc' is used uninitialized [-Wuninitialized]
maybe_uninitialized.f90:4:23:

    4 | ecc    = 1.736d57 * fcc * gcc * density
      |                       ^
note: 'fcc' was declared here

  1. Are you using -finit-local-zero in the compilation?
  2. Do you know for certain it runs correctly?
    2.a) What kind of verification and/or validation have you performed?

Compiler-dependent. For a previous discussion see Some type of automatic initialization of variables? - #4 by rwmsu

If it really works despite the uninitialized variable, it’s probably that ecc is not used for anything important in the model.

No, I wasn’t. I think it was mentioned way back but I will try it.

No, I am not using that option.
Correctly, in that the model produces results as expected; so, the base model results match predicted.

I am using gfortran (if that helps).

ECC is the total energy gained through the conversion from hydrogen to helium to carbon to oxygen, using the triple alpha process (and more). This is a significant contributor to stellar temperature, etc and a driving force behind star evolution. So, it is should be important. Hahaha!

However, I do not yet know what fcc is in that system.

Equally, I cannot confirm yet that the result of this reaction is used, or if it is using the ratio of energy; which might mean you are totally correct (and, in turn, Ivan is, in that I would not know if this calculation is actually working correctly).

I will now check further. Early days on this part.

There are other ways for a variable to acquire a value than an assignment statement.

The statement may be inside an IF(<condition>)…ENDIF block that is not entered because the condition is not satisfied. The line of code may be a vestige of older code that was imperfectly removed before you received the code. The subprogram that contains the statement may not be called for certain program data sets.

That is not a valid question in a forum such as the present one, nor is an answer useful to you.

Here is a short program that is pertinent to the issues with this thread. Try to work out the answer to “What is its expected output?” without using a computer to compile and run it.

program indef
   print *,transfer('CARTHAGO DELENDA EST',0d0)
end program

I fear you missed the point behind my question, which would not be difficult given I did not define it clearly.

I am not interested in the value of fcc, or if this section of code is running (it is). The issue with fcc and the entire section, is slowly being unpicked and improved.

My question is purely curiosity in that what is the system likely doing to the undefined variable, in terms of compilation?

I know in this specific case that this section of code does run. I also know in this specific case that whatever is happening is not having a considerable impact upon the model. That could be for a multitude of reasons, including that the role of fcc is so insignificant that a default value of 1 is fine, or that the default value is accidentally close to the range of fcc (zero would be a significant factor) or even that ecc, where fcc is only ever appearing, is not being used (or, more accurately, later calculations based on ecc results are not being used).

Whatever the issue with fcc is, I will resolve that over the next few days. I am purely intrigued with what gfortran is doing - purely out of curiosity.

It’s fairly easy to test what different compilers do to uninitialized variables:

program main
    implicit none

    real :: x

    print *, x
end program

Then you can try different compilers and flags. For example:

$ gfortran main.f90 && for i in {1..10}; do ./a.out; done
   5.17461830E-24
   5.84620817E-17
   1.06416293E-03
  -1.72170103E-02
   1.18819388E+23
   6.59463023E-20
  -1.98622284E-30
  -6.92440164E+12
  -2.12326761E-30
   106597.242
$ ifort main.f90 && for i in {1..10}; do ./a.out; done
  0.0000000E+00
  0.0000000E+00
  0.0000000E+00
  0.0000000E+00
  0.0000000E+00
  0.0000000E+00
  0.0000000E+00
  0.0000000E+00
  0.0000000E+00
  0.0000000E+00

Interestingly, when I use optimization, my currently installed gfortran version seems to use zero in this case:

$ gfortran -O3 main.f90 && for i in {1..10}; do ./a.out; done
   0.00000000    
   0.00000000    
   0.00000000    
   0.00000000
   0.00000000    
   0.00000000
   0.00000000    
   0.00000000
   0.00000000    
   0.00000000

I read a quote once that was something like this: “If you have undefined behaviour in your application it might work just fine, it might erase your hard drive or it might start playing Quake on its own”. That is of course highly unlikely in this case, but the point is that you simply don’t know what you’ll get.

@plevold thank you.

And, once I had stopped doing what I was doing, I realised how stupid I was being by posting the question: I could have simply written a small program to test this out (just as you did)!

Just goes to show how easy it is to not think whilst you are thinking! Hahaha!

Zero is interesting, since it wipes out that section of the code (that particular equation is much longer). Tells me that this part is most likely invalid; or cancelled out further into the equation. However, that is for me to find out and wasn’t the point of my OP; just a nice side gain.

1 Like

So that’s a good point to note that with variables, if they are undefined (not initialized explicitly) and yet referenced on the right-hand side of equations (e.g., assignments in Fortran with var = expr), a compiler can treat them differently depending on the compiler options selected by the user, optimization is after all such an option (e.g., -O2).

Thus with an undefined variable in the mix, a program cannot be expected to have defined (consistent) behavior.

gfortran also has a compiler option -finit-real=<zero/inf/-inf/nan/snan> for local variables that can result in different values and different program behavior.

1 Like

And I definitely suggest you to use something like -finit-real=snan, -finit-integer=-99999 and -ffpe-trap=invalid,zero,overflow options:

And then check the results of the code or if there is an exception. You cannot really believe the results if some variable is not initialized.

For others seeing a similar initial situation …

It looks like this is really uninitialized but using just the original single-line post it does not show if any modules or common blocks are used, which might be initializing the value in another location. Printing the value is useful even if just wondering what is happening to it, uninitialized or not.

Not initially finding an initialization can be particularly easy to miss with modules if the ONLY parameter is not used and IMPLICIT NONE is not declared. From the description I am assuming this code is likely using implicit typing, which becomes a bigger problem when modules are being used than with a self-contained unit. Contained procedures can also lead to confusion where a variable may be imported or alternatively declared in the local scope.

The general approach is to turn on as many of the debug flags as you can when deconstructing code. I am curious why as to whether the value is used or not seemed to be undetermined. Typically you can follow the value and see that by inspection, but if not the flags described above can be particularly useful.

@urbanjost
For clarity, implicit none is declared, no modules are imported, no variable called fcc appears in any of the modules that are imported, fcc is declared as a real at the top of this function.

I can atest that fcc has no value assigned from any point whatsoever. The setting of this to zero is likely to have little to no affect upon low mass objects, since this part of the nuclear reaction requires high density regions - those unlikely to be experienced in a star at the mass equivalent to our Sun. This omission is more likely to affect massive stars (mass > 10 sol masses), which is where this model is going. If this is set to zero for low mass, no odds. If this is set to a low value then it would be approximating zero anyway (due to the rest of the equation). A large value might produce an anomaly but it doesn’t. The evidence given is that it is set to zero.

None of which is important, since I now simply need to find the actual screening factor equation and plug that in. The main question was interest in what the compiler does in such situations; gfortran appears to zero them by default.

Thank you. :slight_smile:
I will add these to my list, once I have checked out what they do. :slight_smile:

@plevold showed upthread gfortran does not “appears to zero them by default”:

image

Okay, thank you.
I took from @plevold’s example, and comment, that zero was the default. You have shown that is not the case.
Though it is now of little interest, it looks now as if the variable is simply assigned to an area of memory and its default value is anything that is already there?

Anyway, been an interesting foray into a curiosity.
Thanks everyone. I propose this discussion now ends. :slight_smile:

Years ago I tried the equivalent of -finit-real=<zero/inf/-inf/nan/snan> with another compiler (I think it was g95 but am not now sure) and found that it worked as I had hoped with scalars, but not with arrays.
Caveat emptor.