ラベル付きbreakが欲しい

他の多くの言語には、ラベル付きbreakがあるのに、C++にはない。
マクロで強引に実装してみた。
ついでに制御移行条件、制御移行前実行部も付けてみる。

#define CAT2(X,Y) X##Y
#define XCAT(X,Y) X##Y
#define CAT(X,Y) CAT2(X,Y)
#define BRK CAT(BRK, __LINE__)
#define CNT CAT(CNT, __LINE__)
#define RDO CAT(RDO, __LINE__)
#define BLABEL(lable) XCAT(BRK,lable)
#define CLABEL(lable) XCAT(CNT,lable)
#define RLABEL(lable) XCAT(RDO,lable)
#define BREAK(cond, label)					\
if(!((sizeof(#cond)==1)||bool(cond)))				\
  if(0){ CAT(NOLABEL,__LINE__): break; } else;			\
else								\
  for(int CAT(LAST,__LINE__)=0;;++CAT(LAST,__LINE__))		\
    if(CAT(LAST,__LINE__))					\
      { goto BLABEL(label); BRK: goto CAT(NOLABEL,__LINE__); }	\
    else
#define CONTINUE(cond, label)					\
if(!((sizeof(#cond)==1)||bool(cond)))				\
  if(0){ CAT(NOLABEL,__LINE__): continue; } else;		\
else								\
  for(int CAT(NEXT,__LINE__)=0;;++CAT(NEXT,__LINE__))		\
    if(CAT(NEXT,__LINE__))					\
      { goto CLABEL(label); CNT: goto CAT(NOLABEL,__LINE__); }	\
    else

#if defined(__GNUC__)
#define REDO(cond, label)					\
if(!((sizeof(#cond)==1)||bool(cond)));				\
else								\
  for(int CAT(REDO,__LINE__)=0;;++CAT((REDO,__LINE__))		\
    if(CAT((REDO,__LINE__))					\
      { goto RLABEL(label); RDO: goto *REDO; }			\
    else
#else
#define REDO(cond, label)					\
if(!((sizeof(#cond)==1)||bool(cond)));				\
else								\
  for(int CAT((REDO,__LINE__)=0;;++CAT((REDO,__LINE__))		\
    if(CAT((REDO,__LINE__)) goto RLABEL(label);			\
    else
#endif
#if defined(__GNUC__) || defined(_MSC_VER)
#define FOR(...)   for(__VA_ARGS__)      LABEL
#define WHILE(...) while(__VA_ARGS__)    LABEL
#define DO         do                    LABEL
#else
#define FOR(X)   for  (X)    LABEL
#define WHILE(X) while(X)    LABEL
#define DO       do          LABEL
#endif


#if defined(__GNUC__)
#define LABEL(label)						\
if(void*RE_DO=&&RLABEL(label))					\
  { goto RLABEL(label); BLABEL(label): break; CLABEL(label):; }	\
else RLABEL(label):
#else
#define LABEL(label)	\
if(0) { BLABEL(label): break; CLABEL(label):; } else RLABEL(label):
#endif

GCC以外に、VC,BCCでもある程度動く。条件部、ラベルはどちらも省略可能
使用例

    // BREAKの動作確認。    
    puts("BREAKの動作確認");
    FOR(i=1; i<=5; i++)(next1) {
      for(j=1; j<=3; j++) {
        printf("i=%d j=%d\n", i, j);
        BREAK(i+j >= 4, next1)  // i+j >= 4 のとき、ループから脱出する。
          puts("BREAK実行");    // ループから脱出する前にこの文を実行する。
      }
    }
    puts("");

    // CONTINUEの動作確認。    
    puts("CONTINUEの動作確認");
    FOR(i=1; i<=5; i++)(next2) {
      for(j=1; j<=3; j++) {
        printf("i=%d j=%d\n", i, j);
        CONTINUE(i+j >= 4, next2)
          puts("CONTINUE実行");
      }
    }