Skip to content

Fix compilation error and logic bug in mosaic_util.c#389

Closed
ceblanton wants to merge 1 commit intomainfrom
380.fix-mosaic-util-compilation
Closed

Fix compilation error and logic bug in mosaic_util.c#389
ceblanton wants to merge 1 commit intomainfrom
380.fix-mosaic-util-compilation

Conversation

@ceblanton
Copy link
Copy Markdown
Contributor

@ceblanton ceblanton commented Mar 10, 2026

This change resolves a build failure in mosaic_util.c where a static const double array (m[3][3])was being initialized with variables calculated at runtime. Standard C requires static variables to be initialized with compile-time constants, which caused GCC to throw an "initializer element is not constant" error.

Removing the static keyword not only fixes the compilation issue but also corrects a likely logic bug. As an automatic local variable, the rotation matrix will now accurately populate with fresh, updated values on every function call, ensuring mathematical correctness and thread safety.

Description
Using intel-classic compilers, mosaic_util.c fails to compile. (GCC does not have this problem)

cc -DHAVE_CONFIG_H -I. -I../../lib -I..    -DpgiFortran -I/opt/cray/pe/netcdf/4.9.0.11/intel/2023.2/include -O2 -MT libfrencutils/mosaic_util.o -MD -MP -MF $depbase.Tpo -c -o libfrencutils/mosaic_util.o ../../lib/libfrencutils/mosaic_util.c &&\
mv -f $depbase.Tpo $depbase.Po
icc: remark #10441: The Intel(R) C++ Compiler Classic (ICC) is deprecated and will be removed from product release in the second half of 2023. The Intel(R) oneAPI DPC++/C++ Compiler (ICX) is the recommended compiler moving forward. Please transition to use this compiler. Use '-diag-disable=10441' to disable this message.
../../lib/libfrencutils/mosaic_util.c(1695): error: expression must have a constant value
    static const double m01 = - is2;
                                ^

../../lib/libfrencutils/mosaic_util.c(1696): error: expression must have a constant value
    static const double m02 = is2;
                              ^

../../lib/libfrencutils/mosaic_util.c(1700): error: expression must have a constant value
    static const double m[3][3] = { {m00, m01, m02}, {m02, m11, m12},{m01, m12, m11} };
                                     ^

../../lib/libfrencutils/mosaic_util.c(1700): error: expression must have a constant value
    static const double m[3][3] = { {m00, m01, m02}, {m02, m11, m12},{m01, m12, m11} };
                                          ^

../../lib/libfrencutils/mosaic_util.c(1700): error: expression must have a constant value
    static const double m[3][3] = { {m00, m01, m02}, {m02, m11, m12},{m01, m12, m11} };

Fixes #380

How Has This Been Tested?
Test suite passes on gaea and GFDL workstations.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules
  • New check tests, if applicable, are included
  • make distcheck passes

This change resolves a build failure in mosaic_util.c where
a static const double array (m[3][3])was being initialized
with variables calculated at runtime. Standard C requires static
variables to be initialized with compile-time constants,
which caused GCC to throw an "initializer element is not constant" error.

Removing the static keyword not only fixes the compilation issue but also corrects a likely logic bug. As an automatic local variable, the rotation matrix will now accurately populate with fresh, updated values on every function call, ensuring mathematical correctness and thread safety.
@ceblanton ceblanton requested a review from underwoo March 10, 2026 16:15
@underwoo
Copy link
Copy Markdown
Member

underwoo commented Apr 9, 2026

@claude review

Copy link
Copy Markdown
Member

@underwoo underwoo left a comment

Choose a reason for hiding this comment

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

Code Review for #380 / PR #389

The fix correctly resolves the compilation error where static const local variables were being initialized with other static const variables (is2), which is not a valid constant expression in C. The test suite passing on gaea and GFDL workstations is good confirmation.

A few items worth addressing before merging:

1. Commit message: Inaccurate "logic bug" claim

The description states this "corrects a likely logic bug." This is inaccurate. All six removed-static values (m00, m01, m02, m11, m12, and m[3][3]) are derived entirely from compile-time constants (M_SQRT2, 0, 0.5). Whether declared static or as automatic variables, they produce identical values on every invocation. There is no logic bug — the only issue was a compilation error.

2. Inaccurate thread safety claim

The description also says removing static ensures "thread safety." This is misleading. The function writes to the global array the_rotation_matrix[3][3] (line 44), which remains a shared mutable global. Making the local temporaries non-static has no bearing on the thread safety of that global write.

3. Inconsistent treatment of is2

static const double is2 = 1.0/M_SQRT2; is kept as static, while all variables derived from it (m01, m02, m[3][3]) are changed to automatic. This inconsistency could be confusing to future readers.

4. A cleaner alternative fix

Since the values are mathematical constants, they could be expressed directly using standard macros, keeping the static optimization intact and avoiding stack allocation on each call:

void set_the_rotation_matrix() {
  // M_SQRT1_2 == 1/sqrt(2)
  static const double m[3][3] = {
      { 0.0,       -M_SQRT1_2,  M_SQRT1_2 },
      { M_SQRT1_2,  0.5,        0.5       },
      {-M_SQRT1_2,  0.5,        0.5       }
  };
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      the_rotation_matrix[i][j] = m[i][j];
}

M_SQRT1_2 (= 1/√2) is a compile-time constant available in <math.h> (already included), which satisfies the C standard's requirement for static initializers. This eliminates the original compilation error and makes the intent clearer with no functional change.

5. Minor: commit message title typo
The commit subject says mosaic_util.nc — should be mosaic_util.c.

Summary: The fix works and resolves the build failure. Items 1–3 are documentation/description accuracy concerns. Item 4 is a suggested improvement that would be cleaner. Item 5 is a trivial typo. None of these block correctness, but items 1–3 could mislead future maintainers.


Generated by Claude Code

@underwoo underwoo changed the title Fix compilation error and logic bug in mosaic_util.nc Fix compilation error and logic bug in mosaic_util.c Apr 9, 2026
@underwoo
Copy link
Copy Markdown
Member

underwoo commented Apr 9, 2026

@ceblanton, please look at the review above. While I will approve the PR, I want to make sure that you do a few things when committing the merged code.

  1. Update the commit message to remove the inaccurate claims. For example, this is not a logical bug, and this does not affect the thread safety of the code. Make sure to not include these in the merge commit message. (Squashing the merge will allow you to address that in the commit message.)
  2. Consider using M_SQRT1_2 as described in the comment item 4. I think doing this will be a cleaner solution.

@ceblanton
Copy link
Copy Markdown
Contributor Author

To avoid the incorrect commit message and undesired fix, I created a new branch and PR in #393

@ceblanton ceblanton closed this Apr 9, 2026
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.

static const double variables in lib/libfrencutils/mosaic_util.c

2 participants