8

I recently upgraded to GCC 4.4 (MinGW TDM build) and now the follow code produces these warning:

In member function 'void Console::print(const std::string&)':

warning: array subscript is above array bounds

Here's the code:

void Console::print( const std::string& str ) {
        std::string newLine( str );
        if( newLine.size() > MAX_LINE_LENGTH ) {
            sf::Uint32 stringSize = newLine.size();
            for( sf::Uint32 insertPos = MAX_LINE_LENGTH;
                    insertPos < stringSize; insertPos += MAX_LINE_LENGTH ) {
                newLine.insert( insertPos, "\n" );
            }
        }

        StringList tokens;
        boost::split( tokens, newLine, boost::is_any_of("\n") );

        for( StringList::iterator it = tokens.begin();
                it != tokens.end(); ++it ) {
            addLine( *it );
        }
    }

Any ideas?


It is the optimizations that are doing it...

Also it appears to be this line which is causing it:

boost::split( tokens, newLine, boost::is_any_of("\n") );

Ah yes, I found it, it is the argument for boost::is_any_of(), by wrapping it in a string() constructor the warning goes away, thank you all for your help :)

boost::split( tokens, newLine, boost::is_any_of( string( "\n" ) ) );
Community
  • 1
  • 1
Adam
  • 25,966
  • 23
  • 76
  • 87
  • 2
    Presumably the compiler also gave a line number for the error? Please indicate it in your code via a comment. –  Jul 22 '09 at 22:03
  • 2
    Out of curiosity, does it still do it if you declare `stringSize` as `const`? – Pavel Minaev Jul 22 '09 at 22:15
  • It does not give the line #, the warning i posted there is the exact text from the compiler. – Adam Jul 22 '09 at 22:19
  • You'll have to explain this to me, I don't see how the constness of stringSize could be implicated in anything here. – Andy J Buchanan Jul 22 '09 at 22:33
  • 1
    It is clear that compiler is trying to do some code analysis to figure out whether the for-loop in this case can ever have index variable out of bounds. I'm wondering if perhaps it sees that the upper bound the index variable is compared against is non-const, and assumes that some other code elsewhere might change it (and isn't smart enough to see that there is no code path that could lead to that here). – Pavel Minaev Jul 22 '09 at 22:46
  • 3
    In view of your edit saying what line it is, I'm more confident in my "compiler bug" theory. I reckon most likely it's the `boost::is_any_of`, and it's iterating over the string literal and triggering a spurious bound warning for an end-of-array pointer. – Steve Jessop Jul 22 '09 at 22:52
  • Good theory, seems very plausible. In fact I encountered something like that in gcc last year, it was a bit easier to spot though, not being buried in template code. – Andy J Buchanan Jul 23 '09 at 01:28
  • BTW, unrelated to your actual question, but I'm pretty sure my answer about your '\n' insert loop being in error is right, the loop as written does not split the lines evenly (which I assume you intended), and terminates too early. – Andy J Buchanan Jul 23 '09 at 01:37
  • @Andy J Buchanan: Yes I saw that too, instead of "stringSize" I now just use "newLine.size()" right in the loop. Also, I init "insertPos = MAX_LINE_LENGTH - 1" now as well. – Adam Jul 24 '09 at 01:18
  • 2
    Thanks - I have this problem, too, and your workaround helped me. Upvoted. – Jim Hunziker Oct 16 '09 at 17:33
  • Does anybody know the reason for this warning? – fcatho Aug 02 '16 at 09:56

3 Answers3

3

Could have something to do with one or more of these GCC bugs:

GCC bugzilla search results for "Warning: array subscript is above array bounds"

Not all of them are valid, but there are some fixed ones if you search around, too:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37861

So I'm pretty sure there's something going on there. Based on the comments, I'd try compiling without optimisation and see if it goes away.

I got a spurious bounds warning using one of the standard algorithms (std::remove, I think) and passing iterator parameters:

myarray, 
myarray + sizeof(myarray)/sizeof(*myarray)

which I'm pretty sure are in bounds. It was only in toy code, though, so I just bodged around it. If GCC really is throwing dodgy warnings you'll just have to inspect your code extra-carefully until it's fixed.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
3

Got the same error. As a workaround I replaced

is_any_of(" ")

with

is_from_range(' ', ' ')

which might also be slightly more efficient.

Patrick Ohly
  • 712
  • 6
  • 8
1

I notice your loop here is altering the length of the string, but not updating the loop termination condition. Could this be the source of your issue?

   sf::Uint32 stringSize = newLine.size();
   for( sf::Uint32 insertPos = MAX_LINE_LENGTH;
      insertPos < stringSize; insertPos += MAX_LINE_LENGTH ) 
   {
      newLine.insert( insertPos, "\n" );
      // You were probably wanting to put this here..
      insertPos++;
      stringSize++;
   }
Andy J Buchanan
  • 1,952
  • 14
  • 13