Nvfortran C_BOOL BIND(C) .not. improper value

Assume a C or C++ program wishes to send/receive logical(C_BOOL) from a fortran procedure. This is broken with NVHPC at least 24.3. The issue is when .not. doesn’t properly invert the value since NVHPC designates logical as odd and even per the reference manual instead of 1 and 0 like other compilers.

nvfortran reference guide:
The logical constants .TRUE. and .FALSE. are defined to be the four-byte values -1 and 0 respectively.
A logical expression is defined to be .TRUE. if its least significant bit is 1 and .FALSE. otherwise.

MWE

nvfortran -c c_bool.f90
nvc c_bool.o c_bool.c
./a.out. 
# results in failure

c_bool.c:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool logical_not(bool);

int main(void) {

  int c = 0;
  bool b = true;

  b = logical_not(b);
  if(b){
    fprintf(stderr, "not(true) != false\n");
    c++;
  }

  b = logical_not(b);
  if(!b){
    fprintf(stderr, "not(false) != true\n");
    c++;
  }

  if(c){
    fprintf(stderr, "ERROR: C_BOOL\n");
    return EXIT_FAILURE;
  }

  printf("OK: C_BOOL\n");

  return EXIT_SUCCESS;
}

c_bool.f90

module dummy

use, intrinsic :: iso_c_binding, only: C_BOOL

implicit none

contains

logical(C_BOOL) function logical_not(L) bind(C)
logical(C_BOOL), intent(in), value :: L
logical_not = .not.L
end function logical_not

end module dummy

I believe what you’re seeing is a difference in the Fortran standard. We’re using the F2008 and earlier definition, while F2018 changed to using the 0/1 definition.

Along with the LLVM community’s “F18” project, we’re in the process of a complete reimplementation of the Fortran front-end to be fully F2018 compliant. While I don’t have a timeline, once stable, we’ll likely be replacing nvfortran with this new flang-based front-end.

Though in the meantime, we’ve only put a few F18 features into nvfortran, this not being one of them. Though I did add a report, TPR #35624, requesting engineering see if this is something we can add to nvfortran. If it’s easy, then they likely add it, otherwise, we’ll need to wait a bit until we make the switch to the flang-based front-end.

Thanks, I see this in these discussions too.

Ah, thanks for the reminder. I forgot about the -Munixlogial flag. This changes logicals to treat any nozero logical value as true so can be used as a work around for you.

% nvfortran -Munixlogical c_bool.f90 -c
% nvc c_bool.o c_bool.c; a.out
c_bool.c:
OK: C_BOOL

Yes that’s a solution -Munixlogical. oneAPI needs -fpscomp logical too. I document the hex values at GitHub - scivision/fortran-cpp-interface: Examples of Fortran 2003 C / C++ interfacing with Fortran.
examples in that project under “test/bool” and “src/bool”

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.