1

I discovered a piece of code that should produce an error because the array goes out of bounds but instead it behaves strangely. When I step into it just stops after 4 loops and doesn't add the controls. How can this be, no errors or compiler warnings or anything?

    Panel[] panel = new Panel[4];
    Label[] label = new Label[4];
    private void Form1_Load(object sender, EventArgs e)
    {
        for (int x = 0; x < 20; x++)
        {
            label[x] = new Label { Name = x.ToString("00"), BackColor = Color.Blue, Text = "Test" };
            panel[x] = new Panel { Name = x.ToString("00"), BackColor = Color.Blue };
        }
        tableLayoutPanel1.Controls.AddRange(label);
        tableLayoutPanel2.Controls.AddRange(panel);
    }
CodeCamper
  • 6,609
  • 6
  • 44
  • 94
  • That would not result in a compiler error. Surely you are in fact getting an error at runtime? – Kirk Woll Jun 21 '13 at 01:11
  • 1
    The compiler does not perform bounds checking, the runtime does. – spender Jun 21 '13 at 01:12
  • He's right - I just ran this, and it just magically "stops" at the 5th iteration through the loop, and displays the Form. Really weird seeing that and no exception thrown. Edit: need to wrap it, or set VS to break on exceptions. – Gjeltema Jun 21 '13 at 01:14
  • you can check in `Debug -> Exceptions -> Common Language Runtime Exceptions -> System.IndexOutOfRangeException`, it should be checked. – King King Jun 21 '13 at 01:15
  • Strangely enough, my VS is set up to break on all CLR exceptions, including IOOR, yet it didn't break on this. – Gjeltema Jun 21 '13 at 01:20
  • @KingKing on this computer I am using VS 2010 Express and I can't seem to find the Exceptions screen. – CodeCamper Jun 21 '13 at 01:20
  • I've tested and it threw an exception normally, what kind of VS are you using? – King King Jun 21 '13 at 01:20
  • @KingKing VS2012 Professional (downloaded from MSDN). Did you put your code in the Form_Load handler of a WinForm? I put this code elsewhere and it breaks just fine, but when in the Form_Load handler, nothing. – Gjeltema Jun 21 '13 at 01:21
  • I may have found a new clue to this magic error handling. If I run with debugging it magically produces no error. If I run without debugging it says click Continue if you want to magically skip over errors and let your program continue to run. Since when does .net have a magic skip over error feature and how do I disable/implement it in other places. Surely this must be some sort of glitch or hidden feature? – CodeCamper Jun 21 '13 at 01:22
  • I see that same behavior too when starting it as "Start without Debugging". – Gjeltema Jun 21 '13 at 01:28
  • Added an edit to my answer with a reference to Hans Passant explaining this. – Gjeltema Jun 21 '13 at 01:30
  • @KingKing are you using a 64 bit machine? I think this glitch only occurs on 64 bit machines.__________ `-1 for .NET :(` – CodeCamper Jun 21 '13 at 01:44
  • @CodeCamper yes, I'm using Win 7 Ultimate 64 bit, but I don't think it matters, this kind of exception always threw when I used my old 32 bit machine. – King King Jun 21 '13 at 03:47
  • @KingKing If you run in debug mode it throws an error? If you launch the program without debug it doesn't give you the choice to continue? Gjeltema posted a bunch of articles as to how this is a glitch and everyone was experiencing it so I am curious as to what patch you downloaded to fix this. – CodeCamper Jun 21 '13 at 04:47
  • @CodeCamper start debugging will throw the exception, start without debugging will show a dialog asking for exit or continue, clicking continue button will run normally (of course). I didn't download any patch, I'm using VS 2008 Express and VS 2010 Ultimate. – King King Jun 21 '13 at 04:59
  • @KingKing tested on VS 2010 Express and Gjeltema tested on 2012 Professional. I am curious as to why your debugger throws an exception and ours do not... – CodeCamper Jun 21 '13 at 06:11
  • @CodeCamper My guess is he didn't put the code in a handler for a Load event for a WinForm. – Gjeltema Jun 21 '13 at 14:25

1 Answers1

3

If you wrap the code in a try-catch, you'll see the exception thrown. My guess is the exception is thrown and swallowed by the Form somehow when the try-catch isn't there.

    void Form1_Load(object sender, EventArgs e)
    {
        try
        {
            for (int x = 0; x < 20; x++)
            {
                label[x] = new Label { Name = x.ToString("00"), BackColor = Color.Blue, Text = "Test" };
                panel[x] = new Panel { Name = x.ToString("00"), BackColor = Color.Blue };
            }
            this.Controls.AddRange(label);
            this.Controls.AddRange(panel);
        }
        catch (Exception ex)
        {
            this.Text = ex.Message;
        }

    }

Also, as noted by the commenters, the compiler doesn't do compile-time array bounds checking.

Edit: Additional note, this only seems to be needed when in the Load event handler for the Form. If this code is elsewhere besides that, it breaks when debugging normally (presuming your Visual Studio is set to break on CLR exceptions).

More about this issue from the great Hans Passant: Why the form load can't catch exception?

And drilling through the answers ends up at this blog post: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/

Community
  • 1
  • 1
Gjeltema
  • 4,122
  • 2
  • 24
  • 31
  • I am really curious as to how the form load event magically swallows the error. How can I create magic error ignoring events!? Also I found a new clue if you run without debugging .NET Framework says `hello welcome to the hidden implementation of VBs on error goto break; press continue to magically skip over errors thank you have a nice day.` – CodeCamper Jun 21 '13 at 01:25
  • So it is a glitch that is only experienced on 64 bit machines if I understand those links correctly hmmm... would wrapping the entire form load in a try catch that displays a `MessageBox` and closes the program almost emulate what should be happening? – CodeCamper Jun 21 '13 at 01:43
  • @CodeCamper Yeah, something like that is what you'll need to do to ensure users don't just click "Continue" and use an improperly initialized application. – Gjeltema Jun 21 '13 at 01:58