On processors for D ~ decoupling

kris foo at bar.com
Thu Apr 6 23:01:36 PDT 2006


Walter Bright wrote:
> kris wrote:
> 
>> It would help if you'd note under what circumstances the TypeInfo /is/ 
>> included, then. For example, this program:
>>
>> void main()
>> {
>>         throw new Exception ("");
>> }
>>
>>
>> causes all kinds of TypeInfo to be linked:
> 
> 
> In general, an easy way to see why a particular module is being pulled 
> in is to temporarily remove it from the library (lib phobos -foo;), 
> link, and see where the undefined reference is coming from. I'd start by 
> running obj2asm on the module you just compiled, and see what extern 
> directives it puts out.
> 
> I'm not trying to be a jerk by telling you this procedure rather than 
> just giving the answer, but 1) I don't know the answer offhand and I'd 
> have to follow the same procedure to figure it out and 2) I hope that by 
> giving you the tools and methodology for figuring it out, this kind of 
> question won't repeatedly come up (and yes, it has come up repeatedly). 
> 3) I hope that anyone else with these kinds of questions will get 
> familiar with how to use these tools, too. It's a lot better than 
> guessing and assuming.
> 
> Tools like lib, obj2asm, and grep are incredibly useful.

Yes, they are useful. And I'm not trying to be a jerk by pointing out 
that the D runtime is missing some much needed TLC (to put it very 
nicely). Why do you think Ares exists anyway?


>> Where did all that come from? I suspect you're looking at this concern 
>> with a microscope only, while I think the bigger picture is perhaps 
>> more important.
> 
> 
> I don't think there is a bigger picture. There's only a case by case 
> analysis of what is needed and what isn't.

I see.


> All those other names are are the static data. Things like:
> 
> const dchar LS = '\u2028';      /// UTF line separator
> const dchar PS = '\u2029';      /// UTF paragraph separator
> 
> I submit that they aren't significant. 

Yes, you're right. Unless they're huge tables (such as the Unicode 
character map; oh wait; is that linked by default? :)


>> You're focusing purely on the fact that adding an itoa() would 
>> increase the executable size.
> 
> 
> Yes.
> 
>  > At the same time, completely ignoring the explicit
> 
>> mention of using the C runtime function instead (which is usually 
>> linked also), and the clear fact that importing std.string brings 
>> along with it the following:
> 
> 
> And the only possible problem I see there is worrying about executable 
> size.


Forgive me, but, there's a certain unattributed reputation for avoiding 
any and all important and/or salient points whenever it suits ~


>> And, apparently, you think it's perhaps responsible for bringing in 
>> the floating point support too.
> 
> 
> That is a problem, and I can fix that. No big deal - it wasn't printf 
> bringing in the floating point - and a reengineering or rewrite of 
> Phobos is not necessary. I don't even need to change any library source 
> code.


What's all this about necessary re-engineering and rewriting of Phobos? 
Where the heck did that come from?


>> The point being made is that of coupling between low and high levels ~ 
>> illustrated quite well by the above.
>> I think this kind of thing is worth addressing, for a number of reasons.
> 
> 
> I think you're seeing an effect that is an issue, but are mistaken as to 
> the cause of the problem.


I see low-level code being dependent upon high-level. I also see a large 
brick wall with an entirely unresponsive mason sitting atop.



> Again, it isn't necessarilly printf doing that. Try the code I posted in 
> the last message that stubs out printf, which will *prevent* it from 
> being linked in from the library. Compile/link it, and examine the .map 
> file.


Sigh. I did that last year, as you well know. After all, that's the 
reason you sent me the source code.


> Because it's not portable (what should the Linux one look like?), and 
> does not deliver the billed benefits. But the worst thing about calling 
> ConsoleWrite() directly is that it does not play well with any other IO 
> the user may have done or be in the process of doing. What will happen 
> is that any object.print()'s will not be synchronized with the output 
> from writef, printf, or any other of the stdout functions.


Fair point about the synchronization aspect. I'm glad you brought that up.

This is when library designers do one of two things: insert an indirect 
hook (like Sean has done in many places), or remove the functionality 
from that layer (again, like Sean has done). The worst possible thing to 
do is just leave it in there. It becomes part of the "legacy" and thus 
is impossible to remove cleanly at some future date; and it tends to 
negate reasonable attempts to clean up other similar concerns.

Heck, object.print() should probably be entirely removed anyway; the 
functionality provided is of dubious value, other than for some truly 
lazy and limited debugging; it caused enough concern that there was a 
general concensus to remove it, *or at least make it a null-op*, two 
years ago; and it's not even applied to any extent. The toString() 
method provides similar capability without the coupling issues. Again, 
it could simply become a null-op, or be removed. There's no reasonable 
balanced need for it to exist as it does today.

But then, why ever bother cleaning /anything/ up, when it won't make any 
difference anyway?


> Why does the C library need replacing? I honestly don't get it.

Who said it /needed/ replacing? I'm simply talking about applying a 
small sprinkling of decoupling dust


>> Why not just remove the dependency instead?
> 
> Because it doesn't buy anything to remove it. Try it and see (or even 
> easier, try the source I posted with the stubbed out printf - that will 
> absolutely, positively prevent printf from being linked in from the 
> library, without needing to change or recompile object.d at all).


You snipped what I thought a fair and appropriate analogy, so I'll 
repeat it:

"Take a shotgun, and pepper the boat you're standing in with holes. Now, 
see? When you plug up this one hole, it really doesn't stop the water 
coming in? See? Hardly any difference"

There /is/ a bigger picture here. One has to first see it, and then 
approach a resolution in small steps. Unfortunately the "it doesn't buy 
anything to remove it" outlook is entirely non-conducive to stepwise 
refinement. Nothing will ever get improved with that attitude.


> If you want to use a system that for some reason can't have C's IO 
> subsystem, then just include the one liner:
> 
> extern (C) int printf(char* f, ...) { return 0; }
> 
> somewhere in your code, and it's gone.


Forgive me, but that's just printf(). If I have, as you say, a system 
that can't have C's IO subsystem, the above will hardly help me at all. 
I suspect you're well aware the C IO subsystem consists of significantly 
more than just printf? Say, perhaps 50-ish functions? You're going to 
suggest I stub them all out just because Object.print() calls printf()?



> I'm trying to point out that things aren't so simple.


And I'm trying to point out just how simple it is to /start/ the process 
of eliminating questionable couplings that lead to Derek's sad example.



> Until you've tracked down each and every one and understand where it is 
> pulled in from and why it is there, there is no way to decide which ones 
> are superfluous or not.


There's rarely a need to do any of that when one is careful to decouple 
responsibilities.


> There's an awful lot of startup and shutdown going on - stuff that is 
> required for D (or the C runtime library, for that matter) to function. 
> An awful lot is required for the exception handling support to work - 
> that has to be in all programs. For the gc to start up and shut down 
> gracefully. It goes on.


Sure; that's a given. Yet it's also quite clear the D runtime links the 
kitchen-sink too. Given Derek's example:

void main() {}

The .map for that is a fine specimen of "unexpected" coupling. It does 
seem as though much of that is actually in the C library, but then 
you're arguing most fervently against doing anything to fix any such 
things.


>> Also, please keep in mind that the concern is one of unecessary 
>> coupling from the low-level runtime support, into the high-level 
>> library functions. This will often result in a cascade of 
>> dependencies, much like what we see below. Not only does it cause 
>> code-bloat, but it makes the language-support dependent upon a 
>> specific high-level library. These dependencies are /very/ easy to 
>> remedy, with an approriate reduction in code size as a bonus.
> 
> 
> As we've discovered, pulling printf out of object.d isn't going to 
> remedy anything. 

Sigh. I'm now at a complete loss at how to respond. Instead, I'll remind 
you what prompted this exercise in futility:

~~~~~~~~~~~~~~~~~~~~

Walter Bright wrote:
 > Phobos doesn't require floating point support from the processor
 > unless one actually uses floating point in the application code.

That turned out to be somewhat less than truthful.

 > I also really don't understand why anyone using D would require
 > not using Phobos. What's the problem?

With much respect, the 'problem' is perhaps that you don't see any?





More information about the Digitalmars-d-announce mailing list