From 3b071b4efa5b580e92b7d23e55555f5f8451bcfc Mon Sep 17 00:00:00 2001 From: Stephan Hageboeck Date: Fri, 27 Feb 2026 10:37:42 +0100 Subject: [PATCH] Fix argument passing conventions in h2root. When variable-length strings are passed into functions compiled by gfortran, the lengths of the strings have to be passed at the end of the argument list as size_t. When using gcc <= 7 or clang (where the __GNUC__ macro might return unpredictable values), we were putting int on the C side, which got interpreted as size_t on the fortran side. (cherry picked from commit 3a9316ed1ddb4f0655d8d979181819e94c877048) --- main/src/h2root.cxx | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/main/src/h2root.cxx b/main/src/h2root.cxx index 1e72e0cee44bd..bd1f67996852a 100644 --- a/main/src/h2root.cxx +++ b/main/src/h2root.cxx @@ -134,11 +134,7 @@ void MAIN__() {} // As recommended in // https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html -#if __GNUC__ > 7 -typedef size_t fortran_charlen_t; -#else -typedef int fortran_charlen_t; -#endif +using fortran_charlen_t = size_t; #else # define hlimit HLIMIT @@ -329,11 +325,11 @@ int main(int argc, char **argv) int lun = 10; #ifndef WIN32 - // "px" is a string being changed to "pxc" in the fortran side; since it's a temporary on C's side, - // we need a buffer of at least 3 chars on Cs side, too. Predefine it as a extra variable "px " since that way - // the space will be replaced by 'c' on the preallocated memory, instead of appending a new char (new memory) to "px". - auto opt = PASSCHAR("px "); - hropen(lun,PASSCHAR("example"),PASSCHAR(file_in),opt,record_size,ier,7,strlen(file_in),2); + // Reminder: Argument passing convention is that string lengths go as hidden arguments + // at the end of the argument list. + constexpr auto chdir = "example"; + constexpr auto opt = "px"; + hropen(lun, chdir, file_in, opt, record_size, ier, strlen(chdir), strlen(file_in), strlen(opt)); #else hropen(lun,PASSCHAR("example"),PASSCHAR(file_in),PASSCHAR("px"),record_size,ier); #endif