Skip to content

Surprising behavior with return values #158

@wch

Description

@wch

I'm writing a function that returns integers, and I want it to return 0 or integers(0) as a sentinel value in case of an error. However, when I tried doing that, I ran into some surprising behavior.

My first attempt was to return a bare int, which resulted in a segfault. I discovered later that int doesn't automatically get coerced to integer. The only reason this was allowed to compile is because 0 has a special meaning; when I tried using 1, it resulted in a compile-time error -- which would have been useful for 0 as well.

cpp11::cpp_function("
integers test() {
  return 0;
}")
test()
#>  *** caught segfault ***
#> address 0x0, cause 'memory not mapped'

I tried returning integers(0) and got a segfault, which again was surprising:

cpp11::cpp_function("
integers test() {
  return integers(0);
}")
test()
#>  *** caught segfault ***
#> address 0x0, cause 'memory not mapped'

Then I tried integers(), and got NULL, but I would have expected integer(0):

cpp11::cpp_function("
integers test() {
  return integers();
}")
test()
#> NULL

Then I tried writable::integers(0) but got a compilation error:

cpp11::cpp_function("
integers test() {
  return writable::integers(0);
}")
#> (Compile error)

Then I tried writable::integers() but got an error when running the function:

cpp11::cpp_function("
integers test() {
  return writable::integers();
}")
test()
#> Error: Invalid input type, expected 'integer' actual 'NULL'

So my immediate question is, is there a one-liner to return either a 0 or zero-length integer vector from this function? (And note that the function signature is integer instead of int because in most cases I return a vector.)

The bigger questions are:

  • Can there be better compile-type checks to prevent the segfault code from compiling?
  • Why does returning integers(0) result in a segfault?
  • Why does returning integers() result in NULL, and returning writable::integers() result an error where it expects integer but gets NULL?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions