Skip to content

Replace min/max variable names - #26

Merged
manodeep merged 4 commits into
mom5from
24-replace-min-max-var-names
Aug 26, 2026
Merged

manodeep merged 4 commits into
mom5from
24-replace-min-max-var-names

Conversation

@manodeep

Copy link
Copy Markdown
Collaborator

For metadata type variables min/max -> valid_min/valid_max; for time related variables min -> minutes

Fixes #24

claude added 2 commits August 20, 2026 15:48
Fortran has no way to reach an intrinsic that a local name has shadowed, so
any scoping unit with a variable called min or max simply cannot call MIN()
or MAX(). mpp_io has five such routines, and the shadowing is invisible at
the point of failure: gfortran does not say "you shadowed an intrinsic", it
says "Unclassifiable statement" on the line that tried to use it.

Renamed, in mpp_io_mod and the fms_io/oda_tools code that calls it:

  mpp_write_meta_axis_r1d   min            -> valid_min
  mpp_write_meta_axis_i1d   min            -> valid_min
  mpp_write_meta_field      min, max       -> valid_min, valid_max
  mpp_modify_field_meta     min, max       -> valid_min, valid_max
  mpp_get_field_atts        min, max       -> valid_min, valid_max
  register_restart_axis_r1d min            -> valid_min
  validtype                 %min, %max     -> %valid_min, %valid_max
  fieldtype                 %min, %max     -> %valid_min, %valid_max
  fms_io ax_type            %min           -> %valid_min

valid_min and valid_max are not invented names: these variables exist to
carry the CF attributes that the same routines already write as the string
literals 'valid_min' and 'valid_max'. The declaration now matches the
attribute it produces.

The component renames are cosmetic -- a component does not shadow anything --
but validtype and fieldtype are PRIVATE-component types whose min/max are
only reachable inside mpp_io_mod, so the rename is contained, and leaving
field%min next to a valid_min dummy would be worse than either alone.

API impact, audited rather than assumed. Dummy-argument names are visible to
keyword callers. Every keyword caller of the affected routines in FMS is
updated here -- 11 call sites in fms/fms_io.F90,
fms/fms_io_unstructured_register_restart_axis.inc,
fms/fms_io_unstructured_save_restart.inc and oda_tools/write_ocean_data.F90.
MOM5 outside its vendored src/shared has *zero* keyword min=/max= callers of
mpp_write_meta, mpp_modify_field_meta, mpp_get_field_atts or
register_restart_axis, so re-vendoring src/shared is the whole of the MOM5
change. Positional callers are unaffected either way.

Deliberately NOT renamed: the integer min variables in time_manager.F90,
time_interp_external.F90 and oda_core_ecda.F90. Those hold minutes. They do
shadow the intrinsic in their own scopes, but valid_min would be a lie; the
right name there is 'minute' and it is a separate change.

No behaviour change: this is a pure rename, and the CF attribute strings
written to the files are untouched.

This commit is self-contained and applies to the mom5 branch on its own.
Applied on top of the parallel-netCDF series it also makes MAX() reachable in
mpp_write_meta_field, which is what the chunking loop there had to work
around by hand.
Companion to the valid_min/valid_max rename, covering the other family of
min shadowing in this tree. These variables hold minutes, so valid_min would
have been wrong for them; minutes is the name the surrounding code already
uses.

  time_manager/time_manager.F90       date_to_string
                                      program test (#ifdef test_time_manager)
  time_interp/time_interp_external.F90  time_interp_external_3d
                                        time_interp_external_0d
  oda_tools/oda_core_ecda.F90         get_obs

Every one is an unpacking of get_date(time, yr, mo, day, hr, min, sec) into
locals. While the local is called min, the MIN intrinsic is unreachable in
that scoping unit, and gfortran reports an attempt to use it only as
"Unclassifiable statement" on the line that tried.

Unlike the valid_min/valid_max rename there is no API surface here at all:
all four declarations are plain locals, not dummy arguments, so no caller
anywhere can name them and nothing outside these three files can see the
change. The values are passed to get_date and increment_date positionally.

time_manager already uses minutes as the dummy-argument name in
increment_date, increment_date_private and decrement_date, so this makes the
module self-consistent rather than introducing a new convention. No program
unit that declares min also declares minutes, so there is no collision --
checked per scoping unit, not per file.

The time_manager 'program test' block sits behind #ifdef test_time_manager
and is not built by default; it was syntax-checked separately with
-Dtest_time_manager, clean both before and after this change.

No behaviour change: a pure rename of local variables, with no format string,
attribute or output text touched. The ' min=' label in format 11 stays as it
is -- that is display text, not an identifier.

This commit is independent of the parallel-netCDF series and applies to the
mom5 branch on its own.
@manodeep

Copy link
Copy Markdown
Collaborator Author

@dougiesquire @anton-seaice Will either of you be able to review this?

Comment thread mpp/include/mpp_io_write.inc Outdated

@dougiesquire dougiesquire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @manodeep

Comment thread fms/fms_io.F90
Comment thread mpp/include/mpp_io_write.inc Outdated
Comment thread mpp/include/mpp_io_write.inc

@dougiesquire dougiesquire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @manodeep

@manodeep
manodeep merged commit 0b2a9e7 into mom5 Aug 26, 2026
4 checks passed
@manodeep

Copy link
Copy Markdown
Collaborator Author

Thanks @dougiesquire

@manodeep
manodeep deleted the 24-replace-min-max-var-names branch August 26, 2026 08:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use of variables called min and max is blocking the min() and max() functions

3 participants