April 07, 2006 Re: On processors for D ~ decoupling | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> Ares currently uses fprintf for this purpose, which is essentially the same thing. And as you say, it would be easy enough to hook the function if this behavior isn't desirable.
>
> I'm glad the compiler issues came to light however. I don't suppose this will have any impact on the template code generation problem in libraries?
Unfortunately, no, as as I recall that is a limitation in the object file format.
|
April 07, 2006 Re: On processors for D ~ decoupling | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anders F Björklund | Anders F Björklund wrote:
> Sean Kelly wrote:
>
>>> Errors should be printed on stderr (fprintf), not on stdout (printf)...
>>
>> An easy change. Just use fprintf and specify stderr as the output file.
>
> For some reason this change has been rejected earlier. I don't know why.
> Just thought that if the file is revised, then maybe it can be included?
>
> http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/2001
> http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/4368
No idea. I do suggest using fprintf instead of fwritefln, but I can't think of a reason not to do this. I made the change to Ares quite a while ago.
Sean
|
April 07, 2006 Re: On processors for D ~ decoupling | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > > I know you're still bothered by the issue of C's IO being pulled in. I have another utility for you - \dm\bin\libunres. Libunres will identify any symbols unresolved by a library. For reference, here's the result of running this utility on the Ares version of the DMD GC and DMD runtime, respectively. The dependencies should be roughly equivalent to the appropriate portions of Phobos. Note that "_gc_*" "_thread_*" and "_on*" are defined by the GC or standard library: C:\bin\dmd\lib>libunres dmdgc.lib Unresolved externals: _D6object6Object5opCmpFC6ObjectZi _D6object6Object6toHashFZk _D6object6Object8opEqualsFC6ObjectZi _D6object6Object8toStringFZAa __Class_6Object __d_framehandler __d_local_unwind2 __d_monitorenter __d_monitorexit __end __except_list __imp__GetCurrentThreadId@0 __imp__VirtualAlloc@16 __imp__VirtualFree@12 __nullext __vtbl_9ClassInfo __xi_a _calloc _free _malloc _memcpy _memmove _memset _onOutOfMemory _realloc _thread_init _thread_needLock _thread_resumeAll _thread_scanAll _thread_suspendAll C:\bin\dmd\lib>libunres dmdrt.lib Unresolved externals: __Ccmp __Dmain __LCMP@ __LDIV@ __ModuleInfo_3std1c4math __ModuleInfo_3std1c5ctype __ModuleInfo_3std1c5stdio __ModuleInfo_3std1c6stdarg __ModuleInfo_3std1c6stddef __ModuleInfo_3std1c6stdlib __ModuleInfo_3std1c6string __ModuleInfo_3std1c7stdbool __ULDIV@ ___alloca ___fpclassify_d ___fpclassify_f ___fpclassify_ld __assert __except_list __fltused __global_unwind __imp__DeleteCriticalSection@4 __imp__EnterCriticalSection@4 __imp__InitializeCriticalSection@4 __imp__LeaveCriticalSection@4 __imp__QueryPerformanceCounter@4 __imp__QueryPerformanceFrequency@4 __imp__RaiseException@16 __iob __local_except_handler _calloc _exit _fclose _fgetc _fopen _fprintf _free _gc_calloc _gc_free _gc_init _gc_malloc _gc_realloc _gc_setFinalizer _gc_sizeOf _gc_term _isalpha _isgraph _isspace _malloc _memcmp _memcpy _memicmp _memmove _memset _onArrayBoundsError _onAssert _onOutOfMemory _onSwitchError _onUnicodeError _printf _qsort _sprintf _strlen _strtoul _strtoull _unmangle_ident The ModuleInfo dependencies could be eliminated by explicitly declaring forward references to the appropriate C routines instead of importing the D header modules. The remaining dependency list is really pretty minimal. I am somewhat surprised to see printf in there, though--I must have missed a "debug" prefix somewhere. Sean |
April 07, 2006 Re: On processors for D ~ decoupling | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> I am somewhat surprised to see printf in there, though--I must have missed a "debug" prefix somewhere.
Quick follow-up. All printf calls in the DMD runtime are either commented out or are prefixed by a debug qualifier. And the library was built without -debug set. Any ideas why it would be listed as a dependency? A grep of dmdrt.lib listed this:
._fprintf
._printf
._fprintf
._sprintf
so perhaps calling fprintf creates the other dependencies as well? I'll give the map a look and see if it ofers any clues.
Sean
|
April 07, 2006 Re: On processors for D ~ decoupling | ||||
---|---|---|---|---|
| ||||
Posted in reply to kris | kris wrote: > If you'll read the posts again, sans prejudice, I hope you'll find that they are about decoupling (like the title says). What I did is ask what is being coupled that needs decoupling, i.e. trying to drill down to find the *real* issue with printf and std.string.toString. I don't agree with the notion that printf and its 4K of code is in the same category as Java's entire runtime library. In other words, I do not agree with absolutes like "coupling is always bad." Each case should be looked at individually on its merits. For printf, the actual coupling problem is: 1) It pulls in floating point formatting code. This turns out to not be correct. 2) It's bloated. The bloat turns out to be 4K code - a big problem on an 8 bit machine to be sure, but not on a 32 bit one. 3) It pulls in the entire C I/O system. This turns out to also not be correct. It pulls in a reasonable portion of it. 4) It should be replaceable/hookable. Yes, it is. On the other hand, the advantages of having a print in Object are: 1) Every object can be relied upon to have some sort of print method. 2) Substituting a toString() is problematic because it usually requires extra allocation and hence double buffering - so most I/O systems avoid such designs. Also, the print is often used for debugging, and having it be forced to use an allocation can upset what one is trying to debug - by causing a gc collection cycle, for example. 3) It being synchronized with C's IO means it doesn't screw up when mixed with normal IO code. If printf pulled in a megabyte graphics library, sure, that's unreasonable coupling. But it doesn't. So, in my judgment, its benefits outweigh its disadvantages. You're free to disagree, but disagreement on a judgment call doesn't mean I or you are secretly convinced by the other's argument and lying about it. Let's look at the 'coupling' problem of typeinfo calling std.string.toString: 1) It's assumed to link in all of std.string, and everything std.string references. This is not correct. 2) std.string does pull in the floating point code, but this is a compiler problem and easily (and already in my working version) fixed. 3) There's another problem where it pulled in std.uni, but again, this is a compiler problem and easily fixed. So what std.string.toString actually pulls in (given the compiler fixes) is just std.string.toString and a few bytes of static data. So, in the end, the coupling turns out to be nonexistent. The assumption that calling one routine in a module brings in the entire module is not correct (and hasn't been since the late 80's). The proposed solution, calling C's itoa(), is problematic because it requires another allocation (itoa expects a 0 terminated string). Furthermore, itoa() is not a standard C function, so such dependency won't be portable. Writing another itoa unique to typeinfo kinda defeats the purpose of writing a library with reusable code. > You made it implicitly clear there was no way you'd consider isolating object.d from std.string in order to make the former more amenable to alternate libraries. Thus, that aspect was completely ignored also. No, I did not ignore it. I don't feel it's productive to rewrite the functions in std.string in each module. std.string is not a burdensome piece of code. Should I also rewrite memcpy() in every module? How far do you want to go to pursue decoupling for decoupling's sake? And suppose Fred discovers a way to double the speed of std.string.toString - pursuing your approach would mean none of the rest of the library would benefit from that. In my not-so-humble (!) opinion, when you're using copy/paste across modules, that's a red flag something is wrong with the design. I'll agree with you that pointless and gratuitous coupling should be avoided, but that is not the case with the two examples we're discussing. > Looking again at your recital of adamant examples, I'm rather sorry, and entirely disappointed that's all you got from this exchange. I used the word adamant because you haven't acknowledged that I've addressed the underlying __fltused and std.uni issues, you haven't acknowledged that they are solvable compiler issues rather than library design issues, and just keep pushing the same solution. > Yes, there's certainly truth there; but it apparently makes a point of purging all mention of decoupling ~ that's where frugality lies. I shall reiterate that what I was doing was addressing what the underlying issue with coupling was. If those can be successfully addressed, then there is no coupling issue. > You've again omitted a crucial part. The C runtime itself apparently has all kinds of interdependencies (the console startup/exit code is a prime example). I did not omit it. I addressed that in my last post. > Thus, the lists you show are simply the tip of the iceberg. I imagine you already know this quite intimately, so will suggest you do a step-by-step examination of the .map file for Derek's example: > > void main() {} > and ask yourself just why and where the kitchen-sink is linked? And as I've already told you, I've already done that and that there are good reasons for the code that is linked in. |
April 07, 2006 Re: On processors for D ~ decoupling | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> Quick follow-up. All printf calls in the DMD runtime are either commented out or are prefixed by a debug qualifier. And the library was built without -debug set. Any ideas why it would be listed as a dependency? A grep of dmdrt.lib listed this:
>
> ._fprintf
> ._printf
> ._fprintf
> ._sprintf
>
> so perhaps calling fprintf creates the other dependencies as well? I'll give the map a look and see if it ofers any clues.
You can see which module(s) is referencing them by using grep across the .obj files.
|
April 07, 2006 Re: On processors for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> Fredrik Olsson wrote:
>> And besides, is it wise to depend on what a linker "should do"? If current build chain nicely throws out what is not needed, does that make it right to assume that all build chains should behave as such?
>
> I think this is a reasonable assumption, as to do otherwise necessitates design compromises to keep modules as small and isolated as possible. And while this may be reasonable for small projects, I can't see it working very well for large ones.
This capability of linkers (eliminating unreferenced functions) first appeared in the late 80's, and quickly became standard practice. If you've got a linker that doesn't support that, you're likely to have many other serious problems with it, as D (and C++) depend on other linker features introduced in the late 80's.
D doesn't require anything of a linker that C++ doesn't already realistically require.
|
April 07, 2006 Re: On processors for D ~ decoupling | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright Attachments: | Walter Bright schrieb am 2006-04-06: > Although there is a lot of code in std.string, unreferenced free functions in it should be discarded by the linker. A check of the generated .map file should verify this - it is certainly supposed to work that way. That's not what is happening on Linux: > extern(C) int printf(char* x, ...){ > *(cast(char*)0) = 'a'; > } > > int main(){ > return 0; > } Symbols present in the executeable from std.string: _D3std6string10capitalizeFAaZAa _D3std6string10countcharsFAaAaZk _D3std6string10expandtabsFAaiZAa _D3std6string10splitlinesFAaZAAa _D3std6string11removecharsFAaAaZAa _D3std6string12replaceSliceFAaAaAaZAa _D3std6string15StringException5_ctorFAaZC3std6string15StringException _D3std6string2trFAaAaAaAaZAa _D3std6string3cmpFAaAaZi _D3std6string4atofFAaZe _D3std6string4atoiFAaZl _D3std6string4chopFAaZAa _D3std6string4findFAaAaZi _D3std6string4findFAawZi _D3std6string4icmpFAaAaZi _D3std6string4joinFAAaAaZAa _D3std6string4succFAaZAa _D3std6string4wrapFAaiAaAaiZAa _D3std6string5chompFAaAaZAa _D3std6string5countFAaAaZk _D3std6string5entabFAaiZAa _D3std6string5ifindFAaAaZi _D3std6string5ifindFAawZi _D3std6string5rfindFAaAaZi _D3std6string5rfindFAawZi _D3std6string5splitFAaAaZAAa _D3std6string5splitFAaZAAa _D3std6string5stripFAaZAa _D3std6string5zfillFAaiZAa _D3std6string6abbrevFAAaZHAaAa _D3std6string6centerFAaiZAa _D3std6string6columnFAaiZi _D3std6string6formatFYAa _D3std6string6insertFAakAaZAa _D3std6string6irfindFAaAaZi _D3std6string6irfindFAawZi _D3std6string6repeatFAakZAa _D3std6string6striplFAaZAa _D3std6string6striprFAaZAa _D3std6string7iswhiteFwZi _D3std6string7replaceFAaAaAaZAa _D3std6string7sformatFAaYAa _D3std6string7soundexFAaAaZAa _D3std6string7squeezeFAaAaZAa _D3std6string7toCharzFAaZPa _D3std6string7tolowerFAaZAa _D3std6string7toupperFAaZAa _D3std6string8capwordsFAaZAa _D3std6string8ljustifyFAaiZAa _D3std6string8rjustifyFAaiZAa _D3std6string8toStringFPaZAa _D3std6string8toStringFaZAa _D3std6string8toStringFcZAa _D3std6string8toStringFdZAa _D3std6string8toStringFeZAa _D3std6string8toStringFfZAa _D3std6string8toStringFgZAa _D3std6string8toStringFhZAa _D3std6string8toStringFiZAa _D3std6string8toStringFjZAa _D3std6string8toStringFkZAa _D3std6string8toStringFlZAa _D3std6string8toStringFlkZAa _D3std6string8toStringFmZAa _D3std6string8toStringFmkZAa _D3std6string8toStringFoZAa _D3std6string8toStringFpZAa _D3std6string8toStringFqZAa _D3std6string8toStringFrZAa _D3std6string8toStringFsZAa _D3std6string8toStringFtZAa _D3std6string8toStringFxZAa _D3std6string9inPatternFwAAaZi _D3std6string9inPatternFwAaZi _D3std6string9isNumericFAC8TypeInfoPvZx _D3std6string9isNumericFAaxZx _D3std6string9isNumericFYx _D3std6string9maketransFAaAaZAa _D3std6string9toStringzFAaZPa _D3std6string9translateFAaAaAaZAa dmd a.d -L--cref: internal/arraycat.d:101 current: > throw new Error(std.string.format("lengths don't match for array copy, > %s = %s", to.length, from.length)); suggested: > throw new Error("lengths don't match for array copy," ~ > toString(to.length) ~ " = " ~ toString(from.length)); Thomas |
April 07, 2006 Re: On processors for D ~ decoupling | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas Kuehne | Thomas Kuehne wrote: > Walter Bright schrieb am 2006-04-06: >> Although there is a lot of code in std.string, unreferenced free functions in it should be discarded by the linker. A check of the generated .map file should verify this - it is certainly supposed to work that way. > > That's not what is happening on Linux: ... > dmd a.d -L--cref: Should compile with -O -release to check this. > internal/arraycat.d:101 > current: >> throw new Error(std.string.format("lengths don't match for array copy, >> %s = %s", to.length, from.length)); > > suggested: >> throw new Error("lengths don't match for array copy," ~ >> toString(to.length) ~ " = " ~ toString(from.length)); Thanks, I'll do that. |
April 07, 2006 Re: On processors for D ~ decoupling | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
>
> You can see which module(s) is referencing them by using grep across the .obj files.
Thanks. Turns out it was a debug printf I'd left in place by accident.
Sean
|
Copyright © 1999-2021 by the D Language Foundation