Split region names in C / C ++

Introduction

This question follows from this: Named idiom: is it dangerous? . For people who do not want to read the original question, they talked about such things:

named(label1) for(int i = 0 ; i < 10 ; i++) {
    for(int j = 0 ; j < 10 ; j++) {
      if(some_condition)
            break(label1); // exit outer loop
      }
}

This new question is about an improved version of the named loop idiom. If you are too lazy to read the whole post, you can directly go to the "Example" section of this post to clearly understand what I'm talking about.

Design violations

Unfortunately, the question was closed very quickly (and was later reopened later), because there were more discussions for the pros / cons than a purely technical question. It seems that this does not match the SO Q & A format. Moreover, the code I presented had several flaws:

  • break
  • ( , MSVC):

    int foo() {
    
       named(label1) for(int i = 0 ; i < 10; i++)
       {
          if(some_condition)
          {
              break(label1);  // here it ok, the behavior is obvious
          }   
       }
    
       break(label1); // it compiles fine without warning... but the behavior is pretty obscur!
    
    }
    
  • . , - .

    int foo() {
    
    named(label1)  for(int i = 0 ; i < 10 ; i++)
           named(label2)  for(int j = 0 ; j < 10 ; j++)
            if(i*j<15)
                cout << i*j << endl;
            else
                break(label2);
     }
    

, . , , .

NAMED break:

    #define NAMED(bn)   if(const bool _YOU_CANNOT_USE_NAMED_BREAK_IF_YOU_ARE_OUTSIDE_##bn##_ = true)\
                            goto _named_loop_identifier__##bn##_;\
                        else\
                            _break_the_loop_labelled_##bn##_:\
                            if(true)\
                                {}\
                            else\
                                if(! _YOU_CANNOT_USE_NAMED_BREAK_IF_YOU_ARE_OUTSIDE_##bn##_)\
                                    goto _break_the_loop_labelled_##bn##_;\
                                else\
                                    _named_loop_identifier__##bn##_:\


    #define BREAK(bn) if(!_YOU_CANNOT_USE_NAMED_BREAK_IF_YOU_ARE_OUTSIDE_##bn##_){} \
                        else goto _break_the_loop_labelled_##bn##_

, , MSVC GCC, , " ", " " " ". , , . :

    NAMED(loop1) for(int i = 0 ; i < 10; i++) {
        NAMED(loop2) for(int j = 0 ; j < i ; j++) {
            cout << i << "," << j << endl;
            if(j == 5) {
                BREAK(loop1);   // this one is okay, we exit the outer loop
            }
        }
        BREAK(loop2); // we're outside loop2, this is an error
    }

, break: '_YOU_CANNOT_USE_NAMED_BREAK_IF_YOU_ARE_OUTSIDE_loop2_`, .

, () :

break :

     NAMED(myloop) for(int i = 0 ; i < rows; i++) {
         for(int j = 0 ; j < cols ; j++) {
            if(some_condition) {
                 BREAK(myloop);
            }
         }
     }

:

NAMED(myscope1) {
    cout<< "a";
    NAMED(myscope2)
    {
        cout << "b";
        NAMED(myscope3)
        {
            cout << "c";
            BREAK(myscope2);
            cout << "d";
        }
        cout << "e";
    }
    cout <<"f";
}

: abcf.

, , , , , 10 .

" ?", " ?" " ?", stackoverflow . , : " - ", " " " ".

. , .

  • , ? , ++ , , - ?

  • - ? . ++ ( , , - ...)?

- , . , , , ?

EDIT: const ( ). if for , , :

if(true)
     BREAK(label);

EDIT2: JensGustedt, if C ( ++). .

+5
2

, , ... bool, NAMED(bn), , if, , ? (: , .:)

, :

{
    NAMED(one) { ... }
}
BREAK(one);

BREAK(nb);

:

{
    NAMED(bn) { ... }
    BREAK(bn);
}

, , . , .

-Jesse

PS: try..finally, finally , try. , finally, .

P (PS) S: , , :

#if DEBUG
    NAMED(bn)
#endif
    while(true)
    {
        BREAK(BN);
    }

!; -D DEBUG, RELEASE.

+2

++, C...

if/else , C, else .

for, , P99. else ( ). , for - C, , , if while, ++.

, , register bool const bool. , .

, , for goto. , , - . C , , setjmp/longjmp. ++ , , try/catch.

+1

All Articles