evilbeanfiend wrote: evildave wrote: EvanED wrote:
bitwiseshiftleft wrote:Though when was the last time you were working with it? VC++6 was not great, but the versions since have improved quite a bit.
The 'latest' were well into the .NET versions, but the internal, fixed buffers that make the compiler crash are larger, but still present.
is that strictly a compiler issue or a libstdc++ implementation issue? afaik m$ don't make make the libstc++ that they provide, dinkumware do. of course this is largely irrelevant to the end user.
vsc++ has been pretty good at conforming to the standard (apart from template export) since 7.0 which wasn't long after gcc got serious about supporting templates and namespaces properly.
It's strictly an internal compiler issue. IT CRASHES
. It contains fixed internal buffers, so if you overflow them, you'll get an 'INTERNAL ERROR' and the compiler aborts. You have to turn off the 'precompiled headers' and 'incremental' everything and anything to get a (much slower) build, but that only postpones the 'die horribly' longer. The 'incremental' stuff breaks ANYTHING in the preprocessor that deals with a __LINE__ as a token, BTW.
Naturally the same code built in gnu without a problem, but I have my own subset of minor pet peeves with that. That episode where the pedantic dick-head decided that anything like 'offsetof' in C++ SHALL GENERATE A WARNING, with no way to disable said warning sort of ticked me off, because I do treat warnings as errors. The way he defended his inexcusable actions were sort of comical, too. I think it was 3.something when that happened. Had to 'work around' it by...
Code: Select all
#define offsetof(c,m) ((size_t)((c*)(4))->m)-4)
#define offsetof(c,m) ((size_t)((c*)(NULL))->m))
It made some simple code that 'created' native classes (assumed to be glorified structures in the object model I was using, not a virtual anything
) from serial IO in order to communicate with some other runtime I had to deal with at the time a lot simpler to write and use.
What I ultimately did was, well, EVIL by most people's accounts, but I really, really liked it. It made my serial stuff absolutely version-proof and VERY fast.
It broke MSVC because I wrote things like....
Code: Select all
#define MyEnum( op ) \
op( eFirst )\
op( eSecond )\
op( eThird )\
#define MyStruct( op ) \
op( base, struct, MyOtherStruct, copy(template) )\
op( x, scalar, int16, iminmax(0, 0,1000) )\
op( y, scalar, int16, iminmax(0, 0,1000) )\
op( name, string, char, "Bob" )\
op( type, enum, MyEnum, eThird )\
And then passed different 'op' macros to it that would make the class/struct, construct and destruct the class/struc, serialize the class/struct, XML read/write the class/struct, validate the class/struct, copy or clone the class/struct, etc.
The part that really choked Visual Studio.net was when I passed a set of these structs to another set of macros to declare and generate protocols and event dispatchers from a set of those definitions that would call your handler(s) with the incoming data already in a constructed class. That's what killed Visual Studio.net and blew its internal buffers, and needed to be 'engineered around'.
Code: Select all
// All structure definitions, like above
// Makes an enum, a message receiver, message sender, XML parser, XML writer, etc. from the data, based on what 'op' you drop in.
So, once you had these macros, expanding macros, expanding more macros, Visual Studio would shit its self.
Most people don't understand that when you have teams (not just ONE team, no, gotta split up everybody on the project into competing, dysfunctional cliques) working on a client/server project, it becomes critical to keep the protocol and data formats compatible. What happens is, somebody makes some small change, gets interrupted, and fails to make the 30 other changes that had to be made to support it.
So you get serial packets that are out of whack, data gets corrupted, and somebody spends hours and hours chasing the problem and eventually checking all 31 places that the change should have affected.
This kind of code gets rid of all of that. You don't 'step' into the serial code, it was all made for you by the compiler. At least, not after the core code generator's all written and verified. It makes the same operations on the data you'd have written by hand, very consistently.
Anyway, at the time, I was forced to work on a server that would build and run on either a Visual Studio/Windows environment, or a 'Unix/Linux' environment... so I endlessly tripped over all these little 'differences'. The client team wanted their own version of the server to 'debug' in Visual Studio. The server team, well, we didn't want the damned thing to crash, and to use more scalable hardware than Windows supported. Anyway, the edit/compile/test thing went sort of like this...
"All done! Let's see how it looks in Linux..."
"Crap! Let's fix that...
OK, let's see how it looks in Windows..."
Lots of little spots where I had to do... ppMS(ms), ppGNU(gnu), ppMSGNU( ms,gnu ) things, as well as the more conventional #ifdef/#else/#endif things.
Ah, C++. Most people don't understand why I loathe it so. Not only do you deal with every difference in the target OS, you deal with every difference in compiler and library implementation, and it will NEVER get better. Use it at your own peril.
C code can be object oriented, you have TOTAL control over how it works, and at least the whole object and template model which you wrote it under won't crumble before your eyes as the compiler 'evolves' into ever more deluxe lumps of excrement.
Later versions of the 'object model' looked more like this, which worked around the internal issue, and made it at least 'step' in debuggers...
Code: Select all
record_var( z, float32, 0.0f )
record_var( y, float32, 0.0f )
record_var( x, float32, 0.0f )
record_achar( name, char, 32, "unnamed" )
record_obj( stars, starmap )
Then you'd define something and #include a factory that would define all the record_ things, include that defined string token to make a set of handlers for the data you defined, then undef and redefine the record_ things, until you had all the data declared and functions written.