3

Just now I had a bug of the following sort:

#include <iostream>

const int i = i;

int main(void)
{
    /* not allowed by default, but with -fpermissive */
    //const int i;
    /* allowed by default, even without -fpermissive. Seems to initialize to 0 */
    for ( int j = 0; j < i; ++j )
        std::cout << "hi";
    /* i = 0 */
}

Compiled with:

g++ const-init.cpp -Wall -Wextra -pedantic -O2

Because the compiler silently initialized i to 0 some loops were optimized away. The error happened because of a copy-paste error.

Is this 'feature' valid and/or documented somewhere? What is it even good for? Does it have a name?

Edit: Without -O2 g++ behaves like I would want it to behave: it issues the following error

const-init.cpp:8:19: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
     const int i = i;
                   ^

So why does the compiler assume 0 for i when using the -O2 Flag and even deletes the whole loop because of this assumption?

mxmlnkn
  • 1,887
  • 1
  • 19
  • 26
  • 1
    Possible dupe: https://stackoverflow.com/questions/28152298/why-is-initialization-of-a-new-variable-by-itself-valid – Jonathan Potter Nov 14 '15 at 02:09
  • 1
    There's probably much more information than you need in [this Q&A](http://stackoverflow.com/questions/23415661/has-c-standard-changed-with-respect-to-the-use-of-indeterminate-values-and-und), but TL;DR: don't rely on the value of `i`. The variable `i` is in scope for its own initialization, but its value is not well-defined. – chris Nov 14 '15 at 02:09
  • You guys are fast, after posting this question I noticed that -Wall does indeed issue a warning, but not so when using -O2. I specified this in the question – mxmlnkn Nov 14 '15 at 02:12
  • 1
    When the code causes undefined behaviour the compiler may assume anything – M.M Nov 14 '15 at 02:21
  • Why do you say that the compiler assumed that `i` is `0`? Your observation (elimination of the loop) is equally consistent with `-1`, or `-999`, or `INT_MIN`. – Ben Voigt Nov 14 '15 at 02:37
  • 1
    @Voigt: I sad 0, because I didn't have the idea to test other conditions, but you are right, the loop is equally optimized away for e.g. `for ( int j=2; j>i; j--)` The only thing which won't be optimized away is: `if ( i == i ) std::cout << "At least it's equal.\n";` It all makes sense considere the comment by M.M. That should be an answer. The current answer by ThomasG doesn't question my statement of i being 0 like Voigt did. – mxmlnkn Nov 14 '15 at 09:38
  • @mxmlnkn quite old question, but just in case you still care: I had a very similar problem and tried to find out how to get a warning also with `-O2` (see [this question](http://stackoverflow.com/questions/36497982/how-to-make-g-generate-an-error-warning-for-int-i-i/36498051#36498051)). Seems like this problem is fixed in more recent versions of g++ – 463035818_is_not_an_ai Apr 08 '16 at 11:31
  • @M.M I am not sure this is UB even after [DR 2026](http://stackoverflow.com/a/34276374/1708801) – Shafik Yaghmour Jan 11 '17 at 21:18

1 Answers1

3

Its name is "undefined behaviour" and setting i to 0 is just one possible outcome.

rici
  • 234,347
  • 28
  • 237
  • 341