Limit the scope of variables and procedures
Variables and procedures shall be declared in the minimum scope from which all references to the identifier are possible.
Using a broader scope than necessary increases maintenance cost and the likelihood of unintended name resolution or modification. Restricting scope reduces namespace pollution and limits access to identifiers from unrelated program units.
In modern Fortran, adhering to this rule includes:
- Avoid using global or module-level variables when local variables or argument passing are sufficient.
- Declaring variables within the smallest enclosing block or procedure in which they are used.
- Restricting the visibility of module procedures using the
privateattribute.
Noncompliant Code Example
In this noncompliant example, the function helper_calc is intended for internal use by the public_routine . However, in Fortran, module procedures have public visibility by default. As a result, helper_calc is accessible to any program unit that uses math_mod , unnecessarily exposing an internal implementation detail.
module math_mod
implicit none
contains
! Noncompliant: Default public visibility
function helper_calc(x) result(y)
real, intent(in) :: x
real :: y
y = x * 2.0
end function helper_calc
subroutine public_routine(val)
real, intent(inout) :: val
val = helper_calc(val)
end subroutine public_routine
end module math_mod
Compliant Solution
In this compliant solution, the private statement is applied at the module level to change the default visibility of all entities to private. The intended public interface is then explicitly declared using the public_routine using the public attribute. This confines helper_calc to the module scope and prevents unintended external use.
module math_mod
implicit none
private ! Sets default visibility to private
public :: public_routine
contains
! Compliant: Only visible within math_mod
function helper_calc(x) result(y)
real, intent(in) :: x
real :: y
y = x * 2.0
end function helper_calc
subroutine public_routine(val)
real, intent(inout) :: val
val = helper_calc(val)
end subroutine public_routine
end module math_mod
Noncompliant Code Example
In this noncompliant code example, the variable current_count is declared at the module level. The subroutine update_counter depends on this global variable, giving it unnecessarily wide scope. Any program unit that uses counter_mod can access or modify current_count, increasing the risk or unintended interactions.
module counter_mod
implicit none
integer :: current_count = 0 ! Noncompliant Scope is too wide
integer, parameter :: MAX_COUNT = 100
contains
subroutine update_counter()
if (current_count < MAX_COUNT) then
current_count = current_count + 1
end if
end subroutine update_counter
end module counter_mod
Compliant Solution
In this compliant solution, current_count is declared local to the subroutine with the SAVE attribute. This limits visibility to update_counter while maintaining its value between calls. The global namespace is protected, and other program units cannot modify current_count directly.
module counter_mod
implicit none
integer, parameter :: MAX_COUNT = 100
contains
subroutine update_counter()
! Compliant: Scope is limited to this subroutine
integer, save :: current_count = 0
if (current_count < MAX_COUNT) then
current_count = current_count + 1
end if
end subroutine update_counter
end module counter_mod
Risk Assessment
Failure to minimize scope limits the compiler's ability to optimize and increases the likelihood of name collisions and unintended side effects. It degrades the locality of reference and makes the code difficult to review and maintain.
| Recommendation | Severity | Likelihood | Detectable | Repairable | Priority | Level |
| SAD01-F | Low | Unlikely | Yes | Yes | P3 | L3 |
Attachments:
button_arrow_left.png (image/png)
button_arrow_up.png (image/png)
button_arrow_right.png (image/png)


