代码之家  ›  专栏  ›  技术社区  ›  Jonathan Leffler

源文件中的代码排序-转发声明与“不要重复自己”?[关闭]

  •  4
  • Jonathan Leffler  · 技术社区  · 17 年前

    如果在C中进行代码配置,并配置编译器以坚持在使用它们之前声明所有函数(或者在C++中进行编码),那么最终可以使用至少两个用于源文件的组织。

    要么:

    • 报头
    • 转发此文件中(静态)函数的声明
    • 外部功能(主要入口点)
    • 静态-非公共-功能

    或:

    • 报头
    • 静态-非公共-功能
    • 外部功能(主要入口点)

    我认识到,在C++中,“static”一词不是首选,但我主要是C程序员,而C++中存在等价概念,即文件中的匿名命名空间中的函数。

    问题:

    • 你使用哪个组织,为什么你更喜欢它?

    作为参考,我自己的代码使用第二种格式,这样在使用静态函数之前就定义了它们,这样就不需要同时声明和定义它们,这样就节省了两次写出有关函数接口的信息——反过来,当内部接口需要改变。其缺点是文件中定义的第一个函数是最低级别的例程——由文件后面定义的函数调用的例程——因此,它更接近文件的底部,而不是顶部有最重要的代码。这对你有多重要?

    我假设所有外部可访问的函数都在头中声明,并且这种形式的重复是必要的——我认为这不应该引起争议。

    6 回复  |  直到 17 年前
        1
  •  3
  •   Adam Hawes    17 年前

    在C代码中,我使用一个简单的规则:

    • 具有非静态成员的每个C文件都将具有定义这些成员的相应头文件。

    这在过去对我来说非常有效-这使得查找函数定义变得足够容易,因为如果我需要查找它,它在同一个名为.h的文件中。它也适用于doxygen(我的首选工具),因为所有的cruft都保存在头文件中,我大部分时间都不在头文件中—C文件中充满了代码。

    对于文件中的静态成员,我坚持以这样的方式对声明进行排序,即在使用声明之前通过实例化定义声明。而且,我几乎总是避免函数调用中的循环依赖。

    对于C++代码,我尝试如下:

    • 头文件中定义的所有代码。使用pragma interface/pragma实现通知编译器;类似于模板将所有代码放在头中的方式。

    在C++中,这对我来说是非常好的。这意味着最终会有大量的头文件,在某些情况下会增加编译时间。最后,您还可以使用一个C++主体文件,其中只包含头并编译。您可以在这里实例化静态成员变量。这也成为了一个噩梦,因为更改方法参数和破坏代码太容易了。

    我搬到了

    • 包含doxygen注释的头文件(模板除外,其中代码必须包含在头文件中)和完整的正文文件,但短方法除外,我知道在使用时我更喜欢使用内联方法。

    将实现与定义分离有一个独特的优点,即更难更改方法/函数签名,因此您不太可能这样做并破坏事物。它还意味着我可以在头文件中有大量的doxygen块来记录代码中的工作方式和工作方式,除了一些有用的注释,比如“declare a variable called i”(tough in chick)。

    ADA强制您使用约定和文件命名方案。大多数动态语言(如Ruby、Python等)通常不关心在何处/是否声明内容。

        2
  •  6
  •   Robert Gamble    17 年前

    我一直使用方法1,原因是我喜欢能够快速判断在特定文件中定义了哪些函数,并在一个地方看到它们的签名。我不认为必须随函数定义一起更改原型的论点特别有说服力,因为您通常最终会更改调用已更改函数的所有代码,而在更改函数原型的过程中,更改函数原型似乎相对来说是微不足道的。

        3
  •  2
  •   Darius Bacon    17 年前

    第二:因为我编写了许多短函数并对它们进行自由重构,所以维护前向声明会非常麻烦。如果有一个Emacs扩展可以为您做到这一点而不必大惊小怪的话,我会感兴趣的,因为自上而下的组织更易于阅读。(我更喜欢自上而下的,例如python。)

    实际上不完全是您的数字2,因为我通常在.c中将相关函数分组在一起,不管它们是公共的还是私有的。如果我想查看所有的公开声明,我将在标题中查找。

        4
  •  2
  •   EvilTeach    17 年前

    给我2号。

    我认为使用静态或其他方法使模块函数和变量对模块私有是一个很好的实践。

    我更喜欢将API函数放在模块的底部。相反,我将API函数放在类的顶部,因为类通常是可重用的。把api函数放在最上面可以更容易地快速找到它们。大多数IDE都可以直接带您访问任何函数。

        5
  •  1
  •   Giacomo    17 年前

    (谈论C代码)

    第二个是我,因为我 总是 忘记更新forward decls以反映静态函数的更改。

    但我认为最好的做法应该是

    • 报头
    • 转发声明+对每个声明的函数行为的注释
    • 导出的函数+代码不够清晰时有关实现细节的最终注释
    • 静态函数+关于实现细节的最终注释
        6
  •  0
  •   Community Mohan Dere    9 年前

    这对你有多重要?

    不是这样。

    所有本地函数都必须标记为 static 但是对于我来说,在文件中定义如何分组函数太多了。任何版本都没有强有力的理由,我也从来没有发现过任何强有力的缺点。

    一般来说,编码约定是非常重要的,我们试图尽可能多地定义,但在这种情况下,我觉得这是不合理的开销。

    在重新阅读了所有的帖子之后,我似乎应该简单地投赞成票(我确实投了赞成票)。 Darius 回答,而不是写下所有这些…