1

When I was reading Code Complete 2nd Edition, there was a piece of code:

for ( int recordCount = 0; recordCount < MAX_RECORDS; recordCount++ ) {
  // looping code that uses recordCount
}
// intervening code
for ( int recordCount = 0; recordCount < MAX_RECORDS; recordCount++ ) {
  // additional looping code that uses a different recordCount
}

The author claimed that he found 3 different C++ compilers that has 3 different behaviors on this:

When I checked this functionality with three different C++ compilers, however, I got three different results:

  • The first compiler flagged recordCount in the second for loop for multiple variable declarations and generated an error.
  • The second compiler accepted recordCount in the second for loop but allowed it to be used outside the first for loop.
  • The third compiler allowed both usages of recordCount and did not allow either one to be used outside the for loop in which it was declared.

As is often the case with more esoteric language features, compiler implementations can vary.

This paragraph bothered me so much because I've always believed that the behavior in the third compiler is the only correct behavior, regarding to the C++ specification.

Can anyone help me to find out which section of the C++ specification specifies this behavior?

johnlinp
  • 575
  • 3
  • 15
  • 1
    The correct behavior is *"allowed both usages of recordCount and did not allow either one to be used outside the for loop in which it was declared"*. Both GCC, Clang, and MSVC do the right thing. – HolyBlackCat Mar 17 '20 at 08:59
  • 3
    How old is the book you are reading? Never seen any compiler do anything but your last expected result recently. – super Mar 17 '20 at 08:59
  • 1
    if the book calls for loops an "esotheric language feature" i'd get a different one – 463035818_is_not_a_number Mar 17 '20 at 09:05
  • @super According to https://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670, the publish date is 2004. – johnlinp Mar 17 '20 at 09:08
  • 1
    [This answer and its comments](https://stackoverflow.com/a/49448101/445976) discuss how some old compilers used to allow what is now non-standard behavior of loop variable lifetime. Note: for the most part "Code Complete 2" is still a decent book. – Blastfurnace Mar 17 '20 at 09:16
  • 2
    I've voted to close as a duplicate, since the link provided by @Blastfurnace actually answers this question. The first case described here was common with compilers compliant with draft C++ standards in the mid 90s - before the first C++ standard was ratified in 1998 and some of these compilers were still in regular use until the mid-2000s. The third case is required by all ratified C++ standards. The second case describes behaviour of some old (early to mid 90s) C++ compilers but no draft or ratified C++ standard ever required that behaviour. – Peter Mar 17 '20 at 10:20
  • Thanks @Blastfurnace for providing the link. – johnlinp Mar 17 '20 at 15:05
  • Also thanks @Peter. That's pretty much what I needed. – johnlinp Mar 17 '20 at 15:06
  • Incidentally, C++98, the first ratified standard, Section 6.5.3 "The for statement", para 3 is what requires this, with the wording "If the *for-init-statement* is a declaration, the scope of the name(s) declared extends to the end of the *for-statement*." All subsequent standards, AFAIK, have the same wording, but section numbers change. That para is followed by an illustrative example of the form `int i = 42; int a[10]; for (int i = 0; i < 10; i++) a[i] = i; int j = i; // j = 42` – Peter Mar 17 '20 at 20:19

0 Answers0