The code snippet is valid Fortran and should compile correctly.
Which compiler are you using to compile this successfully?
I don’t claim to know the standard well enough to know if this should work, but I thought only quoted strings are allowed for the bind C name? Or maybe it’s a newer Fortran 2018 feature?
Compiling your snip-it with gfortran gives the same error as nvfortran, but if I use “_chdir” for the name, it works for both compilers.
% gfortran --version
GNU Fortran (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% gfortran -c test.F90
test.F90:11:51:
11 | function chdir(path) result(stat) bind(C, name=chdir_symbol)
| 1
Error: Parameter ‘chdir_symbol’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
test.F90:12:13:
12 | import :: c_char, c_int, chdir_symbol
| 1
Error: IMPORT statement at (1) only permitted in an INTERFACE body
test.F90:13:21:
13 | character(kind=c_char, len=1), intent(in) :: path(*)
| 1
Error: Parameter ‘c_char’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
test.F90:14:14:
14 | integer(c_int) :: stat
| 1
Error: Parameter ‘c_int’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
test.F90:15:7:
15 | end function chdir
| 1
Error: Expecting END INTERFACE statement at (1)
% diff -u test2.F90 test.F90
--- test2.F90 2021-06-01 10:34:36.283953729 -0700
+++ test.F90 2021-06-01 10:15:27.025290767 -0700
@@ -8,7 +8,7 @@
#endif
interface
- function chdir(path) result(stat) bind(C, name="_chdir")
+ function chdir(path) result(stat) bind(C, name=chdir_symbol)
import :: c_char, c_int, chdir_symbol
character(kind=c_char, len=1), intent(in) :: path(*)
integer(c_int) :: stat
% gfortran -c test2.F90
% nvfortran -c test2.F90
%
Turns out that there is a bug in gfortran as well. This usage is working with Intel’s and NAG’s Fortran compilers. There is a related discussion on the Fortran discourse about the failure with gfortran and the standard conformance of this code
I decided to post the difficult example with a constant expression imported into an interface body here, but there is also a simpler example with a constant expression inside a module body:
module m_api
use, intrinsic :: iso_c_binding
implicit none
character(len=*), parameter :: namespace = "m_"
contains
function info_api() result(stat) bind(C, name=namespace//"info")
integer(c_int) :: stat
stat = 0_c_int
end function info_api
end module m_api
which will fail with nvfortran but compile with gfortran:
❯ nvfortran api.f90 -c
NVFORTRAN-S-0034-Syntax error at or near identifier namespace (api.f90: 6)
NVFORTRAN-S-0038-Symbol, info_api, has not been explicitly declared (api.f90)
0 inform, 0 warnings, 2 severes, 0 fatal for info_api
Sounds good. I filed TPR #30170 with the issue and sent it to our engineers for investigation.
Note out of curiosity and to answer my own question, I looked at the F2003, 2008, and 2018 standards. This section hasn’t changed so this isn’t an issue with a change in the standard.
❯ nvfortran --version
nvfortran 21.11-0 64-bit target on x86-64 Linux -tp haswell
NVIDIA Compilers and Tools
Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
❯ nvfortran mwe.f90
NVFORTRAN-S-0034-Syntax error at or near identifier namespace (mwe.f90: 8)
NVFORTRAN-S-0038-Symbol, info_api, has not been explicitly declared (mwe.f90)
0 inform, 0 warnings, 2 severes, 0 fatal for info_api