3

I have heard of a limitation in VC++ (not sure which version) on the number of nested if statements (somewhere in the ballpark of 300). The code was of the form:

if (a) ...
else if (b) ...
else if (c) ...
...

I was surprised to find out there is a limit to this sort of thing, and that the limit is so small. I'm not looking for comments about coding practice and why to avoid this sort of thing altogether.

Here's a list of things that I'd imagine could have some limitation:

  • Number of functions in a scope (global, class, or namespace).
  • Number of expressions in a single statement (e.g., compound conditionals).
  • Number of cases in a switch.
  • Number of parameters to a function.
  • Number of classes in a single hierarchy (either inheritance or containment).

What other control structures/language features have limits such as this? Do the language standards say anything about these limits (perhaps minimum requirements for an implementation)? Has anyone run into a particular language limitation like this with a particular compiler/implementation?

EDIT: Please note that the above form of if statements is indeed "nested." It is equivalent to:

if (a) { //...
}
else {
    if (b) { //...
    }
    else {
        if (c) { //...
        }
        else { //...
        }
    }
}
  • 1
    The code may have same effect, but it is not necessarily identical. –  Jan 22 '10 at 17:56
  • 3
    Well, that would be where you are wrong. The compiler cares a great deal about scope. –  Jan 22 '10 at 18:00
  • 2
    From the compiler's point of view, chained `if` statements aren't nested, because there's only one conditional active at once. Some languages have an `else if` construct to make this more clear (as does the C and C++ preprocessor). If you get into compiler design, you'll find that parsing a conventional nested if statement is much different from parsing a chained `else if` construct. – David Thornley Jan 22 '10 at 18:06
  • 2
    @stringray: Neil and David are correct, those two bits of code are not equivalent from the compiler's point of view. – BlueRaja - Danny Pflughoeft Jan 22 '10 at 18:08
  • 1
    Stinray: no, your samples are not identical. The scoping is different. – Paul Nathan Jan 22 '10 at 18:09
  • I have to agree with Stingray. Since there're no contents in the expanded nesting version, there's no difference whatsoever in the scoping. – Max Shawabkeh Jan 22 '10 at 18:26
  • @Max That is not what I said, as you will see if you read my two comments above. –  Jan 22 '10 at 18:31
  • 1
    @Max: The compiler still has to keep track of the scopes internally, it can't know ahead of time that there's nothing there without looking at it first. The compiler is not psychic. – BlueRaja - Danny Pflughoeft Jan 22 '10 at 18:31
  • @STingRaySC: Neither C nor C++ has an explicit `elseif` construct, but `else if` works nicely. The difference is not in the language definition, which makes no distinction, but in the front end of the compiler. The fact that only one scope is open at a time (the `if` statement is completely wrapped up, and then the `else` is handled) makes the difference. Possibly if compilers worked very differently there would be no practical difference between bush and chain, but in this world with this technology there is a great difference. – David Thornley Jan 22 '10 at 18:53
  • Also, the compiler can't predict the future. It can know the past. In an `if (...) if (...)` construct, it can't know whether there will be `else` constructs. In an `if (...) this; else if (...) that;...` construct, it knows when it hits each individual `else` that everything behind it has been wrapped up. – David Thornley Jan 22 '10 at 18:56
  • 1
    @StingRay: You need to grow up. Bolding and capitalizing your statements doesn't magically make them better arguments. It just makes you look immature. There are some very experienced people here, and I'm grateful to be able to get their input on things. You should do the same. Be here with an open mind ready to learn or discuss things, not throw a temper when someone disagrees with you. Support your ideas with reason and evidence, not emotion. Emotion caries no substance in a discussion. I don't mean to create an awkward situation or a bad taste in your mouth about me, though. – GManNickG Jan 22 '10 at 19:41
  • I know that I'm very late to this post, but since you can define variables inside of the conditions (e.g. `if (int x = 0)`) of `if` constructs, I do believe they have scopes. Further, since those variables are accessible from further conditions in the `else if` chain, I believe the scopes are indeed nested. They may be parsed differently by a front-end, but the nested scopes must exist nonetheless. – Chris Badger May 24 '16 at 23:50

4 Answers4

11

Visual C++ Compiler Limits

The C++ standard recommends limits for various language constructs. The following is a list of constructs where the Visual C++ compiler does not implement the recommended limits. The first number is the recommended limit and the second number is the limit implemented by Visual C++:

  • Nesting levels of compound statements, iteration control structures, and selection control structures [256] (256).

  • Parameters in one macro definition [256] (127).

  • Arguments in one macro invocation [256] (127).

  • Characters in a character string literal or wide string literal (after concatenation) [65536] (65535).

  • Levels of nested class, structure, or union definitions in a single struct-declaration-list [256] (16).

  • Member initializers in a constructor definition [6144] (approximately 600, memory dependent, can increase with the /Zm compiler option).

  • Scope qualifications of one identifier [256] (127).

  • Nested external specifications [1024] (10).

  • Template arguments in a template declaration [1024] (64).

Nikola Smiljanić
  • 26,745
  • 6
  • 48
  • 60
6

Do the language standards say anything about these limits (perhaps minimum requirements for an implementation)?

No, the standard sets no minimum limits on this. But it is good practice for an implementation to set and document a hard limit on such things, rather than fail in some unknown way when the limit is exceeded.

Edit: The standard recommends some minimum limits In Annex B - there are really too many to post here and they are in any case advisory:

The limits may constrain quantities that include those described below or others. The bracketed number following each quantity is recommended as the minimum for that quantity. However, these quantities are only guidelines and do not determine compliance.

  • 1
    As I recall, the standard sets some recommended minimum limits somewhere in one of the appendices. Doesn't it? (Don't have the standard here to check) – jalf Jan 22 '10 at 17:46
  • 2
    There are some minimum lengths for identifiers, if I recall. Oh, all right, I'll have a look, but I can't recall anything else. –  Jan 22 '10 at 17:48
  • Agreed. There are physical limitations that vary between environments, and having a well defined limitation is better than an unknown one. – user229044 Jan 22 '10 at 17:52
  • 2
    I can tell you have never written a compiler. –  Jan 22 '10 at 17:58
  • @meagar: There was a P.J. Plauger column on that in an old magazine, discussing the C standard limit on nested `#include`s. The options seemed to be: say nothing (so nobody could count on anything), recommend something (see last parenthesis), set a high or infinite limit (which would complicate compiler writing for no clear use case) or set a low limit. The Committee went with the last approach. – David Thornley Jan 22 '10 at 17:58
  • The recommended minimum limit for nested control structures is 256. But, to hammer the point home, that is just a recommendation. – Mike Seymour Jan 22 '10 at 17:59
  • 2
    @STingRaySC:One time on comp.lang.c.moderated there was a rather long discussion about how hard a compiler was required to *try* to compile a program to conform. By the end there was nearly a complete consensus that technically, a program that never did anything but print "compiler limit exceeded" probably qualified as a conforming implementation (with the proper documentation). – Jerry Coffin Jan 22 '10 at 18:05
  • @Jerry Coffin: There was Peter Seebach's compiler that copied the program to /dev/null (he used Unix), printed "Warning: wonky compiler" (the required diagnostic in case the program is ill-formed in a way the compiler is required to diagnose), and IIRC it then returned 0. I never dug into the C Standard definition of a conforming implementation, but he said it looked like a conforming C compiler to him. – David Thornley Jan 22 '10 at 18:58
  • 1
    @STingRaySC: We can tell you've never written a compiler because you're looking at a conditional construct from the point of view of the language definition, not how easy or difficult it would be for the compiler to parse, represent, and translate. There's nothing wrong with never having written a compiler, but if you do (even a small one) you will understand the discussion here better. – David Thornley Jan 22 '10 at 19:02
3

C specifies that implementations must be able to translate a program that contains an instance of each of a number of limits. The first limit is that of 127 nesting levels of blocks. (5.2.4.1 of ISO/IEC 9899:1999)

C doesn't say that any valid program that contains no more than 127 nesting levels must be translated; it could be unreasonably large in other ways. The rationale was to set some level of expectation that portable programs can have, while allowing latitude not to exclude small implementations and implementations targetting small systems.

In short, if you want more than 127 nesting levels it probably means that you should consult your implementation's documentation to see if it guarantees to support a larger number.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
3

Just to put the whole scoping thing to bed, the following is legal C++ code:

int main() {
    if ( int x = 1 ) {
    }
    else if ( int x = 2 ) {
    }
}

which it would not be if both the if and the else if were at the same scope. I think there have been a lot of misunderstandings, perhaps engendered by my comment:

The compiler cares a great deal about scope. 

which is of course true, but maybe not helpful in this situation.