# Forbid the use of undeclared and unset variables in print statements and the RHS of assignments

**URL:** <https://fortran-lang.discourse.group/t/forbid-the-use-of-undeclared-and-unset-variables-in-print-statements-and-the-rhs-of-assignments/7456>\
**Category:** Language enhancement\
**Created:** [February 22, 2024, 7:43pm UTC](https://fortran-lang.discourse.group/t/forbid-the-use-of-undeclared-and-unset-variables-in-print-statements-and-the-rhs-of-assignments/7456 "2024-02-22T19:43:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [February 22, 2024, 7:43pm UTC](https://fortran-lang.discourse.group/t/forbid-the-use-of-undeclared-and-unset-variables-in-print-statements-and-the-rhs-of-assignments/7456/1 "2024-02-22T19:43:55Z")

</div>

Whether to eliminate implicit mapping has been much discussed here, and the argument against doing so is that removing it would break a lot of working, standard-conforming code.

Would it be feasible to eliminate the use of variables in a `print` or `write` statement or the RHS of an assignment that have never been declared **and have not been set**? The code

```auto
euler = 0.577215
print*,euler
end

```

would still be allowed

but

```auto
euler = 0.577215
print*,eulr ! note typo
end

```

would not be. It would still be allowed to use an undeclared and unset variable in a subroutine call or function reference, because the subroutine may set the variable or never use it, and the function may never use it.

Currently the 2nd code can be compiled with gfortran -std=f2018 and gives random output. I don’t think this should persist indefinitely for future standards.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [February 22, 2024, 8:16pm UTC](https://fortran-lang.discourse.group/t/forbid-the-use-of-undeclared-and-unset-variables-in-print-statements-and-the-rhs-of-assignments/7456/2 "2024-02-22T20:16:18Z")

</div>

The standard already disallows undefined variables from appearing in uses where their value is required. But this is not something that can be reliably checked at compile-time, so it isn’t a constraint. Some compilers can diagnose this, and a few do it by default.

---

<div class="post-metadata">

**Author:** ![mecej4](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mecej4/32/855_2.png) [@mecej4](https://fortran-lang.discourse.group/u/mecej4)\
**Post date:** [February 23, 2024, 2:42am UTC](https://fortran-lang.discourse.group/t/forbid-the-use-of-undeclared-and-unset-variables-in-print-statements-and-the-rhs-of-assignments/7456/3 "2024-02-23T02:42:46Z")

</div>

The idea makes sense for scalar variables of intrinsic type, but consider what might happen if `euler` is an array, say `euler(4)`, and only its elements with indices 1 and 3 are defined, the array is in the output list of a diagnostic PRINT statement, and whether elements are defined or not is not knowable at compile time.

Similar problems may arise when (a) a copy of a variable of any type is made into a temporary variable, to be used only after an error condition might occur later, or (b) partial definition of a user-defined type variable, i.e., only some elements are defined and the undefined elements are used only in diagnostic print statements.

My objections could be deflected if Fortran were to provide an intrinsic inquiry function `defined()` or `initialized()` similar to `present()`, `associated()`, `allocated()`, etc…

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [February 23, 2024, 1:27pm UTC](https://fortran-lang.discourse.group/t/forbid-the-use-of-undeclared-and-unset-variables-in-print-statements-and-the-rhs-of-assignments/7456/4 "2024-02-23T13:27:34Z")

</div>

> [@mecej4](#):
>
> The idea makes sense for scalar variables of intrinsic type, but consider what might happen if `euler` is an array, say `euler(4)`, and only its elements with indices 1 and 3 are defined, the array is in the output list of a diagnostic PRINT statement, and whether elements are defined or not is not knowable at compile time.

My proposal is intended to catch spelling errors in variable names when the user fails to use `implicit none`. The compiler cannot be expected to catch the use of all uninitialized variables at compile time. Already you cannot refer to `euler(4)` unless you previously had either `real euler(4)` or `dimension euler (4)` earlier in the program unit.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [February 23, 2024, 2:40pm UTC](https://fortran-lang.discourse.group/t/forbid-the-use-of-undeclared-and-unset-variables-in-print-statements-and-the-rhs-of-assignments/7456/5 "2024-02-23T14:40:26Z")

</div>

The general term is use before define. This falls into the “quality of implementation” category. A compiler should be able to detect this in some cases (and I believe some compilers do), but probably not in the general case. For local and `intent(out)` variables it’s usually pretty obvious. You don’t even need the lack of a declaration to be able to detect that in most cases. But, in the case of use or host associated variables, intent(inout) or no intent arguments, or it’s passed as an argument to a procedure that might have defined it first, all bets are off. All that being the case, it certainly can’t be made a constraint, so compilers aren’t strictly required to detect the error at compile time, and the already present prohibition on use before define in the standard covers it.

---

<div class="post-metadata">

**Author:** ![gak](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/gak/32/146_2.png) [@gak](https://fortran-lang.discourse.group/u/gak)\
**Post date:** [February 24, 2024, 9:19pm UTC](https://fortran-lang.discourse.group/t/forbid-the-use-of-undeclared-and-unset-variables-in-print-statements-and-the-rhs-of-assignments/7456/6 "2024-02-24T21:19:43Z")

</div>

My recollection is that the “define before use” problem in general is not computable; the Halting Problem can be reduced to it. It falls into the general category that “any non-trivial property of a program is undecidable”.

Most compilers that detect the error look to see if there are any possible paths to a “use” that don’t appear to have a “define” along the way. They look at all the branches of conditional constructs and expect to see some kind of definition…

```auto
integer :: i
real :: h
call random_number(h)
if (h > 0.5) then
    i = 1
else if (h > 0.3) then
    i = 0
! else
! 'i' not set in this potential path
endif
print *, i ! Maybe notice that 'i' wasn't set on every potential path
end

```
