【问题标题】:Questions about C syntax used in rabbitmq-c关于rabbitmq-c中使用的C语法的问题
【发布时间】:2014-01-17 19:39:02
【问题描述】:

我正在查看rabbitmq-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 语句的作用类似于“继续”语句。显然,使用“继续”是行不通的。同样,我不确定为什么,因为据我所知,中断会导致退出 while 循环。

【问题讨论】:

    标签: c++ c while-loop rabbitmq break


    【解决方案1】:

    大括号引入了复合语句和新的内部范围。

    如果您在复合语句中定义变量,则它们仅在该复合语句中可见(在最里面的封闭 {} 之间),并且至少在原则上,当该复合语句是没有执行。

    此外,在 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 不会终止循环。难道是简单地再次进入循环? (如果不研究其余代码,我无法判断。)

    【讨论】:

    • 在上面的代码中,有什么理由使用外大括号吗?如果while循环永远运行,那么只有两个变量res和envelope应该在循环重启时自动销毁。
    猜你喜欢
    • 2021-05-15
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多