v icon indicating copy to clipboard operation
v copied to clipboard

empty `[noreturn]` function

Open premek opened this issue 2 years ago • 7 comments

Describe the bug

empty [noreturn] function never returns

Expected Behavior

should the compiler say that empty [noreturn] function is not allowed?

Current Behavior

program compiles and runs, never finishes

Reproduction Steps

import os

[noreturn]
fn usage() {
}

fn main() {
    println(os.args[1] or { usage() })
}

Possible Solution

No response

Additional Information/Context

No response

V version

V 0.3.3 adcd16b

Environment details (OS name and version, etc.)

debian linux

CC version: cc (Debian 10.2.1-6) 10.2.1 20210110 thirdparty/tcc status: thirdparty-linux-amd64 12f392c3

premek avatar Apr 21 '23 18:04 premek

This seems not a bug. The [noreturn] attr makes the code generator append while (1); to the end of function, even it being an empty function.

felipensp avatar Apr 21 '23 23:04 felipensp

As per documentation

// This function will NOT return to its callers. // Such functions can be used at the end of or blocks, // just like exit/1 or panic/1. Such functions can not // have return types, and should end either in for{}, or // by calling other [noreturn] functions. [noreturn] fn forever() { for {} }

this behaviour is not mentioned. guess we need to include the above point

preveen-stack avatar Apr 22 '23 11:04 preveen-stack

Also, v does not detect unreachable code after the [noreturn] function

import os

[noreturn]
fn usage() {
}

fn main() {
    println(os.args[1] or { usage() })
    println("unreachable code")
}

preveen-stack avatar Apr 22 '23 11:04 preveen-stack

Also, v does not detect unreachable code after the [noreturn] function

import os

[noreturn]
fn usage() {
}

fn main() {
    println(os.args[1] or { usage() })
    println("unreachable code")
}

It is reachable if args[1] exists

calm-courrier avatar Apr 22 '23 20:04 calm-courrier

It seems ok to me. What do you think @medvednikov ?

felipensp avatar Apr 29 '23 12:04 felipensp

Seems correct to me as it is. Marking a function as [noreturn] tells the compiler it will not return. So the compiler sticks the for {} in at the end to ensure that it won't return. The user is free to put an exit() or a panic() in the function if they don't want it to just hang.

It might be best to clarify that in the docs, but I don't think any other changes need to be made.

JalonSolov avatar Apr 29 '23 15:04 JalonSolov

Just to add why I (as a beginner in V) thought this was strange, I understood the [noreturn] as just a marker informing that the function does not return, it wasn't clear that it changes the function making sure it does not return. What I was expecting was that the compiler would make sure the function is guaranteed not to return and fail the compilation otherwise. Of course documenting and keeping the current behavior is also fine.

premek avatar Apr 29 '23 15:04 premek