Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6335283
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T18:49:30+00:00 2026-05-24T18:49:30+00:00

Possible Duplicate: Why doesn't .net/C# eliminate tail recursion? Take the following C# code: using

  • 0

Possible Duplicate:
Why doesn't .net/C# eliminate tail recursion?

Take the following C# code:

using System;

namespace TailTest
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            Counter(0);
        }

        static void Counter(int i)
        {
            Console.WriteLine(i);
            if (i < int.MaxValue) Counter(++i);
        }
    }
}

The C# compiler (mine anyway) will compile the Counter method into the following CIL:

.method private static hidebysig default void Counter (int32 i) cil managed 
{
.maxstack 8
IL_0000:  ldarg.0 
IL_0001:  call void class [mscorlib]System.Console::WriteLine(int32)
IL_0006:  ldarg.0 
IL_0007:  ldc.i4 2147483647
IL_000c:  bge IL_0019
IL_0011:  ldarg.0 
IL_0012:  ldc.i4.1 
IL_0013:  add 
IL_0014:  call void class TailTest.MainClass::Counter(int32)
IL_0019:  ret 
}

The problem with the above code is that it will cause a stack overflow (at about i=262000 on my hardware). To get around this problem, some languages do what is called tail-call elimination or tail-call optimization (TCO). Essentially, they turn the recursive call into a loop.

My understanding is the the 64-bit implementation of the .NET 4 JIT now performs TCO and avoids the overflow on code like the above CIL. However, the 32-bit JIT does not. Mono does not seem to either. It is interesting that the JIT (which is under time and resource pressure) does TCO while the C# compiler does not. My question is why isn’t the C# compiler itself more TCO aware?

There is a CIL instruction that tells the JIT to perform TCO. For example, the C# compiler could instead generate the following CIL:

.method private static hidebysig default void Counter (int32 i) cil managed 
{
.maxstack 8
IL_0000:  ldarg.0 
IL_0001:  call void class [mscorlib]System.Console::WriteLine(int32)
IL_0006:  ldarg.0 
IL_0007:  ldc.i4 2147483647
IL_000c:  bge IL_001c
IL_0011:  ldarg.0 
IL_0012:  ldc.i4.1 
IL_0013:  add 
IL_0014:  tail.
IL_0017:  call void class TailTest.MainClass::Counter(int32)
IL_001c:  ret 
}

Unlike the original, this code will not overflow and will run to completion even on the 32-bit JIT (both .NET and Mono). The magic is in the tail. CIL instruction. Compilers like F# will generate CIL that includes this instruction automatically.

So my question is, is there a technical reason that the C# compiler does not do this?

I get that it has historically maybe just not been worth it. Code like Counter() has not been common in idiomatic C# and/or the .NET framework. You could easily view TCO for C# as an unnecessary or premature optimization.

With the introduction of LINQ and other things, it seems like both C# and C# developers are moving in more functional directions. So, it would be nice if using recursion was not such an unsafe thing to do. But my question is really a more technical one.

Am missing something that makes TCO like this a bad idea (or a risky one) for C#. Or is there something that makes it particularly tricky to get right? That is really what I am hoping to understand. Any insight?

EDIT: Thanks for the great information. I just wanted to be clear that I am not criticizing the lack of or even demanding this feature. I am not super interested in the rational around prioritization. My curiosity is what obstacles might I not perceive or understand that make this a difficult, dangerous, or undesirable thing to do.

Perhaps a different context will help focus the conversation…

Let’s say I was going to implement my own C#-like language on the CLR. Why would I not (other than opportunity cost) include automatic and transparent emission of the ‘tail.’ instruction where appropriate? What challenges would I encounter or what constraints would I introduce in supporting this feature in a language very much like C#.

Thank you again (and in advance) for the responses.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T18:49:32+00:00Added an answer on May 24, 2026 at 6:49 pm

    check the following links

    Why doesn't .NET/C# optimize for tail-call recursion?
    /491463#491463
    http://social.msdn.microsoft.com/Forums/en-US/netfxtoolsdev/thread/67b6d908-8811-430f-bc84-0081f4393336?StatusCode=1
    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=166013&wa=wsignin1.0

    The following statement is MS official (Luke Hoban Visual C# Compiler Program Manager) and copied from last link

    Thanks for the suggestion. We’ve considered emiting tail call instructions at a number
    of points in the development of the C# compiler. However, there are some subtle issues
    which have pushed us to avoid this so far: 1) There is actually a non-trivial overhead
    cost to using the .tail instruction in the CLR (it is not just a jump instruction as
    tail calls ultimately become in many less strict environments such as functional
    language runtime environments where tail calls are heavily optimized). 2) There are
    few real C# methods where it would be legal to emit tail calls (other languages
    encourage coding patterns which have more tail recursion, and many that rely heavily
    on tail call optimization actually do global re-writing (such as Continuation Passing
    transformations) to increase the amount of tail recursion). 3) Partly because of 2),
    cases where C# methods stack overflow due to deep recursion that should have succeeded
    are fairly rare.

    All that said, we continue to look at this, and we may in a future release of the
    compiler find some patterns where it makes sense to emit .tail instructions.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Possible Duplicate: Why doesn’t VS 2008 display extension methods in Intellisense for String class
Possible Duplicate: Entity Framework with NOLOCK I'm using EF4 and .Net 4 to load
Possible Duplicate: problem with template inheritance This code doesn't compile in GCC: template <typename
Possible Duplicate: Why does ASP.NET auto-generated .designer code have the incorrect type? On my
Possible Duplicate: .Net Changes the element IDs I have the following problem (I'll explain
Possible Duplicate: Protect .NET code from reverse engineering? I want to make my software
Possible Duplicate: Hash Function .NET hi, I should write an app that take string
Possible Duplicate: .prop() vs .attr() Please take a look at this fiddle: http://jsfiddle.net/DGzvP/ $(#test).prop({
Possible Duplicate: 'Delegate 'System.Action' does not take 0 arguments.' Is this a C# compiler
Possible Duplicate: .Net Console Application that Doesn’t Bring up a Console I have a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.