C++ Logo

std-proposals

Advanced search

[std-proposals] !continue

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Sun, 5 Nov 2023 20:38:48 +0000
Today I was programming an Arduino microcontroller and I wrote the
following loop:

            for ( ; Serial.available(); ++p )
            {
                if ( p >= &buf[sizeof(buf) - 1u] ) break;
                p[0u] = Serial.read();
                p[1u] = '\0';
                unsigned const len = std::strlen(buf);
                char *ending = nullptr;
                if ( nullptr != (ending = std::strstr(buf, "\r\n")) )
                {
                    ending[0u] = '\0';
                    ending[1u] = '\0'; // Overwrite the "\r\n" with "\0\0"
                    if ( ending != buf ) this->ProcessInput();
                    buf[0u] = '\0';
                    p = buf - 1u; // subtract 1 because it will be
incremented upon continuing
                }
            }

On the third last line, you'll see that I wrote:

    p = buf - 1u; // subtract 1 because it will be incremented upon continuing

instead of just:

    p = buf;

and that's because 'p' will get incremented upon the next iteration of
the loop, i.e. the 'for' loop has '++p' as the post-iterative step.

This code I've written today will work fine on a microcontroller, but
on a desktop PC that has extreme debugging enabled (for example
'mudflap' or 'address santiser'), the debugger will stop the program
when it sees that 'p' has become less than 'buf'.

So I was thinking . . . what if we could easily express that we want
to continue on to the next iteration of the loop, but that we don't
want to execute the post-iterative step. Maybe we could write
"!continue" for this, something like:

            for ( ; SerialSimGsm.available(); ++p )
            {
                if ( p >= &buf[sizeof(buf) - 1u] ) break;
                p[0u] = SerialSimGsm.read();
                p[1u] = '\0';
                unsigned const len = std::strlen(buf);
                char *ending = nullptr;
                if ( nullptr != (ending = std::strstr(buf, "\r\n")) )
                {
                    ending[0u] = '\0';
                    ending[1u] = '\0'; // Overwrite the "\r\n" with "\0\0"
                    if ( ending != buf ) this->ProcessInput();
                    buf[0u] = '\0';
                    p = buf;
                    !continue; // Don't allow 'p' to be incremented
                }
            }

In this example, the post-iterative step is quite simple, but there
are other times when I write loops like:

            for ( ; Serial.available(); delayMicroseconds(750u), ++p )
or:

            for ( ; Serial.available(); Serial2.write(Serial.read()) )
DoSomethingInBetween();

and so the statement "!continue" could be quite versatile in these
more complex loops.

Received on 2023-11-05 20:38:59