On 2012-08-21 18:15Z, Earnie Boyd wrote:
> So based on http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx and
> in particular the following text (each line is a column in the
> spreadsheet), since we are using MSVCRT or equivalent these should
> always be defined. Thoughts?
I interpret it differently, as follows (I've transposed the last two
spreadsheet columns to the front):
If you run the ms compiler and linker with this switch:
then they'll define these macros, which your code can rely on for
choosing among conditional sections:
> _MT, _DLL
and this CRT '.lib' file will be linked:
which is an import library for the following dll:
and here's a narrative description:
> Multithreaded, dynamic link (import library for MSVCR110.DLL). Be
> aware that if you use the Standard C++ Library, your program will need
> MSVCP110.DLL to run.
I haven't used their compiler in twenty years, so it's conceivable that
I've misunderstood. But note that the "Option" column that I moved to
the very front is the only one they set in boldface and made clickable,
which would seem to give it primacy. Click on it:
http://msdn.microsoft.com/en-us/library/2kzt1wy3%28v=vs.80%29.aspx and the same information appears in a different format that supports
the interpretation above, e.g.:
Description: "Causes your application to use the multithread- and
DLL-specific version of the run-time library. Defines _MT and _DLL
and causes the compiler to place the library name MSVCRT.lib into
the .obj file."
That implies that /MD is what governs, and the consequent use of MSVCRT
and definitions of some macros are among the effects that result.
If we want to define similar macros, they should indicate which compile
and link options were given to gcc. (There may be some reason to use our
own names--e.g., borland used __DLL__ instead of _DLL, but I don't know
the reason why.) But I would caution against adding any macros now: that
might break existing code, and AFAICR nobody has ever asked for such a
change. I'd just follow the digitalmars approach, because the reason
highlighted below applies to us as well:
http://www.digitalmars.com/ctg/ctgPorting.html | Problem: _MT not automatically defined
| 32-bit Microsoft C++ sets _MT=1 if the /MT (multi-threaded) option is
| specified. If /MD (multi-threaded DLL) is specified, 32-bit Microsoft
| C++ sets _MT=1 and _DLL=1. Digital Mars C++ has no equivalent switches
| because its 32-bit run-time library is always multi-threaded. To solve
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [MinGW too]
| this problem, define _MT and _DLL on the dmc command line as necessary.
On Tue, Aug 21, 2012 at 4:59 PM, Greg Chicares wrote:
> On 2012-08-21 18:15Z, Earnie Boyd wrote:
>> So based on http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx and
>> in particular the following text (each line is a column in the
>> spreadsheet), since we are using MSVCRT or equivalent these should
>> always be defined. Thoughts?
> I interpret it differently, as follows (I've transposed the last two
> spreadsheet columns to the front):
> If you run the ms compiler and linker with this switch:
> then they'll define these macros, which your code can rely on for
> choosing among conditional sections:
>> _MT, _DLL
> and this CRT '.lib' file will be linked:
> which is an import library for the following dll:
This DLL is the 2012 version of MSVCRT.DLL. So in my mind they are
equivalent with regard to the purpose of the DLL providing the
MultiThread C runtime. _MT meaning MultiThread. Note that /MT gives
you the MultiThread static version and doesn't use the _DLL. MS no
longer supports Single Thread libraries.
My question leads to since we by default use the MultiThread
msvcrt.dll should we not define these _MT and _DLL macro by default?
Preferably with the GCC specs? Currently GCC will define _MT but only
if -mthreads used but that has no meaning as I've discovered in the
current versions of GCC.
However, of what use are these macro? Do they control any code?
On 2012-08-21 21:43Z, Earnie Boyd wrote:
> My question leads to since we by default use the MultiThread
> msvcrt.dll should we not define these _MT and _DLL macro by default?
I'd say we should not.
> Preferably with the GCC specs? Currently GCC will define _MT but only
> if -mthreads used but that has no meaning as I've discovered in the
> current versions of GCC.
Then the _MT macro signifies that the -mthreads option was given:
only that, and nothing more. An example quoted below seems to
depend on that meaning.
> However, of what use are these macro? Do they control any code?
I did some googling, but couldn't find any use case to support
our defining _DLL . It's used in system headers to decide whether
to use __declspec(dllimport), which our w32api headers already do
unconditionally. I don't see how this would be useful elsewhere.
I always thought that when a toolchain defines _MT, it's promising
to provide all necessary support for threading. If that's right
(but see the contrary example below), then I suppose it'd be safe
to define it unconditionally for current MinGW gcc. (Earlier
versions that require the thread-destruction DLL shouldn't define
it unless invoked with the appropriate option to link that DLL.)
Here's an example where defining _MT *might* be helpful:
// STLPort does not support single threaded builds:
#error STLPort does not support single threaded builds
OTOH, I would suppose that anyone who builds stlport with MinGW gcc
has grown accustomed to adding '-D_MT' manually. I don't recall
anyone ever asking us to define it automatically. But something
similar has been requested upstream--see:
However, another interpretation is that _MT signifies that the
toolchain has been invoked with an explicit option that requests
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11953#c25 | Consider a library libjohndoe, this library comes in two
| flavours: one that is not thread-safe (-ljohndoe) and
| one that is thread-safe, but considerably slower and
| larger so that users really only want to use it when
| they are actually using threads (-ljohndoe_r).
If we define _MT all the time, we break that code. If we tell
the author that we defined _MT for compatibility with msvc,
he'd probably retort that his code still works with msvc--so
our change made us incompatible. To me, that's a strong-enough
argument for making no unnecessary change in MinGW.
Of course we could say that he should have defined and used
his own _MY_LIBRARY_USES_THREADS instead of using _MT. But
that only brings us back to the problem experienced upstream:
On Wed, Aug 22, 2012 at 11:32 AM, Greg Chicares wrote:
> Here's an example from the wild:
> http://research.cs.wisc.edu/sonar/projects/mnemosyne/resources/doc/html/malloc-original_2benchmarks_2larson_2driver__mt_8cpp-source.html >
> #ifdef _MT
> printf( "\nMulti-threaded test driver \n") ;
> printf( "\nSingle-threaded test driver \n") ;
> #ifdef _MT
> runthreads(sleep_cnt, min_threads, max_threads, chperthread, num_rounds) ;
> runloops(sleep_cnt, num_chunks ) ;
> If we define _MT all the time, we break that code. If we tell
> the author that we defined _MT for compatibility with msvc,
> he'd probably retort that his code still works with msvc--so
> our change made us incompatible. To me, that's a strong-enough
> argument for making no unnecessary change in MinGW.
Well, not really broken, since MSVCRT.DLL always provides Multi
Thread; Single Thread required a different DLL.
> Of course we could say that he should have defined and used
> his own _MY_LIBRARY_USES_THREADS instead of using _MT. But
> that only brings us back to the problem experienced upstream:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11953#c12 > | Admittedly, Boost was never correct to use that macro, but the fact remains that
> | the change has caused problems that Boost must now address.
And MS has stated that MSVCRT.DLL is reentrant safe so one could argue
that _REENTRANT should always be defined; for C at least. We use
libstdc++ for the C++ runtime so that needs to be accounted for.
For the time being I'll leave this alone. We need a testsuite to
drive out the bugs.