www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - * Win32 issues with Templates and Libs *

reply kris <foo bar.com> writes:
dmd on Win32 has recently become much better at handling Templates and 
libs, but it still has some issues. I got lucky and isolated one of 
them, listed below:

Two modules, one called test.d and the other tester.d -- add test.d to a 
library called test.lib, and then compile+link tester.d against said 
lib. You should get a correctly linked app that runs and emits "hello".

============
module test;

extern (C) int printf (char*, ...);

class Test (T)
{
         final void show (T[] msg)
         {
                 printf ("%.*s\n", msg);
         }
}

//Test!(char) Global;
==========


==========
module tester;

pragma (lib, "test.lib");

import test;

void main()
{
         auto t = new Test!(char);
         t.show ("hello");
}
==========

Now, remove the comment in test.d so that 'Global' is exposed, and 
rebuild the lib. You should now get linker errors of this nature:

dmd tester

OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved tester.obj(tester) Error 42: Symbol Undefined _D4test11__T4TestTaZ4Test7__ClassZ tester.obj(tester) Error 42: Symbol Undefined _D4test11__T4TestTaZ4Test4showMFAaZv --- errorlevel 2 This error does not occur with dmd on linux, nor when using GDC on any supported platform that we've tried. It's only the dmd/Win32 combination Please can we have this fixed soon?
Feb 19 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
The problem is that one of two kinds of COMDAT sections can be generated:

1) Only one COMDAT with a particular name may appear
2) Any number of COMDATs with the same name may appear, pick one and 
discard the others

Instantiating a template produces a COMDAT section. Since multiple 
modules may instantiate a template with the same arguments, without 
knowing about each other, option (2) is used.

When a module is put into a library, a dictionary is created for the 
library, essentially an associative array of object modules indexed by 
symbol names. COMDATs of option (1) get put into the dictionary, ones of 
option (2) do not. Why not? Because if there's more than one of (2), 
which object module do you pull in? No way to tell.

Thus, the problem you're seeing. The solution is:

1) have another global in module test that gets pulled in, thus also 
pulling the COMDAT along with it, and resolving the symbol.

2) explicitly link in module test

So, you might ask, why not just regenerate the template instantiation 
every time you use it? Because it would lead to a lot of object file bloat.
Feb 20 2007
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Mmm... yummy technical details :P

There seem to be quite a few problems/annoyances due to limitations in
the object file formats.  It makes one wonder whether it wouldn't be a
good idea to simply make a new one that properly supported D's feature
set...

Of course, that would involve touching OPTLINK, something I gather no
one is particularly keen on :P

	-- Daniel

Walter Bright wrote:
 The problem is that one of two kinds of COMDAT sections can be generated:
 
 1) Only one COMDAT with a particular name may appear
 2) Any number of COMDATs with the same name may appear, pick one and
 discard the others
 
 Instantiating a template produces a COMDAT section. Since multiple
 modules may instantiate a template with the same arguments, without
 knowing about each other, option (2) is used.
 
 When a module is put into a library, a dictionary is created for the
 library, essentially an associative array of object modules indexed by
 symbol names. COMDATs of option (1) get put into the dictionary, ones of
 option (2) do not. Why not? Because if there's more than one of (2),
 which object module do you pull in? No way to tell.
 
 Thus, the problem you're seeing. The solution is:
 
 1) have another global in module test that gets pulled in, thus also
 pulling the COMDAT along with it, and resolving the symbol.
 
 2) explicitly link in module test
 
 So, you might ask, why not just regenerate the template instantiation
 every time you use it? Because it would lead to a lot of object file bloat.

-- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Feb 20 2007
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message 
news:eret4n$2ors$1 digitalmars.com...
 Mmm... yummy technical details :P

 There seem to be quite a few problems/annoyances due to limitations in
 the object file formats.  It makes one wonder whether it wouldn't be a
 good idea to simply make a new one that properly supported D's feature
 set...

That would be awesome. If D compilers could still generate some kind of "standard" object file for linking with other languages, and then a "D object" for D compilers that had extra features. The D object format could even be standardized and made sure to be compatible across D compilers (something C++ sure can't promise!). I always thought it would be cool if templates were sort of .. compiled almost into a scripting language intermediate representation. Then, to instantiate a template, either one it just compiled or one it loaded from a D object, the compiler would just interpret the script. This way a generic "how to instantiate template X" would be stored in the object file, and you wouldn't need the original definition. This is probably a lot of work though.
 Of course, that would involve touching OPTLINK, something I gather no
 one is particularly keen on :P

Phh, if it means getting away from OMF, I'm all for it ;)
Feb 20 2007
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 The problem is that one of two kinds of COMDAT sections can be generated:
 
 1) Only one COMDAT with a particular name may appear
 2) Any number of COMDATs with the same name may appear, pick one and 
 discard the others
 
 Instantiating a template produces a COMDAT section. Since multiple 
 modules may instantiate a template with the same arguments, without 
 knowing about each other, option (2) is used.
 
 When a module is put into a library, a dictionary is created for the 
 library, essentially an associative array of object modules indexed by 
 symbol names. COMDATs of option (1) get put into the dictionary, ones of 
 option (2) do not. Why not? Because if there's more than one of (2), 
 which object module do you pull in? No way to tell.

Let's back up for a second. First, in the situation Kris mentioned, how many instances of Test!(char) exist altogether? I had expected there to be two: one in test.lib and one in tester.obj. But in this case I wouldn't expect the link error to occur, so perhaps you're saying that when the compiler sees "Test!(char) Global" in module test, it doesn't bother to create one in tester.obj? Also, how do COMDATs differ from normal code blocks? ie. Why is the linker able to resolve normal symbols in libraries but not templates? Wouldn't the symbol name in both cases be enough to sort things out?
 Thus, the problem you're seeing. The solution is:
 
 1) have another global in module test that gets pulled in, thus also 
 pulling the COMDAT along with it, and resolving the symbol.
 
 2) explicitly link in module test
 
 So, you might ask, why not just regenerate the template instantiation 
 every time you use it? Because it would lead to a lot of object file bloat.

I guess this answers my question above: the compiler sees "Test!(char) Global" and doesn't bother to create another instance of the code. But surely being able to create a functional application is preferable in this case. Won't an optimizing linker throw out duplicates anyway? Who cares if the object files are bloated, if that's the only workable option here? Or perhaps this suggests the need for a D linker that builds a catalog of symbols inside libraries before linking instead of the behavior you describe above? Sean
Feb 20 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
Sean Kelly wrote:
 Let's back up for a second.  First, in the situation Kris mentioned, how 
 many instances of Test!(char) exist altogether?

One.
 I had expected there to 
 be two: one in test.lib and one in tester.obj.  But in this case I 
 wouldn't expect the link error to occur, so perhaps you're saying that 
 when the compiler sees "Test!(char) Global" in module test, it doesn't 
 bother to create one in tester.obj?

That's right.
 Also, how do COMDATs differ from normal code blocks?

COMDATs are each placed in their own segment.
 ie. Why is the 
 linker able to resolve normal symbols in libraries but not templates? 

Because normal symbols cannot appear multiple times (if they did, you get multiple definition errors at link time).
 Wouldn't the symbol name in both cases be enough to sort things out?

No.
 I guess this answers my question above: the compiler sees "Test!(char) 
 Global" and doesn't bother to create another instance of the code.  But 
 surely being able to create a functional application is preferable in 
 this case.  Won't an optimizing linker throw out duplicates anyway?

The problem is not knowing which module to link in - after all, there are (possibly) other global symbols in the module.
 Who 
 cares if the object files are bloated, if that's the only workable 
 option here?

You'll care <g> once templates get complex enough. It's been a big problem with C++.
 Or perhaps this suggests the need for a D linker that 
 builds a catalog of symbols inside libraries before linking instead of 
 the behavior you describe above?

Building a linker or object file with non-standard semantics has its own set of problems.
Feb 20 2007
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 Who cares if the object files are bloated, if that's the only workable 
 option here?

You'll care <g> once templates get complex enough. It's been a big problem with C++.

I'd prefer bloated object files over link errors as well... Perhaps a command-line option could be added to emit templates in situations like this, so object files don't increase in size because of this unless necessary?
Feb 20 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
Frits van Bommel wrote:
 Walter Bright wrote:
 You'll care <g> once templates get complex enough. It's been a big 
 problem with C++.

I'd prefer bloated object files over link errors as well... Perhaps a command-line option could be added to emit templates in situations like this, so object files don't increase in size because of this unless necessary?

My experience with those command line options is almost nobody is able to use them successfully. (They were used in the early days of C++ before COMDATs.)
Feb 20 2007
parent reply Pragma <ericanderton yahoo.removeme.com> writes:
Walter Bright wrote:
 Frits van Bommel wrote:
 Walter Bright wrote:
 You'll care <g> once templates get complex enough. It's been a big 
 problem with C++.

I'd prefer bloated object files over link errors as well... Perhaps a command-line option could be added to emit templates in situations like this, so object files don't increase in size because of this unless necessary?

My experience with those command line options is almost nobody is able to use them successfully. (They were used in the early days of C++ before COMDATs.)

That raises an interesting question: seeing as how it's using the same backend, how does DMC handle this problem for C++? -- - EricAnderton at yahoo
Feb 20 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
Pragma wrote:
 That raises an interesting question: seeing as how it's using the same 
 backend, how does DMC handle this problem for C++?

Unlike D, a C++ compiler has no idea what templates are instantiated in other files. So it instantiates everything. This is one reason why C++ builds are so much slower than D.
Feb 20 2007
next sibling parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
Walter Bright wrote:

 Pragma wrote:
 That raises an interesting question: seeing as how it's using the same
 backend, how does DMC handle this problem for C++?

Unlike D, a C++ compiler has no idea what templates are instantiated in other files. So it instantiates everything. This is one reason why C++ builds are so much slower than D.

Shouldn't this reasoning make it easier to provide working and efficient template instances together with libs in D? Also, on the topic of OMF, you suggested once that OMF was a better format than ELF? I've yet to see any justification for such a claim, currently it looks a tad behind the times. -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Feb 20 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
Lars Ivar Igesund wrote:
 Also, on the topic of OMF, you suggested once that OMF was a better format
 than ELF? I've yet to see any justification for such a claim, currently it
 looks a tad behind the times.

Elf has its problems, too.
Feb 20 2007
parent Lars Ivar Igesund <larsivar igesund.net> writes:
Walter Bright wrote:

 Lars Ivar Igesund wrote:
 Also, on the topic of OMF, you suggested once that OMF was a better
 format than ELF? I've yet to see any justification for such a claim,
 currently it looks a tad behind the times.

Elf has its problems, too.

That may be so, but according to D lore/rumours, it is actually working in all cases, and on all platforms (in the sense that it isn't a factor in hindering adoption to a given platform). According to your descriptions of the problematics in the template/lib scene, OMF is one of the offending problem areas. According to you, it can't properly handle all use cases of D as a programming language. I have yet to see an example where ELF produce similar problems (or even anyone at all) when using D. It used to be that D was considered to have second rate support on non-Win32 platforms, but I now mostly feel sorry for those users that need to use that platform for D development (The mess that is DLL is M$ fault, I won't blame Digital Mars for that ;). Of course, helping out on projects that want to be crossplatform, I feel the frustration by proxy. -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Feb 21 2007
prev sibling parent reply James Dennett <jdennett acm.org> writes:
Walter Bright wrote:
 Pragma wrote:
 That raises an interesting question: seeing as how it's using the same
 backend, how does DMC handle this problem for C++?

Unlike D, a C++ compiler has no idea what templates are instantiated in other files. So it instantiates everything. This is one reason why C++ builds are so much slower than D.

It's fairly common for C++ compilers to use some kind of storage to record which templates are instantiated from which files, and has been for quite a few years. -- James
Feb 20 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
James Dennett wrote:
 Walter Bright wrote:
 Pragma wrote:
 That raises an interesting question: seeing as how it's using the same
 backend, how does DMC handle this problem for C++?

other files. So it instantiates everything. This is one reason why C++ builds are so much slower than D.

It's fairly common for C++ compilers to use some kind of storage to record which templates are instantiated from which files, and has been for quite a few years.

Yeah, I've considered building such a thing. But it would be complex, and the programmer would have to accommodate its idiosyncracies. Better off fixing the language to support proper modules.
Feb 21 2007
next sibling parent Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 James Dennett wrote:
 Walter Bright wrote:
 Pragma wrote:
 That raises an interesting question: seeing as how it's using the same
 backend, how does DMC handle this problem for C++?

other files. So it instantiates everything. This is one reason why C++ builds are so much slower than D.

It's fairly common for C++ compilers to use some kind of storage to record which templates are instantiated from which files, and has been for quite a few years.

Yeah, I've considered building such a thing. But it would be complex, and the programmer would have to accommodate its idiosyncracies. Better off fixing the language to support proper modules.

For what it's worth, module support has been removed from the list of features slated for C++ 0x. They ran out of time. Sean
Feb 21 2007
prev sibling parent James Dennett <jdennett acm.org> writes:
Walter Bright wrote:
 James Dennett wrote:
 Walter Bright wrote:
 Pragma wrote:
 That raises an interesting question: seeing as how it's using the same
 backend, how does DMC handle this problem for C++?

other files. So it instantiates everything. This is one reason why C++ builds are so much slower than D.

It's fairly common for C++ compilers to use some kind of storage to record which templates are instantiated from which files, and has been for quite a few years.

Yeah, I've considered building such a thing. But it would be complex, and the programmer would have to accommodate its idiosyncracies. Better off fixing the language to support proper modules.

You may well be right; while I've seen such systems work well most of the time, they usually need help if your build structure is not simple (for example, if you build multiple different libraries based on overlapping sets of object files). -- James
Feb 21 2007
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 
 Who cares if the object files are bloated, if that's the only workable 
 option here?

You'll care <g> once templates get complex enough. It's been a big problem with C++.
 Or perhaps this suggests the need for a D linker that builds a catalog 
 of symbols inside libraries before linking instead of the behavior you 
 describe above?

Building a linker or object file with non-standard semantics has its own set of problems.

Thanks for the reply. Your proposed solution finally reminded me that we had this exact conversation a few years ago :-) It's a nasty hack, but what if the compiler performed your proposed solution during compilation:
 1) have another global in module test that gets pulled in, thus also
 pulling the COMDAT along with it, and resolving the symbol.

In modules containing global template instances, generate a symbol, let's say _Dforcelink, which is implicitly referenced in importing modules. Is this possible? Sean
Feb 20 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
Sean Kelly wrote:
 Thanks for the reply.  Your proposed solution finally reminded me that 
 we had this exact conversation a few years ago :-)  It's a nasty hack, 
 but what if the compiler performed your proposed solution during 
 compilation:
 
  > 1) have another global in module test that gets pulled in, thus also
  > pulling the COMDAT along with it, and resolving the symbol.
 
 In modules containing global template instances, generate a symbol, 
 let's say _Dforcelink, which is implicitly referenced in importing 
 modules.  Is this possible?

What happens if you have two such modules in a library?
Feb 20 2007
parent Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 Thanks for the reply.  Your proposed solution finally reminded me that 
 we had this exact conversation a few years ago :-)  It's a nasty hack, 
 but what if the compiler performed your proposed solution during 
 compilation:

  > 1) have another global in module test that gets pulled in, thus also
  > pulling the COMDAT along with it, and resolving the symbol.

 In modules containing global template instances, generate a symbol, 
 let's say _Dforcelink, which is implicitly referenced in importing 
 modules.  Is this possible?

What happens if you have two such modules in a library?

Oops... the name would have to be mangled to include the module name. I suppose this still raises issues for some corner-cases, but it's all I can think of. Sean
Feb 20 2007
prev sibling parent "Kristian Kilpi" <kjkilpi gmail.com> writes:
On Tue, 20 Feb 2007 20:46:39 +0200, Walter Bright  
<newshound digitalmars.com> wrote:
 Sean Kelly wrote:
 Let's back up for a second.  First, in the situation Kris mentioned,  
 how many instances of Test!(char) exist altogether?

One.
 I had expected there to be two: one in test.lib and one in tester.obj.   
 But in this case I wouldn't expect the link error to occur, so perhaps  
 you're saying that when the compiler sees "Test!(char) Global" in  
 module test, it doesn't bother to create one in tester.obj?

That's right.

For a person which doesn't know how linkers and object files work, this seems to be an 'interesting' problem. <g> I mean, there is an instance of Test!(char) in test.lib, but the linker doesn't found it because there might be another instance in another object file? And at the same time, the compiler tries to ensure that there will be only one instance of Test!(char)... What will be the number of instances of Test!(char) if test.d does not contain 'Test!(char) Global;', and I have another module tester2.d, similar to tester.d, which also uses the Test!(char) class? I except two, one for tester.d and one for tester2.d. That is, at least, when the files are compiled independently. And if the compiler would be smart enough to create only one instance in that case, doesn't it mean the same linker error will occur then too?
Feb 20 2007
prev sibling parent reply kris <foo bar.com> writes:
Walter Bright wrote:
 The problem is that one of two kinds of COMDAT sections can be generated:
 
 1) Only one COMDAT with a particular name may appear
 2) Any number of COMDATs with the same name may appear, pick one and 
 discard the others
 
 Instantiating a template produces a COMDAT section. Since multiple 
 modules may instantiate a template with the same arguments, without 
 knowing about each other, option (2) is used.
 
 When a module is put into a library, a dictionary is created for the 
 library, essentially an associative array of object modules indexed by 
 symbol names. COMDATs of option (1) get put into the dictionary, ones of 
 option (2) do not. Why not? Because if there's more than one of (2), 
 which object module do you pull in? No way to tell.
 
 Thus, the problem you're seeing. The solution is:
 
 1) have another global in module test that gets pulled in, thus also 
 pulling the COMDAT along with it, and resolving the symbol.
 
 2) explicitly link in module test
 
 So, you might ask, why not just regenerate the template instantiation 
 every time you use it? Because it would lead to a lot of object file bloat.

Would you perhaps explain why ELF does not have this problem? Thanks
Feb 20 2007
parent reply Walter Bright <newshound digitalmars.com> writes:
kris wrote:
 Would you perhaps explain why ELF does not have this problem? Thanks

The ar format doesn't care if there are multiple definitions of the same symbol. The linker just picks one (presumably the first one it finds) and pulls in that module along with whatever else happens to be in that module.
Feb 20 2007
next sibling parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
Walter Bright wrote:

 kris wrote:
 Would you perhaps explain why ELF does not have this problem? Thanks

The ar format doesn't care if there are multiple definitions of the same symbol. The linker just picks one (presumably the first one it finds) and pulls in that module along with whatever else happens to be in that module.

That's not entirely true. Symbols in ELF can be said to be either LOCAL, GLOBAL or WEAK. The local ones are per module, the global ones you can only have one of, whereas the weak ones you can have multiple of and one (probably the first, depending on linker etc) is chosen. IIRC -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Feb 20 2007
parent Walter Bright <newshound digitalmars.com> writes:
Lars Ivar Igesund wrote:
 Walter Bright wrote:
 
 kris wrote:
 Would you perhaps explain why ELF does not have this problem? Thanks

symbol. The linker just picks one (presumably the first one it finds) and pulls in that module along with whatever else happens to be in that module.

That's not entirely true. Symbols in ELF can be said to be either LOCAL, GLOBAL or WEAK. The local ones are per module, the global ones you can only have one of, whereas the weak ones you can have multiple of and one (probably the first, depending on linker etc) is chosen.

The template instances are put in the .o file as GLOBAL ones.
Feb 20 2007
prev sibling next sibling parent reply kris <foo bar.com> writes:
Walter Bright wrote:
 kris wrote:
 
 Would you perhaps explain why ELF does not have this problem? Thanks

The ar format doesn't care if there are multiple definitions of the same symbol. The linker just picks one (presumably the first one it finds) and pulls in that module along with whatever else happens to be in that module.

For whatever reason, that approach appears to work quite effectively? The problem here is that one cannot currently build a production quality lib where templates are involved. It's not reasonable or feasible to expect a user to understand and compensate for the issues involved, nor is it entirely feasible to construct the lib in such a manner that the rather delicate balance is maintained. We wish it were. The reality problem is this: the more extensive the lib, and the more use it makes of templates, the fragility of it appears to increase exponentially. As does the difficulty of reverting that fragility. At this time, it is just not possible for us to construct a reliable Tango.lib which, given our collective D 'expertise', seems entirely bogus :) Can you resolve it in some reliable and user-friendly manner?
Feb 20 2007
next sibling parent Mike Parker <aldacron71 yahoo.com> writes:
kris wrote:

 At this time, it is just not possible for us to construct a reliable 
 Tango.lib which, given our collective D 'expertise', seems entirely 
 bogus :)
 
 Can you resolve it in some reliable and user-friendly manner?
 

I'd like to throw in my support for this request. This is my last major gripe about D. Templates should just work out of the box, regardless of the type of output being compiled (executable or library), without requiring any tomfoolery from the programmer to work around shortcomings in the object file format. Build tools like Bud and Rebuild help alleviate the situation for projects that distribute source, but that's no solution.
Feb 20 2007
prev sibling parent kris <foo bar.com> writes:
kris wrote:
 Walter Bright wrote:
 
 kris wrote:

 Would you perhaps explain why ELF does not have this problem? Thanks

The ar format doesn't care if there are multiple definitions of the same symbol. The linker just picks one (presumably the first one it finds) and pulls in that module along with whatever else happens to be in that module.

For whatever reason, that approach appears to work quite effectively? The problem here is that one cannot currently build a production quality lib where templates are involved. It's not reasonable or feasible to expect a user to understand and compensate for the issues involved, nor is it entirely feasible to construct the lib in such a manner that the rather delicate balance is maintained. We wish it were. The reality problem is this: the more extensive the lib, and the more use it makes of templates, the fragility of it appears to increase exponentially. As does the difficulty of reverting that fragility. At this time, it is just not possible for us to construct a reliable Tango.lib which, given our collective D 'expertise', seems entirely bogus :) Can you resolve it in some reliable and user-friendly manner?

For example, I get this when linking certain examples: ..\..\tango.lib(Socket) Error 42: Symbol Undefined _D12TypeInfo_AAa6__initZ --- errorlevel 1 Through a slow and entirely tedious process of 'playing' with the lib contents (which took all day), I discover that removing a very specific set of modules cause this link error to go away. Some of those modules make reference to one of two IFTI modules. With another module, I find that commenting out a single method eliminates the linker error. There are no templates within this module, but the particular method creates and returns an AA ...... arrgghhhh! How can anyone deal with that kind of development environment and remain sane? How could they possibly know how to resolve these? I ask you :) Now it's onto the next example that refuses to link. I'm pretty sure it is cold seawater I can feel around my ankles now
Feb 20 2007
prev sibling parent reply kris <foo bar.com> writes:
Walter Bright wrote:
 kris wrote:

 If you prefer, we could switch to the #D thread so as not to pollute
 this one?

Ok, but I'll need an example. I'd start by comparing .map files.

The BIG version ... you're gonna love this: 186kb of code 360kb of data O^O plus some bss, etc Debug symbols are not enabled in the lib (no flags at all). Will send you the two map files if you like?
Feb 21 2007
parent Walter Bright <newshound digitalmars.com> writes:
kris wrote:
 Debug symbols are not enabled in the lib (no flags at all). Will send 
 you the two map files if you like?

Won't help me. See the new thread I started on this.
Feb 21 2007