www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - code coverage and module constructors

reply BCS <BCS pathlink.com> writes:
	If two modules mutually import each other, you can't use code coverage 
on both of them. This is (I think) because the code coverage is 
implemented with some sort of module constructor and generate a loop 
(static this in mod-a must be run before the static this in mod-b which 
must be run before the static this in mod-a ...).

	However this is bunk, -cov for one module shouldn't have any 
dependencies on any other module. D already has one case where a module 
constructor like thing is use that doesn't care about circular imports, 
unittests. Why then isn't the cov startup run the same way?
Jun 19 2006
parent reply kris <foo bar.com> writes:
BCS wrote:
     If two modules mutually import each other, you can't use code 
 coverage on both of them. This is (I think) because the code coverage is 
 implemented with some sort of module constructor and generate a loop 
 (static this in mod-a must be run before the static this in mod-b which 
 must be run before the static this in mod-a ...).
 
     However this is bunk, -cov for one module shouldn't have any 
 dependencies on any other module. D already has one case where a module 
 constructor like thing is use that doesn't care about circular imports, 
 unittests. Why then isn't the cov startup run the same way?

Yeah .... -cov simply highlights the problem if cyclic imports with static-ctors; simply becuase -cov injects a static-ctor into each module (or something like that). On the other hand, cyclic imports are kinda "poor form" - for want of a better description. You *can* eliminate them, potentially using an interface as an intermediary; and probably *should* eliminate them. Of course, that doesn't help when there's cyclic imports all over the library code that one happens to be using (the Win32 headers?). I understand where you're coming from on this, and wholly sympathise since I recently had to redesign a few substantial chunks of code to eliminate the problem. However, I suspect the end-result of my effort was worth it. Hope that doesn't muddy the waters too much?
Jun 19 2006
parent reply BCS <BCS pathlink.com> writes:
kris wrote:
 BCS wrote:
 
     If two modules mutually import each other, you can't use code 
 coverage on both of them. This is (I think) because the code coverage 
 is implemented with some sort of module constructor and generate a 
 loop (static this in mod-a must be run before the static this in mod-b 
 which must be run before the static this in mod-a ...).

     However this is bunk, -cov for one module shouldn't have any 
 dependencies on any other module. D already has one case where a 
 module constructor like thing is use that doesn't care about circular 
 imports, unittests. Why then isn't the cov startup run the same way?

On the other hand, cyclic imports are kinda "poor form" - for want of a better description. You *can* eliminate them, potentially using an interface as an intermediary; and probably *should* eliminate them.

Why are they poor form? (This is a non-rhetorical question, I would like to hear your reasoning.) Putting all your types off by them selves in there own modules can help some. But what about, say, a pair of structs that have methods that take each other as arguments but otherwise have no reason to be in the same module? e.g. struct foo { ... void UseBar(bar b){...} } struct bar { ... void UseFoo(foo f){...} } And interfaces cause a bit of a performance hit (they are bigger for one). Even if this can be eliminated in most cases. Sooner or later it won't be practical or desirable to do it. I would list this as a high priority item on the to list, right below getting -cov working.
 Of
 course, that doesn't help when there's cyclic imports all over the 
 library code that one happens to be using (the Win32 headers?).
 
 I understand where you're coming from on this, and wholly sympathise 
 since I recently had to redesign a few substantial chunks of code to 
 eliminate the problem. 

<nods> I've just lived without static constructors some times.
 However, I suspect the end-result of my effort was worth it.
 
 Hope that doesn't muddy the waters too much?

Jun 19 2006
parent kris <foo bar.com> writes:
BCS wrote:
 kris wrote:

 On the other hand, cyclic imports are kinda "poor form" - for want of 
 a better description. You *can* eliminate them, potentially using an 
 interface as an intermediary; and probably *should* eliminate them.

Why are they poor form? (This is a non-rhetorical question, I would like to hear your reasoning.) Putting all your types off by them selves in there own modules can help some. But what about, say, a pair of structs that have methods that take each other as arguments but otherwise have no reason to be in the same module?

Well, my little gripe with cyclic imports is that they tend to tighly-couple implementation details. That's very much a design-dependent measure, so it's a bit airy fairy for most purposes. For example, some designs are intended to be tightly-coupled. One the other hand, there's something to be said for a large body of code that can be cleanly represented as a DAG (no cycles). Tends to make the overall system a whole lot easier to extend, easier to decouple as necessary, and so on. I suppose it's all about maintenance? Maybe a whiff of 'elegance'? Maybe not. [snip]
 I understand where you're coming from on this, and wholly sympathise 
 since I recently had to redesign a few substantial chunks of code to 
 eliminate the problem. 

<nods> I've just lived without static constructors some times.

Yeah ... in my case, I had to get a fairly substantial library working with -cov, since it would seem rather bogus for a lib to conflict in that respect. Don't want to get off topic too much, but I found Dimple to be a true bobsend for visualizing import-relationships over a large (200+) swathe of modules. I've also discovered that attempts to make the diagrams look 'cleaner' (through refactoring) have an equally pleasant effect on the codebase design itself :)
Jun 19 2006