View Issue Details

IDProjectCategoryView StatusLast Update
0004268OpenFOAMBugpublic2025-09-04 10:33
Reporterjacob Assigned Towill  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
PlatformMinGW-w64OSWindowsOS Version11
Product Version13 
Fixed in Version13 
Summary0004268: Thermo relies on specific ordering of global constructors in separate translation units
DescriptionThe static attributes `derivedThermoName` in thermo classes are initialized in different translation units (e.g. "psiThermo.C") than in which they are used to populate run-time selection tables (e.g. "psiThermos.C") by means of other constructors.

While it seems to work well for common workflow using GNU ld on Linux, in general this is an undefined behaviour in C++ ( https://isocpp.org/wiki/faq/ctors#static-init-order ).

I actually ran into this problem with the MinGW-w64 compiler in Cygwin64 on Windows 11. There, apparently, `derivedThermoName` was not initialized prior to its use in the `defineThermo` macro, resulting in empty string being used to compute the amalgamated thermo name entering the constructor table. As a consequence, thermo models based on distinct basic models (`psiThermo`, `rhoFluidThermo`, etc.) produced identical run-time selection table entries, causing the solver to fail, complaining about the duplicates.

I was able to work around this issue by changing the static attribute `derivedThermoName` to an inline static function of the same name that returned the required string. The macro `defineThermo` then simply called that function.
TagsNo tags attached.

Activities

henry

2025-08-24 18:05

manager   ~0013654

https://openfoam.org/maintenance/
https://openfoam.org/news/funding-2025/

will

2025-09-03 17:03

manager   ~0013658

Turning it into a static function is probably what we'd do to fix this also. Can you give us a patch containing your changes?

jacob

2025-09-03 17:30

reporter   ~0013659

Sure, please find the attached patch.
thermo-static-fun.patch (5,836 bytes)   
diff --git a/src/thermophysicalModels/basic/psiThermo/psiThermo.C b/src/thermophysicalModels/basic/psiThermo/psiThermo.C
index baeb88f91c..d00646e5fb 100644
--- a/src/thermophysicalModels/basic/psiThermo/psiThermo.C
+++ b/src/thermophysicalModels/basic/psiThermo/psiThermo.C
@@ -33,8 +33,6 @@ namespace Foam
     defineRunTimeSelectionTable(psiThermo, fvMesh);
 }
 
-const Foam::word Foam::psiThermo::derivedThermoName("hePsiThermo");
-
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
diff --git a/src/thermophysicalModels/basic/psiThermo/psiThermo.H b/src/thermophysicalModels/basic/psiThermo/psiThermo.H
index 7d3e7b67ac..c902eeeb41 100644
--- a/src/thermophysicalModels/basic/psiThermo/psiThermo.H
+++ b/src/thermophysicalModels/basic/psiThermo/psiThermo.H
@@ -74,7 +74,7 @@ public:
             PsiThermo<BasicThermo<MixtureType, composite>>;
 
         //- The derived name
-        static const word derivedThermoName;
+        static word derivedThermoName() { return "hePsiThermo"; }
 
 
     //- Runtime type information
diff --git a/src/thermophysicalModels/basic/rhoFluidThermo/rhoFluidThermo.C b/src/thermophysicalModels/basic/rhoFluidThermo/rhoFluidThermo.C
index baa278f4c3..8deb21c948 100644
--- a/src/thermophysicalModels/basic/rhoFluidThermo/rhoFluidThermo.C
+++ b/src/thermophysicalModels/basic/rhoFluidThermo/rhoFluidThermo.C
@@ -33,8 +33,6 @@ namespace Foam
     defineRunTimeSelectionTable(rhoFluidThermo, fvMesh);
 }
 
-const Foam::word Foam::rhoFluidThermo::derivedThermoName("heRhoThermo");
-
 
 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
 
diff --git a/src/thermophysicalModels/basic/rhoFluidThermo/rhoFluidThermo.H b/src/thermophysicalModels/basic/rhoFluidThermo/rhoFluidThermo.H
index b0da199e72..7f33fbf238 100644
--- a/src/thermophysicalModels/basic/rhoFluidThermo/rhoFluidThermo.H
+++ b/src/thermophysicalModels/basic/rhoFluidThermo/rhoFluidThermo.H
@@ -73,7 +73,7 @@ public:
             RhoFluidThermo<BasicThermo<MixtureType, composite>>;
 
         //- The derived name
-        static const word derivedThermoName;
+        static word derivedThermoName() { return "heRhoThermo"; }
 
 
     //- Runtime type information
diff --git a/src/thermophysicalModels/multicomponentThermo/psiuMulticomponentThermo/psiuMulticomponentThermo.C b/src/thermophysicalModels/multicomponentThermo/psiuMulticomponentThermo/psiuMulticomponentThermo.C
index 69d8858c20..8a8ff0f005 100644
--- a/src/thermophysicalModels/multicomponentThermo/psiuMulticomponentThermo/psiuMulticomponentThermo.C
+++ b/src/thermophysicalModels/multicomponentThermo/psiuMulticomponentThermo/psiuMulticomponentThermo.C
@@ -37,11 +37,6 @@ namespace Foam
     defineRunTimeSelectionTable(psiuMulticomponentThermo, fvMesh);
 }
 
-const Foam::word Foam::psiuMulticomponentThermo::derivedThermoName
-(
-    "heheuPsiThermo"
-);
-
 
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
diff --git a/src/thermophysicalModels/multicomponentThermo/psiuMulticomponentThermo/psiuMulticomponentThermo.H b/src/thermophysicalModels/multicomponentThermo/psiuMulticomponentThermo/psiuMulticomponentThermo.H
index 89ae0981e0..1ddd1e9b17 100644
--- a/src/thermophysicalModels/multicomponentThermo/psiuMulticomponentThermo/psiuMulticomponentThermo.H
+++ b/src/thermophysicalModels/multicomponentThermo/psiuMulticomponentThermo/psiuMulticomponentThermo.H
@@ -89,7 +89,7 @@ public:
             PsiuMulticomponentThermo<BasicThermo<MixtureType, composite>>;
 
         //- The derived name
-        static const word derivedThermoName;
+        static word derivedThermoName() { return "heheuPsiThermo"; }
 
 
     //- Runtime type information
diff --git a/src/thermophysicalModels/solidThermo/solidThermo/solidThermo.C b/src/thermophysicalModels/solidThermo/solidThermo/solidThermo.C
index c4d5e022c6..30e176f85a 100644
--- a/src/thermophysicalModels/solidThermo/solidThermo/solidThermo.C
+++ b/src/thermophysicalModels/solidThermo/solidThermo/solidThermo.C
@@ -34,8 +34,6 @@ namespace Foam
     defineRunTimeSelectionTable(solidThermo, fvMesh);
 }
 
-const Foam::word Foam::solidThermo::derivedThermoName("heSolidThermo");
-
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
diff --git a/src/thermophysicalModels/solidThermo/solidThermo/solidThermo.H b/src/thermophysicalModels/solidThermo/solidThermo/solidThermo.H
index 3c73c1feee..d9ef7dc7b1 100644
--- a/src/thermophysicalModels/solidThermo/solidThermo/solidThermo.H
+++ b/src/thermophysicalModels/solidThermo/solidThermo/solidThermo.H
@@ -77,7 +77,7 @@ public:
             SolidThermo<BasicThermo<MixtureType, composite>>;
 
         //- The derived name
-        static const word derivedThermoName;
+        static word derivedThermoName() { return "heSolidThermo"; }
 
 
     //- Runtime type information
diff --git a/src/thermophysicalModels/specie/include/makeThermo.H b/src/thermophysicalModels/specie/include/makeThermo.H
index d009a36399..72b90bd261 100644
--- a/src/thermophysicalModels/specie/include/makeThermo.H
+++ b/src/thermophysicalModels/specie/include/makeThermo.H
@@ -48,7 +48,7 @@ Description
     (                                                                          \
         BaseThermo##Mixture##ThermoPhysics,                                    \
         (                                                                      \
-            BaseThermo::derivedThermoName + "<"                                \
+            BaseThermo::derivedThermoName() + "<"                              \
           + Mixture<ThermoPhysics>::typeName() + ">"                           \
         ).c_str(),                                                             \
         0                                                                      \
thermo-static-fun.patch (5,836 bytes)   

will

2025-09-04 10:33

manager   ~0013660

Thanks. Fixed in dev and v13:

https://github.com/OpenFOAM/OpenFOAM-dev/commit/56f426143801d113710890142c4bf4f551b0c0a5
https://github.com/OpenFOAM/OpenFOAM-13/commit/5e5fb78dee871367c713c9074b6126bd3a9a52cd

Issue History

Date Modified Username Field Change
2025-08-24 17:44 jacob New Issue
2025-08-24 18:05 henry Note Added: 0013654
2025-09-03 17:03 will Note Added: 0013658
2025-09-03 17:30 jacob Note Added: 0013659
2025-09-03 17:30 jacob File Added: thermo-static-fun.patch
2025-09-04 10:33 will Assigned To => will
2025-09-04 10:33 will Status new => resolved
2025-09-04 10:33 will Resolution open => fixed
2025-09-04 10:33 will Fixed in Version => 13
2025-09-04 10:33 will Note Added: 0013660