Hi Doug,

On 18/05/07, Doug Cook <[EMAIL PROTECTED]> wrote:
If the lib is added explicitly, you're right -- it probably won't
break anything.

However, there are actually three CRTs. libc (single-threaded
static), libcmt (multi-threaded static), and msvcrt (multi-threaded
DLL). libc is no longer supported (there is no longer any such thing
as a single-threaded Windows app because things like signals can
come in on separate threads). So adding a nodefaultlib for msvcrt is
not just like the nodefaultlib for libc.  It would be like a
nodefaultlib for libcmt.

Points taken. (Though I think LIBC.lib and single-threaded Windows
apps still make sense in some cases: not Vim.)

Lib conflicts are scary. They work only because you are lucky and
because the Microsoft CRT developers worked very hard to make things
work ok most of the time. However, there are some functions that
don't work ok, and the list of functions that don't work ok is
subject to change at any time. And sometimes you might be using a
function that mostly works ok except for some strange edge cases.
Better to just avoid the whole issue if possible.

How? I mean, perl58.dll, tcl84.dll, and msvcrt-ruby18.dll depends on
msvcrt.dll, and python24.dll depends on msvcr71.dll, but nobody has
reported issues (not even the build one) with using them in gvim.exe
(linked with LIBCMT.lib). ONLY the Tcl84 lib has build warnings with
the CONSOLE vim.exe.

Both gvim.exe and vim.exe are linked with tcl84stub.lib, which
contains the linker directive -defaultlib:MSVCRT. Why only vim.exe
gives the warning? Anybody has insights on this?

As for "allowing" multiple CRTs, I was referring to the warning. It
warns when you link with multiple CRTs at the same time. In your
case, the conflict looks scary because you have linked with _dup but
not with free...

(One gotcha: _dup is not strdup, so I do not see why you worry about
free.)

Still I do not like it. But the question is still How? Adding
/nodefaultlib:msvcrt at least removes these ugly imported functions.

You should only use one CRT in an EXE or DLL. Any time you use more
than one within the same executable, you're in undefined territory
and while things may work, things could go wrong at any time.

There's nothing wrong with msvcr71.dll or msvcr80.dll. In fact, they
have many bug fixes and performance improvements over msvcrt.dll.

I agree with this.

However, if you link against one of them, it has to be installed on
the target machine or the EXE/DLL won't load, while msvcrt.dll is
always present on every copy of Windows. That said, you might run
into an old versions of msvcrt.dll that is missing functions you
need (each new version of Windows has added new functions to
msvcrt.dll), while you pretty much know what you are getting when
you use msvcr71 or msvcr80.

But it seems you did not get my point. Tcl84.dll has a dependency on
MSVCRT.dll, but adding MSVCRT.LIB to the build (implicitly or
explicitly) will make vim.exe dependent on MSVCR71.dll (instead of
MSVCRT.dll) under MSVC 7.1. So we do not end up any better.

The basic thing here is: Does /nodefaultlib:msvcrt do more good or
more evil? While many of your points are good and some of mine are
faulted, I still can see only good results instead of evil ones using
it in building Vim.

-----Original Message-----
From: Yongwei Wu [mailto:[EMAIL PROTECTED]
Sent: Thursday, May 17, 2007 7:15 AM
To: Doug Cook
Cc: Bram Moolenaar; Vim-dev mailing list
Subject: Re: MSVC build option about default library MSVCRT

Hi Doug,

On 17/05/07, Doug Cook <[EMAIL PROTECTED]> wrote:
> Bram is wise.

No objection here ;-).

> Adding a nodefaultlib:msvcrt could potentially break things if you
> set USE_MSVCRT=1 to use the CRT DLL instead of statically linking
> the CRT. The problem is that you're linking a static-CRT version
> of Vim with DLL-CRT versions of ActiveState components. The
> problem is not with Vim's makefile.

Adding /nodefaultlib:msvcrt does not affect USE_MSVCRT=1, which will
add the NON-default library msvcrt.lib explicitly.

In fact, I think /nodefaultlib:msvcrt is really symmetrical with the
current setting. We already have /nodefaultlib:libc, which disables
the default static libc. Why should we allow default dynamic libc
while disabling default static libc?

> Generally, if you have lib conflicts, it means you've done
> something wrong.  In this case, you have one OBJ that was compiled
> for use with the static CRT, and another OBJ that was compiled for
> use with the dynamically-linked CRT. Each of them tell the linker
> "you should probably link me with this particular CRT". Luckily,
> the linker is smart enough to only allow one CRT at a time.

Lib conflicts are something wrong, but not necessarily serious. It
is a serious problem only if one does some foolish things like
malloc in one CRT and free in another.

Also, the linker does allow two CRTs at the same time, and which
occurred to me, if I did not add /nodefaultlib:msvcrt. LibcMT will
be linked, but the following five functions are imported from
MSVCR71.dll:

 _fileno
 _chdir
 _fdopen
 _dup
 _putenv
 _stat
 _dup2

> For a standalone program, statically linking with the CRT is
> generally the way to go, so Vim defaults to doing this. Using the
> CRT DLL saves about 150k in disk space, but the CRT DLL is
> 400-800k, depending on which version of Visual C++ you're using.
> The CRT is potentially already in memory in another process, so
> this may or may not save memory at runtime.
>
> For a program that interacts with other DLLs (such as loading
> Perl, Python, Ruby, etc. DLLs at runtime), the CRT DLL starts to
> make more sense. In addition to saving disk space (one CRT DLL
> instead of 150k of static CRT in each executable), you save memory
> (one CRT DLL loaded, and all modules share the same heap) and in
> some cases you avoid bugs (only one CRT so you don't have
> conflicting CRT settings like locale). However, you now have to
> redistribute the CRT with your product, and starting with VC 8.0,
> you have to get the CRT's manifest correctly embedded into your
> EXE and DLLs.

Another problem with CRT DLL is that different MSVC versions will
make the resulting executable dependent on different CRT DLLs.
Linking with MSVCRT.LIB in MSVC 7.1 results in the dependency on
MSVCR71.DLL instead of MSVCRT.DLL. This is not something we like, I
suppose.

Best regards,

Yongwei

--
Wu Yongwei
URL: http://wyw.dcweb.cn/

Reply via email to