A forward declaration is not really a compile time dependency.
If you are forward declaring a function, you are just promising that it is present during linking. So, during compilation it is not an edge in the graph.
If you are forward declaring a data type such as a class, a full definition needs to be visible at its first use or you are using the type as a pointer:
class A;
class B {
A *d_a;
[...]
};
In this case it is not really a dependency either, since the compiler does not need to know the size of A, since d_a is a pointer. When you start to dereference d_a, its definition needs to be fully visible, which is done via headers, which are a DAG through guards.
Could you give an example where C++ dependencies are not a DAG during compilation?
Yes, but it is still a dependency. By which I mean the software won't run if you don't supply the necessary thing at resolution time (which is possibly quite late: well into runtime, if you are on a system with lazy linking). Go (and some other languages, like OCaml) enforces that such dependencies form a DAG: C++ does not.
I don't think this has much to do with compilation speed though.
If you are forward declaring a function, you are just promising that it is present during linking. So, during compilation it is not an edge in the graph.
If you are forward declaring a data type such as a class, a full definition needs to be visible at its first use or you are using the type as a pointer:
In this case it is not really a dependency either, since the compiler does not need to know the size of A, since d_a is a pointer. When you start to dereference d_a, its definition needs to be fully visible, which is done via headers, which are a DAG through guards.Could you give an example where C++ dependencies are not a DAG during compilation?