Is it time to say goodbye to VC6 compiler? - c++

Of late I'm facing the issues that points finger to VC6 compiler.
Few of them are:
A function-try-block doesn't work. Related Q
in-class constant doesn't work.
__FUNCTION_ (Macro to get function name) doesn't work
The latest addition is it doesn't allow void functions to be passed as part of for_each.
The below example is not compiling with VC6 compiler. It says "error C2562: '()' : 'void' function returning a value". It looks like VC6 doesn't like void functions to be passed to for_each.
class Temp
{
public:
Temp(int i):m_ii(i)
{}
int getI() const
{
return m_ii;
}
void printWithVoid()
{
cout<< "i = "<<m_ii<<endl;
}
bool printWithBool()
{
cout<< "i = "<<m_ii<<endl;
return true;
}
private:
int m_ii;
};
int main(void)
{
std::vector<Temp> arrTempObjects;
arrTempObjects.push_back(Temp(0));
arrTempObjects.push_back(Temp(2));
//Doesnot work, compiler error
std::for_each(arrTempObjects.begin(), arrTempObjects.end(), std::mem_fun_ref(&Temp::printWithVoid));
//Works
std::for_each(arrTempObjects.begin(), arrTempObjects.end(), std::mem_fun_ref(&Temp::printWithBool));
return 0;
}
Have you faced any other issues related to VC6.0. Any workaround to resolve these issues ? Or is it time to change the compiler?

Quite frankly I can hardly understand why you wouldn't buy a modern computer and switch to Visual Studio 2008.
VC6 has got a deficient STL, poor C++ standard compliance and obsolete GUI.
You shouldn't let your competitors use better tools than you.

Well, here's the thing. The VC6 compiler sucks. However... the IDE is pretty good.
VS2005 has much better source control support. Otherwise, it's much slower debugging, has a crappy output pane that exponentially decays on inserting output lines (what absolute garbage coding is that?), the help system is many times slower, and debug and continue (possibly Microsoft's best feature over other IDEs) is considerably more broken.
.NET? Sure, VS20xx is the only way to go. However, for one small client that is sticking with VC6/MFC (for interfaces to embedded systems, etc) I actually enjoy working with VC6. It's just FAST.
2008? I'd like to... but it takes a while for my clients to migrate. Nobody has, yet.

Is it time to say goodbye to VC6
compiler ?
Yes.

VC6 cannot do much of any kind of modern C++. I recall I tried to use one of the boost libraries ages ago like probably Graph and it was giving "INTERNAL COMPILER ERROR" all over the place so eventually I chucked that in.

The no-brainer answer is yes, and ASAP. You have free alternatives like VC++ express and Code::Blocks, if the cost as in issue. The pain in solving compatibility issues is IMO no reason not to upgrade because you will have to do it some day anyway and it only gets harder.
The only reason I see for a possible obstacle is if you have MFC code that will be difficult/time consuming to port. In that case you can't use VC++ express (no support for MFC) and you have to make the investment for at least the VS std. edition. That will cost you about EUR 300 (depending on where you live).

I changed from VC++ 6.0 to Code::Blocks (which is FOSS) with g++ a few months ago and haven't really looked back. I miss the VC++ debugger a bit, as the gdb implementation in CB is nowhere near as slick, but that's about all. Some things in the IDE work better (code completion, tooltips, dependancy xalculation) and the compiler is obviously much better.
Regarding your points, function try blocks are hardly a widely used feature, and most people think they are pretty useless. And the __FUNCTION__ macro is not part of the C++ Standard, so you shouldn't depend on it too much if portability is an issue.

No, it was time to say goodbye to it a decade ago. Here are a few reasons why:
There are free, standards-compliant compilers available, both from Microsoft and others
VC6 was written before the C++ language was standardized, and it is nowhere near standards compliant. Especially templates and the standard library live in a world of their own, with no tie to how these features actually work in ISO C++. The language it compiles is not C++. It is a hybrid of pre-standard C++, Microsoft extensions, compiler limitations and bugs. Neither of which are desirable.
VC6 is known to generate invalid code in some cases. Not only does it compile a home-made, buggy and nonstandard language, it also makes invalid optimizations causing crashes, or in some cases actually produces bad assembly that simply can not be executed.
It is broken, and it was always broken. It was designed to compile a language that ceased existing about the same time as the compiler was relased (when the language was standardized), and it failed even at that task, with countless bugs, some of which have been fixed in the half-dozen service packs that were released. But not all of them, and not even all the critical ones.
Of course, the downside to this is that your application is most likely just as broken. (not because you're bad programmers, but because it targets a broken compiler. It has to be broken to be accepted by VC6)
Porting that to a standards-compliant compiler is likely to be a lot of work. Don't assume that you can just import your old projects, click "build", and it'll work.
So if you're part of a big business that can't just take a month off to switch compilers, you might have to port it as a side project, while part of the team is maintaining the VC6 version. Don't scrap VC6 until you've successfully ported everything, and it works.

Unless you have a large program to maintain, yes. Switch today!
The Express versions of VC++ are a free download from Microsoft.

I guess this is why so many applications on Windows sucks because people still use VC6. Why mess with broke, never maintained MFC or even Win32 when their is wxWidgets and Qt4 out there way better than MFC could ever be and you you can even use the free additions of Visual Studio 2005+

You can learn to live with VC6s foibles. It almost has a certain retro charm these days. We've been repeatedly providing "just one last VC6 release" of some libraries to a customer for years now. Hard to argue with a customer prepared to pay for the extra work backporting and maintaining a branch. But at some point the cost for us to backport newer features developed in newer VCs will exceed the cost of them upgrading at their end (especially as more boost and Intel TBB creeps into the codebase's head). Or at least I hope that's what'll happen! Worst case it'll happen just as flaky C++0x support appears and we'll be stuck supporting that for them for 10 years...

General rule seems to be that a new version is an upgrade and is thus worthwhile.
However! you have to pick the right time for it, there are so many bugs fixed, but you then need to be aware of the new bugs and variations from the standard.
Set aside time for the upgrade.
Upgrading compiler versions could well be a project in its own right, make sure you have stable code and good tests before you do an upgrade and when you finish prove that it is still working the same.
You may be forced to upgrade when you start to develop for Vista as VC6 doesn't provide for code signing easily and the redist is not in a form that Vista likes. (want at least VC2K5)

Are you updating the OS any time soon? When I researched moving our apps to Vista, I found that Vista doesn't officially support anything before VS 2005 (except for VB 6), and has a page-long list of possible little problems with VS 2005 that may or may not bite you. I recommended delaying until VS 2008 SP1 was available (i.e., when VS 2008 was really usable), and doing the compiler changeover first.
If the project is a special one for a few customers who run it soley on old NT machines, you may want to keep it at VS 6. If you are selling it for any sort of general consumption, you will need to make it Vista-compatible at some point (or 7-compatible, or whatever), and you will need to upgrade.

Related

Repository of buggy compiler versions for C++11 support

I have a C++ soft that gets compiled with different OSes, platforms & compilers. Now sometimes compiler have bugs e.g. for instance this one, which implies that gcc versions pre 4.6.4 and pre 4.7.3 are a no-go. Now i could include a unit test that showcases the bug (and perhaps this question will reveal that indeed that's what I should be doing) but this is a tedious task: compiler bugs are sometimes hard to repro and turning one into a unit test might not be easy either... and that's when you have the platform & compiler at hand.
What I'm looking for is a repository that tells me which versions of g++, clang++ and msvc++ suffers from fatal bugs for supporting C++11 (i'm not talking about missing features, when features are not there I work around them). I would then fatal crash when building with them in the build system. Nice feature is, I'm not even forced to hit a bug to ban a compiler (so I'm saving myself future trouble).
Does such a list exist?
This is probably not the answer you are looking for, but I believe the correct way to deal with this is to have a white-list, rather than a black-list. In other words, have a list of compilers that you know works, and if the customer tries to build using a different version than the ones you have tested with, you issue a warning message as part of the build script saying something like this:
This compiler is not supported, please see
http://www.example.com/list_of_supported_compilers.html for a list of
compilers we support. If you choose to continue using this compiler,
feel free to do so, but don't expect full support from our
tech-support, if you find a problem.
The reason I say this is that:
You will not be able to prove that EVERY version other than what is on your blacklist works correctly. You can, however, for whatever testcases you have, prove that compiler X version a.b.c-d works [this doesn't mean that this compiler is bug free - just that you haven't hit any of those bugs in your testing!]
Even if the compiler is "known good" (by whatever standard that is defined), your particular code may trigger bugs that affect your code.
Any sufficiently large software (or hardware) product will have bugs. You can only show that your software works by testing it. Relying on external "there is known bug in version such and such of compiler X" will not help you avoid bugs affecting your code. Having said that, most compilers are fairly well tested, so you (usually) need to do some fairly unusual/complicated things to make the compiler fail.
Investigate Boost.Config, in particular the header <boost/config.hpp>.
This includes a large group of macros for a wide variety of compilers (and different versions there of) which indicate which C++ features are enabled, broken etc. It also includes a comprehensive test suite which can be used to test any new compiler for missing features etc.

Major differences between Visual Studio 6.0 and VS 2010 Compilers

Some months ago I posted the following question
Problem with templates in VS 6.0
The ensuing discussion and your comments helped me to realize that getting my hands on a new compiler was mandatory - or basically they were the final spark which set me into motion. After one month of company-internal "lobbying" I am finally getting VS 2012 !! (thank you guys)
Several old tools which I have to use were developed with VS 6.0
My concerns are that some of these tools might not work with the new Compiler. This is why I was wondering whether somebody here could point out the major differences between VS 6 and VS 2012 - or at least the ones between VS 6 and VS 2010 - the changes from 2010 to 2012 are well documentes online.
Obviously the differences between VS 6.0 and VS 12 must be enormous ... I am mostly concerned with basic things like casts etc. There is hardly any information about VS 6.0 on the web - and I am somewhat at a loss :(
I think I will have to create new projects with the same classes. In the second step I would overwrite the .h and .cpp files with the ones of the old tools. Thus at least I will be able to open the files via the new compiler. Still some casts or Class definitions might not be supported and I would like to have a general idea of what to look for while debugging :)
The language has evolved significantly since VS 6.0 came out.
VS6.0 is pre-C++98; VS 2012 is C++03, with a few features from
C++11.
Most of the newer language features are upwards compatible;
older code should still work. Still, VC 6.0 is pre-standard,
and the committee was less concerned about breaking existing
code when there was no previous standard (and implementations
did vary). There are several aspects of the language (at least)
which might cause problems.
The first is that VC 6.0 still used the old scoping for
variables defined in a for. Thus, in VC 6.0, things like the following
were legal:
int findIndex( int* array, int size, int target )
{
for ( int i = 0; i < size && array[i] != target ; ++ i ) {
}
return i;
}
This will not compile in VC 2012 (unless there is also a global
variable i, in which case, it will return that, and not the
local one).
IIRC, too, VC 6.0 wasn't very strict in enforcing access
controls and const. This may not be problem when migrating,
however, because VC 2012 still fails to conform to C++98 in some
of the more flagrant cases, at least with the default options.
(You can still bind a temporary to a non-const reference, for
example.)
Another major language change which isn't backwards compatible
is name lookup in templates. Here too, however, even in VC
2012, Microsoft has implemented pre-standanrd name lookup (and
I mean pre-C++98). This is a serious problem if you want to
port your code to other compilers, but it does make migrating
from VC 6.0 to VC 2012 a lot easier.
With regards to the library, I can't remember whether 6.0
supported the C++98 library, or whether it was still
pre-standard (or possibly it supported both). If your code has
things like #include <iostream.h> in it, be prepared for some
differences here: minor for straight forward use of << and
>>; major if you implement some complicated streambuf. And
of course, all of the library was moved from global namespace to
std::.
For the rest: your code obviously won't use any of the features
introduced after VC 6.0 appeared. This won't cause migration
problems (since the older features are still supported), but
you'll doubtlessly want to go back, and gradually upgrade the
code once you've migrated. (You mentionned casts. This is
a good example: C style casts are still legal, with the same
semantics they've always had, but in new code, you'll want to
avoid them, and least when pointers or references are involved.)

Why is clang not used more? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I've done a fair amount of programming in C/C++ before, but nowadays it only accounts for a small percentage of the programming I do (scripting languages are much better suited for a lot of the work I do). I worked on some C programming projects the last few days and was surprised how many little syntactical details I kept forgetting. What's worse is that cc/gcc typically had cryptic or non-informative error messages about these issues (sorry I can't remember any specific examples).
I learned about the clang compiler not too long ago and decided to try that. The error messages were much clearer and helped me identify and fix the problems in my syntax. My question is why this tool is not used/mentioned more than it is? Is it that it is so new compared to the usual suspects (cc/gcc), or is it that it doesn't support features that they support, or is it just harder to obtain? I have a hard time believing that last one, since it was installed with the dev tools on my iMac and required a single command (sudo apt-get install clang) to install on my Ubuntu box.
My question is why this tool is not used/mentioned more than it is?
It's probably because of history, and because how we humans generally behave.
Traditionally gcc has been the only real (free) compiler that can be practically used to compile C programs on atleast all the free *nix clones out there. It's what virtually all the base system and kernel of linux, *BSD, now probably OSX, and others are compiled with.
While flaws are here and there, basically this means: gcc works. And if it isn't broken, don't fix it. Out of this, you now have a huge user base, it's easy to get help with gcc, there's a lot of people that have used gcc, that are working on gcc itself etc.
Generally, if you want to switch a huge community from something they're used to, to something else, that "something else" have to be *significantly" better. Just "better" is often not reason enough. I think you can find examples of this in many areas of society.
clang is newer, some people will just be suspicious if it's up to the task, if it has bugs, if it produces slower code etc. - it seems to be in the human nature to be suspicious - new things are scary. Many don't even know about clang, many don't care because they're happy with gcc.
Though, if you rather want to use clang, go for it - error messages are indeed "better" and easier to understand vs gcc.
The clang front end is relatively new. For example, the 2.8 release in October 2010 marks the completion of the C++ 98/03 support.
It seems likely that with increasing maturity, there will be an increasing adoption. For example, there is ongoing work on making the FreeBSD OS (and other BSD OS's) build with clang, eliminating a dependence on GCC/G++.
Apple are pushing the LLVM/clang combination. It seems likely that they will cease to support their old GCC toolchain branch (based on 4.2) and come to depend solely on clang tools for OSX/iOS development.
Clang is also seeing increasing adoption in custom compilers for C-like languages (e.g. shader language compilers for OpenCL)
LLVM has been around for a while, but — at least in my neck of the woods — it has only risen to prominence very recently, possibly due to the fact that Apple has been pushing heavily of late to replace gcc with Clang in their own tool-chain.
Also, I believe it's C++ support has only recently become production-grade. EDIT: It appears that it isn't even that yet. (See comments below.)
Another factor might be that LLVM is largely backed by a single vendor, towards which non-Apple developers have an innate mistrust.
My question is why this tool is not used/mentioned more than it is? Is it that it is so new compared to the usual suspects…
This is exactly the reason. It is still new and core functionality is still being actively developed. Remember that existing projects may be making use of compiler-specific features – or using libraries which do – and developers are, in any case, loath to change working tools for experimental ones that may have unexpected bugs or unknown performance/size/etc. tradeoffs, even when the new tools are increasingly getting better every day.
As a student programmer I find it a total godsend mainly due to it's helpful and understandable error messages. I use it mainly for programming in C, though I am beginning to branch out into C++ also using Clang.
As to why is it not mentioned more, I suspect it is since GCC has been established for so long, for most users it is THE compiler. GCC for me works fine except for it's extremely cryptic error messages which as a student does throw me off quite a bit.
Overall I do highly recommend Clang for use by both students and developers. Since it is now the official compiler for Apple and Xcode, I suspect it's use and name recognition will quickly pickup. FreeBSD seems to have also adopted it as their main compiler though I suspect that will have less impact on it's popularity than it's adoption by Apple.
Addendum: Due to the competition from Clang, the clarity of the error messages in GCC 4.8 and 4.9 has shown a significant improvement; though I still find Clang a little more lucid, the gap however has narrowed significantly.
Today, clang is replacing gcc in most places. i.e., most *NIX-like operating system and Linux distributions. Some examples oare FreeBSD,Minix and mac(a bit obvious) clang that switched clang as default compiler. Some of my friends too,when I showed them.
This IMHO, looks like some peoples had problems with it,probably in older versions. But with clang version 3.0, I don't have any of this problems. As I metioned before, I'm using it really in all my new projects. Almost my default compiler, sometimes I do make C=gcc just to seen how difference to clang error/warning. And clang win ever. With better explanations and make a great effort to optimization. It include suggestions for use extensions(some are gcc inerhid) of the compiler to a best perfomance in the code generation.
I had written a trivial function that print an error message. But I would to exit from program after printed the error message on standard output. So,I make a simple modification,put an exit(1) as last statement in the function. As the following:
void error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "error: ");
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(1);
}
And so the clang show
warning: function 'error' could be declared with attribute 'noreturn'
[-Wmissing-noreturn]`
(gcc doesn't produce it even not with -Wall -Wextra -Wunreachable-code -O3 flags)
I say "that seems like nice. But what is 'nonreturn' attribute? I'd never listen or read about this. I jump to google and search for clang could be declared with attribute 'noreturn' (oh,yeah,I could just written clang nonreturn attribute,but forget it) and I found this link with a good explanation of what it this attribute and the possible gain of perfomance that I could get.
So I run to add this attribute to my function prototype(of course,if it is the gcc or clang compiler; macros will do the trick-detection). Oh yeah,to me,any small gain of perfomance(of course,without making the code unreadable) it a win.
And don't ends here,some year ago,I make return in a function where the proviously is a switch as default handling defined(as in the error() function here). But even so, gcc clains about function without return-value(I'm sorry,I don't recall to exactly error/warning message) how it possible? there is no more statements after switch,if no case match,default value is executed and don't really matter the below statements,if any. But clang think different,like me,and give a warning about this declaration,helping me make better code.
And for this kind of very small thing, I'm loving the clang.
(Note: I'm sorry for my bad english. English isn't my native language speaker, but despite it I'm trying express me here)

Is new C++ backward compatible

I haven't coded in C++ for years. I recently discovered that during those years it has changed quite dramatically. I'm not sure I like the changes, but that's another discussion.
I still have some C++ code knocking around my hard drive. If I got it out and tried to compile it with a nice new C++ compiler, say the latest version of g++, would it compile? Without warnings (assuming it compiled without warnings before)?
I did get to mess around with a little VC++ 2010 recently and found some things I expected to work just not working, and got different messages depending on context when I tried to use NULL. But in one part of that code I used NULL without even a warning.
It depends. Usually newer compilers are more standard-compliant, so many constructs that compiled on earlier compilers don't compile now without fixing. For example:
for( int i = 0; ... );
i++;
compiled in Visual C++ 7, but not in Visual C++ 9.
In general, yes it is backwards compatible. However, the devil is in the details. You likely will find things where conventions change, or specific libraries fall into or out of use.
NULL is a macro - prefer to use 0 (or nullptr in C++0x).
Not sure just how old your code is, but Visual C++ v6 suffers from limitations that result in code that simply won't compile on newer compilers. VS2005 and up are a lot better (in the sense of more correct wrt the contemporaneous C++ standard).
I would not expect it to be a huge amount of work to get old code compiled, though. I've done some pretty major ports from VC6 -> VS2005 and for the most part it's a matter of hours, not days. Perhaps once the culture shock has worn off this will not seem so daunting. Really, VC++ 10 is very nice.
This depends on what you're comparing to.
Visual Studio 2010 partially implements the upcoming C++0x draft (recent versions of GCC also implement a subset of this draft, which is expected to be standardized next year)
C++98/C++03 was the first standardized version of C++, and is still the official one (as C++0x is still only a draft)
and of course, there are the dialects from before the language was standardized
C++0x is pretty much backwards compatible with C++03/98. There may be a couple of obscure corner cases that have changed, but you are unlikely to encounter them.
However, a lot of changes occurred when the language was first standardized, meaning that C++98 isn't entirely (but nearly) compatible with pre-standard C++.
But more likely, what you're into isn't a question of C++ backwards compatibility, but simply that compilers have gotten stricter. They have become much better at following the standard, and no longer allow many non-standard tricks that were common earlier. Most likely, your old code was never valid C++, but worked because compilers used to deviate more from the standard.
The language itself hasn't changed since it was standardized in 1998. Idioms have changed, and compilers have both improved their support for the standard and become stricter about non-standard code, but any standard-conforming C++ code that compiled in the past should still compile today. Code that relies on non-standard compiler features or quirks might not work, but compilers typically offer command-line options to make them accept non-standard code that used to be accepted by previous versions of the same compiler.
NULL is a macro that's defined in <cstddef>. Other standard headers may include that header as an implementation detail, so it's often possible to use NULL without explicitly including <cstddef>, but relying on that has always been non-portable. It's OK to use NULL as long as you include its header, though just using 0 is preferred in idiomatic C++.
All version of C++ should be backwards compatible.
Although there might be some unusual cases where there could be a problem, e.g. noexcept on destructos in C++0x (although this has not yet been decided).
Newer C++ standards come to clarify things, then take decissions on which usage is "more correct" or accepted, so I would expect warnings. Some other decisions change what can be done or not, so I would also expect errors. I've come across the same situation, and I had to tweak the code for it to compile. It was not a great deal, but this was taking into account my knowledge of C++. In general, you should encounter not great problems.
There are also other things. For example, not all compilers implemented the whole rules of the C++ standard, or they had bugs. When you get used with a compiler, some of those errors or missing features may pass unnoticed to your compiler, but may cause errors in future versions of the same compiler.
That's the major reason why we have standards. You don't have to worry about compatibility, you will just tell the compiler to compile the code as C++98 (or 2003).
MSVC is unfortunately very bad at supporting C++ standards. It is slowly getting better (and that's why old code doesn't compile, since it shouldn't compile in the first place).
Well, I know a lot of our old VS6 code started throwing tons of warnings when we upgraded to VS 2005 (with full warnings on of course, as everyone should work). Most were good things though, warning of potential information loss, warning that some types may be 64-bit instead of 32-bit like old code might expect, etc.
For your specific example of NULL, that wasn't even really standard C back in the day. Every compiler just had a #define for it that set it to 0. These days it is generally considered more correct (and clear) to just use 0.
If you have used old versions of various libraries such as Boost, expect some problems.
Slightly random, but the keyword export is being removed from the standard. So previously standards compliant code the used export would now be illegal. Of course, very few compilers even began implementing that keyword.
Very similar to sharptooth's answer, there are bits of older C and C++ code that will need /ZC:forScope- set (i.e. don't force conformance in for loop scope). e.g.
int myfunc(int x, int y, int z)
{
int j;
for (int i=0; i <= 10; i++)
{
if (f(i) == 0)
break;
}
j = i;
for (i=0; i <= 10; i++)
{
if (g(i) == 0)
break;
}
if (i > j)
return j;
return i;
}
This type of thing is quite common in much older code, where bytes cost money and variable re-use was common place.

Visual Studio 2005 C++ Compiler slower that Visual Studio 6 Compiler?

One of our old C++ projects is still with Visual Studio 6. Once a year I try to convert it in to a higher Visual Studio Version but it's not easy because not all the code is written by us.
Anyway, I finally succeeded in converting the project to VS2005 after fixing a few hundred lines of code. But compiling the projects takes a very long time! Much longer than in VS6.
Some classes have a lot of codelines, a few thousands even. These are just arrays to be filled in the code with a lot of items. I know it's not the perfect solution but this is how it is at the moment and VS6 never had a problem with that.
Maybe there are just some settings I have to adjust to speed things up but if it stays like it is now I will keep it as an VS6 project since I don't want to sit at my desk all day doing nothing.
Any ideas?
Differences in compile times are normal. The C++ compiler from VS2005 is significantly more compliant to standard C++ than VC6 was. There is a huge difference between these two compilers.
VS2005 produces more optimized code and thus has to spend extra time figuring out how to make it faster.
See if you can find the smallest modules that compile quickly, and very slowly in VS05, and see what they don't have in common. Add in the elements from the slow module to the fast one until you get a sudden slowdown. That is the cause of the problem.
Sounds like you are a few years behind in your "once-a-year-upgrade", no?
Check to make sure you didn't turn off pre-compiled headers.
Get Incredibuild.
Definitely worth the money you pay for it.
What it does is delegate compilation of files to idle build "agents" on the network, get the results back and link it on the build co-ordinator. The more machines the better. I was impressed with the reduction of build time.