2014-01-17 32 views
2

我看rabbitmq-c,我注意到以下几点:关于RabbitMQ的-C使用C语法问题

首先,我不太了解外支架,像这样的用法:

{ 
    amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_empty_bytes, 0, 0, 0, 1, 
           amqp_empty_table); 
    die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue"); 
    queuename = amqp_bytes_malloc_dup(r->queue); 
    if (queuename.bytes == NULL) { 
     fprintf(stderr, "Out of memory while copying queue name"); 
     return 1; 
    } 
    } 

其次,来看看这个:

{ 
    while (1) { 
     amqp_rpc_reply_t res; 
     amqp_envelope_t envelope; 

     amqp_maybe_release_buffers(conn); 

     res = amqp_consume_message(conn, &envelope, NULL, 0); 

     if (AMQP_RESPONSE_NORMAL != res.reply_type) { 
     break; 
     } 

     printf("Delivery %u, exchange %.*s routingkey %.*s\n", 
      (unsigned) envelope.delivery_tag, 
      (int) envelope.exchange.len, (char *) envelope.exchange.bytes, 
      (int) envelope.routing_key.len, (char *) envelope.routing_key.bytes); 

     if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { 
     printf("Content-type: %.*s\n", 
       (int) envelope.message.properties.content_type.len, 
       (char *) envelope.message.properties.content_type.bytes); 
     } 

     amqp_destroy_envelope(&envelope); 
    } 
    } 

在我看来,如果AMQP_RESPONSE_NORMAL = res.reply_type,while循环应该打破!但是,它没有。 break语句就像一个'continue'语句。显然,使用'继续'是行不通的。再次,我不知道为什么,因为据我所知,休息会导致退出while循环。

回答

6

大括号引入复合语句和新的内部作用域。

如果定义了一个复合语句中的变量,它们只是内部的复合语句,并且,至少在原则上(最内层{}之间)是可见的,当复合语句不执行不存在。

另外,在C99之前,C不允许声明和声明混合使用。每个块(包括一个函数的最外面的块)必须包含一系列零个或多个声明后面的声明。创建一个新的内部块是一种允许在函数中引入一个新变量(其初始值可能取决于函数中先前的计算)的方法。这一方面不再是必要的,但(a)代码可能设计为可与C99之前的编译器编译,并且(b)限制范围无论如何都是一个好主意。

至于break声明,是的,它确实终止了while循环 - 在这种情况下,它似乎是封闭的while (1)循环可以停止的唯一方式。执行break;后,执行将在while循环的关闭}后继续。一条continue语句将终止循环的当前迭代并重新开始在顶部。

在快速浏览完整源代码之后,回应您​​的评论,似乎没有任何围绕while循环的外部大括号的理由。源代码大纲如下:

int main(int argc, char const *const *argv) 
{ 
    /* ... */ 
    {     // <-- Opening outer brace 
     while (1) { 
      /* ... */ 
     } 
    }     // <-- Closing outer brace 
    /* ... */ 
} 

删除它们应该没有效果。如果开放式外支架和while (1)之间有声明,它们可能会很有用。也许有代码的早期版本,或者作者可能会在稍后添加某些内容。外括号是无害但无用的。

而且由于该项目使用git进行维护,因此我们可以查看该文件的以前版本。 examples/amqp_listen.c的前一个版本在while (1)之前的块顶部有几个声明。在当前版本中,这些声明被删除(并且一些声明被添加在while循环本身的顶部,但不是相同的。)

这样的小故障很容易发生,因为软件是维护的;恕我直言,这一个是不是一个大问题。

至于你的问题的第二部分,我不知道你为什么说break不会终止循环。难道是循环只是再次进入?(我没有研究其余的代码就说不清)。

+0

在上面的代码中,是否有任何理由使用外括号?如果while循环永远运行,则只有两个变量res和envelope会在循环重启时自动销毁。 – Bob

+0

@Bob:我已经更新了我的答案。 –

+0

@Bob:另一个更新;看最后几段。 –