Visual Studio
Thursday, March 1st, 2007So, I’ve been doing some work on a network visualisation program called BSOD (Don’t ask), cleaning up code here, tweaking some stuff from there. Anyway I’ve got it running well under Linux. The final thing to do before a new version is released is compile it under windows.
Now, I’ve not seriously used Windows since about 1995. When Windows 95 was released my current computer more or less defined the minimum requirements, and through various events ended up using Linux. So this experience with programming under Windows was….. educational. I’m not unbiased in this; I’m used to doing things under Linux. I’ve been using Visual Studio 2005 under XP.
So, what was the experience like? Well, it wasn’t my favourite experience. Some things don’t work as I expect (Every time I try to use the middle click to paste I realise that no… I have to explicitly copy and paste it). Things are different so thats ok. What did bug me was Visual Studio. People explain to me how great Visual Studio is, but my experience was somewhat… different.
Solutions and Projects confused me. Does a solution hold projects, or do projects hold solutions? Why can’t I have multiple solutions open at once? One for building an external library and one for building the main program? Given two checkouts on the same machine, how can I tell what the path is to the file I have open in any obvious way? (I assume theres some way to find out).
Window’s weird ideas about files being open not being able to be touched is annoying. Especially when visual studio suggests that this is probably due to me using version control (wtf?).
Visual Studio recommends poor programming practises. Wizards produce bad code. One example is the skeleton code it produces when you generate a new console application:
int _tmain(int argc, _TCHAR* argv[])
This uses “_tmain”. Now in C/C++ identifiers that begin with an “_” are reserved for the standard library. Programs should avoid ever using identifiers that start with a “_” so that the standard library can use them for symbols that shouldn’t be leaked into the application. For instance <ctypes.h> on MacOS defines almost every single letter variable with a _ in front of it.
Visual studio doesn’t really try to be a C compiler. But it’s almost insulting to have the compiler tell me that my C program doesn’t conform to the ISO C++ specification. It makes me angry to have the compiler suggest changing portable functions (eg strdup()/snprintf()) to less portable versions. C99 was released 8 years ago, yet Microsoft don’t even mention <inttypes.h> / <stdint.h>. These headers are important for portability for applications that deal with integers of fixed length. Sure VS has it’s own non-portable ways of specifing these, but that just makes the oversight more annoying. The solution so far has been to implement our own <inttypes.h> and <stdint.h> for windows and ship them. Frustrating.
Linux doesn’t really have any one elegant way to describe where the library path, library name(s), and header files are for installed library. Two that spring to mind are pkgconfig, and *-config programs. However despite these rather obvious flaws, I don’t see any way to deal with this in Visual Studio eitherrather you have to add the library name(s), the header search paths, and the library search paths. And surprisingly library names aren’t selectable. Plan9’s solution is to have a “#pragma” that specifies the library to link against. Thus if you #include a header, you automatically end up linking against any library that they use.
Microsoft have said in the past that Linux is based on 30 year old technology. Under Linux things have been tried and tested. If they were found lacking then they have been replaced. Windows however appears to have managed to accumulated bizarre limitations directly inherited from the 16bit days. One example which bit me in the butt was that I can’t malloc() in my program, and then free() it in a library. Why? Because in the 16bit world malloc() allocates out of a pool of memory per DLL and a seperate one from the main program. But the limitations is annoying.
DirectX stuff appears to be complicated and rapidly changing. The code I’ve been playing with was written against DirectX 8. DirectX 8 however appears deprecated. (The documentation discusses it’s support for the new and upcoming “whistler” operating system!). However now it appears difficult to compile code against DirectX 8 now, newer SDK’s are geared more towards DirectX9 and DirectX10.
Many of the key combos I remember from my Turbo C++ days still work. The debugger works much the same way. I enjoyed playing with “Run to Cursor” again after all these years. I find using “bt full” from gdb to be much more useful than the annoying “watches”/”call stack”/”locals” interface, which appears to be more limited than I remember it being when I was using IDE’s in DOS.
I miss the flexibility I feel I lose moving to VS. VS seems to want things done in it’s preferred way. Sure you can override it, but you’re swimming against the current. I miss regular expressions, grep, and sed. For example “Find all references” doesn’t show any context, how do I know which one is the one I want? Why can’t I compare two files to see how they differ like I can with diff(1)?
I feel like I’m in Beijing and I don’t speak the language.