try/catch宏后这个分号的影响是什么?

2 c++

我正在看一些有的项目

    PREPAID_TRY ;
Run Code Online (Sandbox Code Playgroud)

这被定义为其他地方

#define PREPAID_TRY try {
Run Code Online (Sandbox Code Playgroud)

我认为通过使用;上面的程序员基本上取消了使用try?尝试不再生效,我是对的吗?

但是在它之下有这样的代码 - 我想知道如果try之前没有它,它是如何编译的?

PREPAID_CATCH_WITH_LOG(pErrInfo, "(Connect)") ;
Run Code Online (Sandbox Code Playgroud)

那定义为

#define PREPAID_CATCH_WITH_LOG(x,t) } \
  catch (const dErrorStruct& ex) {ex.FillErrorStruct(x);Log.LogPrintf(t ## " - %s", x->Description);} 
Run Code Online (Sandbox Code Playgroud)

为什么上面编译程序员;在第一次使用时编译try?在catch上面没有前面的try,是吗?

Com*_*hip 7

所以假设你有

#define PREPAID_TRY try {
#define PREPAID_CATCH_WITH_LOG(x,t) } \
  catch (const dErrorStruct& ex) {ex.FillErrorStruct(x);Log.LogPrintf(t ## " - %s", x->Description);} 
Run Code Online (Sandbox Code Playgroud)

你编写的代码如

PREPAID_TRY;
  SomeFunction();
PREPAID_CATCH_WITH_LOG(pErrInfo, "(Connect)");
Run Code Online (Sandbox Code Playgroud)

如果您自己伪装成预编译器,则可以在重新格式化后填写宏定义并检查编译器是否看到以下代码:

try { 
  ; // Empty statement
  SomeFunction();  // Your original code is still part of the try
}  // Note this brace is part of PREPAID_CATCH_WITH_LOG
catch (const dErrorStruct& ex) {
  ex.FillErrorStruct(pErrInfo);
  Log.LogPrintf("(Connect)" " - %s", pErrInfo->Description); // Note compile-time string concatenation
} 
Run Code Online (Sandbox Code Playgroud)

这给出了一个有效的try/catch块.里面有一个空的statement(;),但由于宏已经写好,你得到一组适当的大括号,这不是问题.还要注意CATCH宏处理try构造的右括号.

实际上后面的分号PREPAID_TRY可以省略,这将消除最终代码中不必要的空语句,但包括它使得行读取更像是一个语句本身而且很可能编写它的程序员甚至没有请注意他把它放在那里(我有时发现自己在写了一整天的C++或C#之后将半冒号放在常规文本中).

当你说"取消试块"时你可能会想到的是类似如下的内容:

#define PREPAID_TRY if(not_out_of_memory())
#define PREPAID_CATCH_WITH_LOG(x,t) \
  else { raise_out_of_memory_exception(); } 
Run Code Online (Sandbox Code Playgroud)

请注意,我必须替换trywith if语句,因为没有大括号的尝试首先是非法的(例如try SomeFunction() catch { ... },不允许),但是if(...) { SomeFunction(); }如果你只调用一个函数,那么大括号是可选的.这导致

if(not_out_of_memory())
  ;
SomeFunction();
else { raise_out_of_memory_exception(); } 
Run Code Online (Sandbox Code Playgroud)

我将原始SomeFunction代码向左缩进,以指示编译器如何解析它.这确实会导致编译器错误,因为当编译器到达时else,就if不再有活动语句了.正确使用此宏的唯一方法是包括您自己的大括号:

PREPAID_TRY {
  SomeFunction();
  ;;;;;; // Now you can put as many semicolons here as you like.
} 
PREPAID_CATCH_WITH_LOG(...)
Run Code Online (Sandbox Code Playgroud)