Skip to content

Commit f9a49d3

Browse files
committed
add nullptr c_associated example
1 parent e96cdc0 commit f9a49d3

File tree

7 files changed

+89
-0
lines changed

7 files changed

+89
-0
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ foreach(a IN ITEMS
4747
array bool error exception
4848
iterator
4949
glibc malloc
50+
nullptr
5051
opaque pointer poly_function poly_type real struct
5152
sleep string submodule
5253
time vector)

test/nullptr/CMakeLists.txt

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
set_property(DIRECTORY PROPERTY LABELS nullptr)
2+
3+
add_library(c_nullptr OBJECT lib.c)
4+
target_include_directories(c_nullptr PRIVATE .)
5+
add_library(cpp_nullptr OBJECT lib.cpp)
6+
target_include_directories(cpp_nullptr PRIVATE .)
7+
8+
add_executable(C_Fortran_nullptr main.f90 $<TARGET_OBJECTS:c_nullptr>)
9+
add_test(NAME C_Nullptr COMMAND C_Fortran_nullptr)
10+
11+
add_executable(Cpp_Fortran_nullptr main.f90 $<TARGET_OBJECTS:cpp_nullptr>)
12+
set_property(TARGET Cpp_Fortran_nullptr PROPERTY LINKER_LANGUAGE ${linker_lang})
13+
14+
add_test(NAME Cpp_Nullptr COMMAND Cpp_Fortran_nullptr)

test/nullptr/Readme.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# NULL / nullptr between C, C++, and Fortran
2+
3+
Unlike in C / C++, do not check equality with C_NULL_PTR in Fortran.
4+
Instead, by definition the
5+
[c_associated()](https://fortranwiki.org/fortran/show/c_associated)
6+
logical function returns ".false." if the C_PTR is C_NULL_PTR, and ".true." otherwise.
7+
See [strptime.f90](./strptime.f90)
8+
for an example of checking in Fortran for a C null pointer returned from a function.

test/nullptr/lib.c

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <nullptr.h>
2+
#include <stddef.h>
3+
4+
const char* nullchar(bool b) {
5+
return b ? NULL : "hello";
6+
}

test/nullptr/lib.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include <nullptr.h>
2+
3+
const char* nullchar(bool b) {
4+
return b ? nullptr : "hello";
5+
}

test/nullptr/main.f90

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
program main
2+
3+
use, intrinsic :: iso_c_binding
4+
5+
implicit none
6+
7+
interface
8+
function nullchar(b) bind(C)
9+
import
10+
logical(c_bool), value :: b
11+
type(C_PTR) :: nullchar
12+
end function
13+
end interface
14+
15+
integer, parameter :: n = 5
16+
character(n) :: s
17+
18+
logical(C_BOOL), parameter :: t = .true., f = .false.
19+
20+
type(c_ptr) :: ptr
21+
22+
if (.not. c_associated(nullchar(f))) error stop "nullptr should not be detected"
23+
24+
ptr = nullchar(t)
25+
if (c_associated(ptr)) error stop "nullptr not detected"
26+
27+
! for simplicity, assume we know strlen is 5.
28+
block
29+
character(kind=c_char), pointer :: c_string(:)
30+
integer :: i
31+
32+
s = "" !< ensure s has no garbage characters
33+
34+
ptr = nullchar(f)
35+
call c_f_pointer(ptr, c_string, [n])
36+
do i = 1, n
37+
s(i:i) = c_string(i)
38+
end do
39+
end block
40+
41+
print '(a)', s
42+
43+
end program

test/nullptr/nullptr.h

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
#ifdef __cplusplus
3+
extern "C" {
4+
#else
5+
#include <stdbool.h>
6+
#endif
7+
8+
const char* nullchar(bool b);
9+
10+
#ifdef __cplusplus
11+
}
12+
#endif

0 commit comments

Comments
 (0)