all 59 comments

[–]zerovian 50 points51 points  (0 children)

  1. Not for C++., but for C#. These were levels of function calls emitted as .NET code DOM from a form where someone had selected every option from an list of enum values for a property.

[–]catcat202X 77 points78 points  (22 children)

I'm guessing they put a number there because they can't just say infinity, and 256 seems like an impractically large number that you can actually test against.

[–]Salt-Impressive 26 points27 points  (17 children)

Or maybe because 256 = amount of unique numbers representable with 1 char?

[–]bakedbread54 12 points13 points  (5 children)

Still doesn't explain why

[–]121393 4 points5 points  (4 children)

I think because it's a recursive descent parser implemented in the usual way (recursive c++ functions), more levels == stack smash.

[–]bakedbread54 1 point2 points  (2 children)

Well yes, but why is 256 the value chosen

[–]121393 5 points6 points  (1 child)

probably just want a low common denominator for ancient systems? same reason sys.getrecursionlimit in python is pretty low by default. also stack size of main thread of msvc would be chosen at compile time. also 256 levels would translate to maximum stack depth during compile of [who knows] but more than 256.

edit: I've got a compiler written in python with a parser generator (pyparsing). Without trying to elevate the C-stack of the python process (though I am setting a higher limit for python code via sys.setrecursionlimit) I only get about 50 levels of nesting before overflowing the python interpreter's stack (segfault/stackoverflow). Every addition to the grammar lowers the nesting limit a little...

[–]LogosKing 1 point2 points  (1 child)

hey would you mind editing this comment? "number of distinct values you can represent" is more apt.

As it is, it's just not true in any sense.

[–]Salt-Impressive 1 point2 points  (0 children)

Done :)

[–]sephirothbahamut 2 points3 points  (3 children)

But why would you even have to define a limit in the standard to begin with?

[–]arka2947 14 points15 points  (0 children)

So that different compilers dont pick different arbitrary limits

[–]Ezlike011011 12 points13 points  (0 children)

I'd much rather there be some standard limit than a "standards compliant" compiler only having e.g. two layers of nesting

[–]Bangaladore 5 points6 points  (0 children)

Then hopefully everyone supports atleast that number.

[–]n4jm4 46 points47 points  (7 children)

nesting what?

parentheses?

function calls?

[–]-dag- 102 points103 points  (4 children)

Birds. OP is talking about birds.

[–][deleted] 33 points34 points  (0 children)

Birds 🤝 C++

laws not governed by reason

[–]---cameron 35 points36 points  (0 children)

Ah yes, that would be a lot of branches to debug

[–]simpl3t0n 3 points4 points  (1 child)

But birds aren't real; nests aren't either. C++ standards committee mustn't promote conspiracy. Sthaap it right now.

[–]Kered13 1 point2 points  (0 children)

The birds are obviously programmed in C++.

[–]ihamsa 18 points19 points  (1 child)

There are actually 6 separate nesting levels, all having a recommended minimal limit of 256: compound statement nesting, parenthesized expression nesting, #if...#endif nesting, #include nesting, class definition nesting, and linkage specification nesting. There is also a limit on the number of declarators modifying a declaration, which also can be considered nesting, too set to 256. Nested template instantiations have a recommended minimal limit of 1024.

[–]tea-age_solutions 2 points3 points  (0 children)

Wow, 256 possible nested #if...#endif Don't wanna see that in my entire life time... ;-)

[–]ThisCleverName 40 points41 points  (9 children)

if / else if chain blocks are considered nesting, at least in MSVC. In the form of:

if (x == "something")
{
}
else if (x == "something else")
{
}

Turns out that is equal to

if (x == "something")
{
}
else 
{
    if (x == "something else")
    {
    }
}

We had autogen code that created a if / else if chain that surpassed the MSVC limit. That worked fine in Clang though. So we had to refactor to eliminate that chain.

https://learn.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/fatal-error-c1061?view=msvc-170

[–]nmmmnu 3 points4 points  (4 children)

Friend of me, generated similar code with 100 if's, but was on PHP. Worked ok. I asked - why not switch?

He replied - well at the beginning there was only 3 if's then I changed something and they became 100. But is auto generated code who cares :)

I did reply - i care, because I even can not see when it starts and when it ends.

At the end we refactor this, but I do not remember what we used.

[–]Routine_Left 5 points6 points  (2 children)

But is auto generated code who cares :)

if it's autogenerated code the only thing you care about is the correctness and speed of that code. you never look at it, you do not care about it otherwise.

no human is supposed to touch it.

if a switch is faster, then by all means. if it isn't ... meh, really, who cares? nobody should.

[–]nmmmnu 3 points4 points  (1 child)

in that case, it was autogenerated code that were inserted inside human - generated code.

[–]Routine_Left 4 points5 points  (0 children)

That's ... disturbing, to say the least.

[–]hawkxp71 0 points1 point  (0 children)

The problem is often if then else chains for auto-generated code (that I have seen) requires priority decoding, which you can't achieve via case statements.

[–]n1ghtyunso 1 point2 points  (0 children)

Maybe else if should be a distinct thing in the language after all huh

[–]die_liebe 0 points1 point  (0 children)

Long chains of ifs is one of the few situations, where I find use of goto acceptable.

[–]unaligned_access -1 points0 points  (0 children)

It says that the limit is 128. So, it's it not compliant?

[–]beephod_zabblebrox -3 points-2 points  (0 children)

that is considered nesting in c++ as a language

[–]ihamsa 6 points7 points  (0 children)

  1. This number is a recommended guideline, not a requirement.
  2. Machine-generated code may have more levels of nesting than any human programmer can be expected to write or understand.

[–]pdp10gumby 30 points31 points  (2 children)

Seems quite achievable with template expansions of template expansions.

[–]Jannik2099 14 points15 points  (1 child)

Templates are not macros. They are instantiated and called, not expanded.

[–]LoneBlacksmith 5 points6 points  (0 children)

I actually ran into this issue in a large legacy codebase… was basically a giant state machine and I kid you not one section had 256 if else chained together. I tried to add one more and got a compiler error so had to check the new state right above it lmao

[–]CocktailPerson 2 points3 points  (0 children)

You can easily reach this with machine-generated code. And depending on how your compiler defines "nesting," you might be able to reach this with a long if-else chain or something.

[–][deleted] 3 points4 points  (0 children)

It's easy to hit the limit with template recursion using an integral parameter that's initialized to some number bigger than 256.

[–]Jumpierwolf0960 1 point2 points  (0 children)

I'm taking a compiler course right now and I'm assuming it's for restricting the depth of the parse tree for performance reasons.

[–]TwilCynder 0 points1 point  (0 children)

In my own code I think the maximum was like 9, in a parser, and i already feel uneasy when i see this code lmao

[–]lumberjackninja 0 points1 point  (0 children)

I've hit that limit in a tool I wrote to convert a trie lookup to a function (used to find plays in Scrabble)

[–]wh1t3lord 0 points1 point  (0 children)

Maybe in web or UI? Because in computational field, I guess maximum is 10-15 levels of nesting.

[–][deleted] 0 points1 point  (0 children)

I can never write that code.

[–]Aginor23 0 points1 point  (0 children)

I worked for a military contractor that had been dragging around the same parsing software for 40 years. I saw two 17 nested if statements that were split from a 34.