C++ GCC4.4 warning: array subscript is above array bounds
Asked Answered
O

3

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" ) ) );
Oligopsony answered 22/7, 2009 at 21:56 Comment(11)
Presumably the compiler also gave a line number for the error? Please indicate it in your code via a comment.Pearl
Out of curiosity, does it still do it if you declare stringSize as const?Birdcage
It does not give the line #, the warning i posted there is the exact text from the compiler.Oligopsony
You'll have to explain this to me, I don't see how the constness of stringSize could be implicated in anything here.Deservedly
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).Birdcage
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.Medievalist
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.Deservedly
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.Deservedly
@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.Oligopsony
Thanks - I have this problem, too, and your workaround helped me. Upvoted.Pilgarlic
Does anybody know the reason for this warning?Cox
E
3

Got the same error. As a workaround I replaced

is_any_of(" ")

with

is_from_range(' ', ' ')

which might also be slightly more efficient.

Emera answered 1/12, 2009 at 17:55 Comment(0)
M
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.

Medievalist answered 22/7, 2009 at 22:32 Comment(0)
E
3

Got the same error. As a workaround I replaced

is_any_of(" ")

with

is_from_range(' ', ' ')

which might also be slightly more efficient.

Emera answered 1/12, 2009 at 17:55 Comment(0)
D
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++;
   }
Deservedly answered 22/7, 2009 at 22:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.