Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there something like [[noreturn]] in C# to indicate the compiler that the method will never return a value?

Tags:

c#

noreturn

For some of my code I use a method which looks like this:

public static void Throw<TException>(string message) where TException : Exception
{
    throw (TException) Activator.CreateInstance(typeof(TException), message);
}

and I want to use it like this (simple example):

public int MyMethod()
{
    if(...)
    {
        return 42;
    }

    ThrowHelper.Throw<Exception>("Test");
    // I would have to put "return -1;" or anything like that here for the code to compile.
}

now, obviously, I know that there is no way MyMethod could never return anything, because it will always (indirectly) throw an exception. But of course I get the compiler value "not all paths return a value".

That's why I am asking if there is anything like the C++ [[noreturn]] attribute that I could use to indicate to the compiler that the code is actually valid?


EDIT: The reason for why I want to use a throwing helper class instead of throwing directly or using an exception builder, is this statement:

Members that throw exceptions are not getting inlined. Moving the throw statement inside the builder might allow the member to be inlined.

I actually measured the code and I would benefit (a little) from inlining, so I would be happy to find ways to achieve this.

like image 826
Thomas Flinkow Avatar asked Jan 12 '18 18:01

Thomas Flinkow


People also ask

What does [[ Noreturn ]] do?

__attribute__((noreturn)) function attribute This function attribute informs the compiler that the function does not return. The compiler can then perform optimizations by removing the code that is never reached.

When might you want to use the [[ Noreturn ]] attribute?

5 Answers. Save this answer. Show activity on this post. The noreturn attribute is supposed to be used for functions that don't return to the caller.

What is noreturn in C?

The _Noreturn keyword was introduced in C11. It tells the compiler that the function it's applied to doesn't return to the caller. The compiler knows that the code following a call to a _Noreturn function is unreachable. An example of a function that doesn't return is abort.


2 Answers

The normal way of doing this is to throw an exception with no branching. Something like this:

public int MyMethod()
{
    //Other code here.

    throw new InvalidOperationException();
}

I actually thought of a way to do what you want:

public class Thrower
{
    public static TRet Throw<TException, TRet>(string message) where TException : Exception
    {
        throw (TException)Activator.CreateInstance(typeof(TException), message);
    }

    public int MyMethod()
    {
        if (new Random().Next() == 2)
        {
            return 42;
        }

        return Throw<Exception, int>("Test");
        // I would have to put "return -1;" or anything like that here for the code to compile.
    }
}
like image 119
Adam Brown Avatar answered Oct 11 '22 15:10

Adam Brown


No, there is no way to get the compiler to understand that the method will always throw an exception and thus marks the end of code execution.

You are forced to

  1. Call the method as the very last statement of your method (if your method is void)
  2. Or add the necessary flow control statements after the method call to end the execution, even though the code will never actually be executed.

As you've pointed out, in a method with a return type, you will be forced to write the appropriate return X; statement where X is an appropriate value for the return type of your method.

There is no way around this.

like image 32
Lasse V. Karlsen Avatar answered Oct 11 '22 15:10

Lasse V. Karlsen