Google样式指南(正向分节) [英] Google Style Guide (Section Forward Decleration)

查看:142
本文介绍了Google样式指南(正向分节)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

序言

《 Google风格指南》中列出了一些前向声明的缺点

The Google Style Guide includes a list of disadvantages of forward declaration

  1. 转发声明可以隐藏依赖项,从而允许用户代码在标头更改时跳过必要的重新编译.

通过对库的后续更改可能会破坏前向声明.函数和模板的前向声明可以防止标头所有者对其API进行其他兼容的更改,例如扩展参数类型,添加具有默认值的模板参数或迁移到新的命名空间.

A forward declaration may be broken by subsequent changes to the library. Forward declarations of functions and templates can prevent the header owners from making otherwise-compatible changes to their APIs, such as widening a parameter type, adding a template parameter with a default value, or migrating to a new namespace.

从命名空间std ::转发声明符号会产生未定义的行为.

Forward declaring symbols from namespace std:: yields undefined behavior.

很难确定是否需要前向声明或完整的#include.用前向声明替换#include可以静默更改代码的含义:

It can be difficult to determine whether a forward declaration or a full #include is needed. Replacing an #include with a forward declaration can silently change the meaning of code:

代码:

  // b.h:
  struct B {};
  struct D : B {};

  // good_user.cc:
  #include "b.h"
  void f(B*);
  void f(void*);
  void test(D* x) { f(x); }  // calls f(B*)
 

如果将#include替换为B和D的正向decl,则test()将调用f(void *).

If the #include was replaced with forward decls for B and D, test() would call f(void*).

  1. 从头文件中声明多个符号比仅#include头文件更冗长.

  1. Forward declaring multiple symbols from a header can be more verbose than simply #includeing the header.

结构化代码以启用前向声明(例如,使用指针成员而不是对象成员)可以使代码更慢,更复杂.

Structuring code to enable forward declarations (e.g. using pointer members instead of object members) can make the code slower and more complex.

问题

我对第一点特别感兴趣,因为我无法提出一个单一方案,即当标头更改时,前向decle会跳过必要的重新编译.谁能告诉我这是怎么发生的?还是这是Google代码库所固有的?

I am particulary interested in the first point, as I cannot come up with a single scenario, where a forward decleration would skip necessary recompilation when headers change. Can anybody tell me how this can happen? Or is this something intrinsic to the google code base?

由于这是列表上的第一点,因此它似乎也很重要.

As this is the first point on the list it also seems rather important.

推荐答案

我无法提出一个单一的方案,即当标头更改时,前向声明会跳过必要的重新编译.

我认为这也不太清楚,也许措辞可能更清楚.

I think this is a bit unclear too, and perhaps could be worded a little more clearly.

隐藏依赖项是什么意思?

What could it mean for a dependency to be hidden?

假设您的文件main.cc需要header.h才能正确构建.

Let’s say your file main.cc needs header.h in order to be built correctly.

  • 如果main.cc包含header.h,则这是直接依赖项.

  • If main.cc includes header.h, then this is a direct dependency.

如果main.cc包含lib.h,然后lib.h包含header.h,则这是间接依赖.

If main.cc includes lib.h, and then lib.h includes header.h, then this is an indirect dependency.

如果main.cc某种程度上依赖于lib.h,但是如果不包含lib.h却不生成生成错误,那么我可以称其为 hidden 依赖项.

If main.cc somehow depends on lib.h but does not generate a build error if lib.h is not included, then I might call this a hidden dependency.

我不认为 hidden 这个字眼是一个平常的名词,因此,我同意可以完善或扩展该措词.

I don’t think the word hidden is a commonplace term for this, however, so I agree that the wording could be refined or expanded.

我有main.clib.htypes.h.

这里是main.c:

#include "lib.h"
void test(D* x) { f(x); }

这里是lib.h:

#include "types.h"
void f(B*);
void f(void*);

这里是types.h:

struct B {};
struct D : B {};

现在,main.cc取决于types.h,以便生成正确的代码.但是,main.cc仅直接依赖于lib.h,它具有 hidden 依赖于types.h.如果我在lib.h中使用前向声明,则这会破坏main.cc.但是main.cc仍然可以编译!

Now, main.cc depends on types.h in order to generate the correct code. However, main.cc only has a direct dependency on lib.h, it has a hidden dependency on types.h. If I use forward declarations in lib.h, then this breaks main.cc. And yet main.cc still compiles!

main.cc中断的原因是,即使main.cc取决于types.h中的声明,它也不包含types.h.前向声明使之成为可能.

And the reason that main.cc breaks is because it does not include types.h, even though main.cc depends on the declarations in types.h. Forward declarations make this possible.

这篇关于Google样式指南(正向分节)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆