c - 为什么这些 C 宏不写成函数呢?

标签 c networking coding-style macros

我正在研究 netstat 工具 (Linux) 的代码,AFAIK 主要读取 /proc/net/tcp 文件并从中打印出来。 (我现在的重点是 -t 模式。)

我对作者选择的编码风格有点困惑:

static int tcp_info(void)
{
    INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)", tcp_do_one);
}

在哪里

#define INFO_GUTS6(file,file6,name,proc)                \
 char buffer[8192];                                     \
 int rc = 0;                                            \
 int lnr = 0;                                           \
 if (!flag_arg || flag_inet) {                          \
    INFO_GUTS1(file,name,proc)                          \
 }                                                      \
 if (!flag_arg || flag_inet6) {                         \
    INFO_GUTS2(file6,proc)                              \
 }                                                      \
 INFO_GUTS3

在哪里

 #define INFO_GUTS3                                      \
  return rc;

#if HAVE_AFINET6
#define INFO_GUTS2(file,proc)                           \
   lnr = 0;                                              \
   procinfo = fopen((file), "r");                        \
   if (procinfo != NULL) {                               \
     do {                                                \
       if (fgets(buffer, sizeof(buffer), procinfo))      \
          (proc)(lnr++, buffer);                          \
     } while (!feof(procinfo));                          \
     fclose(procinfo);                                   \
   }
#else
#define INFO_GUTS2(file,proc)
#endif

等等

很明显,我的编码意识倾斜并说“那些应该是函数”。我看不到这些宏在这里带来的任何好处。它会破坏可读性等。

周围是否有人熟悉此代码,能否阐明此处“INFO_GUTS”的含义以及是否可能(或仍然)存在这种奇怪的编码风格的原因?

如果您对它们的使用感到好奇,完整的依赖关系图如下所示:

#               /--->   INFO_GUTS1  <---\    
#  INFO_GUTS --*        INFO_GUTS2  <----*---- INFO_GUTS6
#      î        \--->   INFO_GUTS3  <---/           î 
#      |                                            |
# unix_info()              igmp_info(), tcp_info(), udp_info(), raw_info()

最佳答案

你认为“那些宏应该是函数”对我来说似乎是正确的;我更愿意将它们视为函数。

了解宏的使用频率会很有趣。然而,它们被使用得越多,如果它们是一个真正的函数而不是一个宏,就应该越节省空间。宏相当大并且使用(本来就很慢的)I/O 函数本身,因此使用宏不会提高速度。

现在,如果您想要函数的内联替换,您可以在 C(以及 C++)中使用 inline 函数。


您还可以争辩说 INFO_GUTS2 应该使用直接的 while 循环而不是 do ... while 循环;如果是,它只需要检查一次 EOF:

while (fgets(buffer, sizeof(buffer), procinfo))
    (*proc)(lnr++, buffer);

实际上,如果 channel 上出现错误(与 EOF 不同),代码可能会进入无限循环; fgets() 会失败,但是 feof() 会返回 false(因为它还没有达到 EOF;它遇到了错误 - 请参阅 ferror( )),这样循环就会继续。不是一个特别合理的问题;如果文件打开,您很少会遇到错误。但是一个可能的问题。

关于c - 为什么这些 C 宏不写成函数呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7158716/

相关文章:

c++ - 设置了 OFN_ALLOWMULTISELECT 标志的 GetOpenFileName()

C执行时间

sql-server - 如果不指定端口号,ssms 无法连接到默认的 sql server 实例

linux - 用于在 Linux 中测试网络连接的自动化脚本

coding-style - 如何在 Xcode 6.1 中更改花括号样式?

c - 结构的指针算法

c - 我如何在其他文件中使用变量、函数和结构?

java - Hadoop namenode 不监听外部 IP

Java (Selenium WebDriver) - 如何编写紧凑的代码

c# - 关于 C# 风格的好书?