Tuesday, January 5, 2010

Windows 7 GodMode

If you have Windows 7, you can create a folder called the following:

"GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}"

Then, if you type “GodMode” in the Explorer Bar, you basically get a one-stop configuration panel that handles 95% of your config panel needs from a single click without going through the fluffy layers of the “Control Panel” happy hierarchy.

http://www.tomshardware.com/news/GodMode-Windows-7-How-to,9345.html

Thursday, May 28, 2009

Another Note on Empty Structs

I mentioned this C++ Standard Violation by MSVC++ in my last post on empty structs:

- There is no padding (other than for alignment) between the last base class and the first class member or vft-pointer(s). *** NOTE: this is an over-aggressive empty-base-optimization that can break the C++ standard.

Let me explain:

The standard on empty struct inheritance specifies that separate structs of the same type should yield unique addresses. In the following code, the two addresses printed should be different in a standards compliant compiler (Intel or GCC). MSVC++ ends up printing the same address twice.

class a { public: void awork() {} };
class b : public a { public: int bdata; };
class c : public a { public: b cdata; };
c test;
a *pca=&(test);
a *pcb=&(test.cdata);
printf("Offset of c::a %d\n",size_t(pca));
printf("Offset of c.b::a %d\n",size_t(pcb));

Friday, May 1, 2009

Empty Struct / Class & Empty Base Rules for MSVC++ and GCC

I now GROK empty class (and empty base optimizations) fully on MSVC and GCC.

----------------------------------------------------------

GCC C++ follows these rules:

- class EmptyBase {}; --> sizeof(EmptyBase) == 1

- Any number of empty-bases will map to 0 in the struct offset as long as all are unique types (including parenting).

- Non empty-base parents are simply in the order declared with only padding for alignment.

- If the first member of a derived class that immediately follows empty-bases does not derive from any of those bases, it is allowed to start at the first properly aligned offset for that member that is greater-than-or-equal-to the empty-base address -- this may be the same address as the empty-bases.

- If the first member of a derived class that immediately follows empty-bases does derive from any of those bases, it will start at the first properly aligned offset for that member that is greater-than the empty-base address -- this is never the same address as the empty-bases.

- Members that are empty-classes take at least one byte of storage in the containing class.

----------------------------------------------------------

MSVC++ follows these rules:

- class EmptyBase {}; --> sizeof(EmptyBase) == 1

- The only way an empty-base class (or class derived from an empty-base) will start at offset 0 (zero) is if it is the first base class.

- A Non-empty-base class will start at the next valid alignment offset for the base class.

- All empty-base classes will appear to have zero effective storage in the derived class and do not affect the current offset unless followed by another empty-base class (or class derived from an empty-base) in which case you should see the following rule.

- An empty-base class (or class derived from an empty-base) that follows an empty-base class (or class derived from an empty-base) will add 1 to the current offset position before padding to the proper alignment for the class.

- There is no padding (other than for alignment) between the last base class and the first class member or vft-pointer(s). *** NOTE: this is an over-aggressive empty-base-optimization that can break the C++ standard.

- Members that are empty-classes take at least one byte of storage in the containing class.

Thursday, April 30, 2009

The C++ Empty Struct Conundrum

Empty structs are treated differently in C++ than in C. Heck, they're treated differently by different C++ compilers :-(

Here's some weirdness with empty structures being treated differently (i.e. different offsets, sizes, binary layout) between C and C++.

struct foo { };
struct foo2 { };

struct bar
{
    foo var1;
    int var2;
};

struct bar2 : foo
{
    int var2;
};

struct bar3 : foo
{
    int a,b;
};

struct bar4 : foo
{
    bar3    var3;
};

struct bar5 : foo, foo2
{
    int    d;
};

struct bar6 : bar2, foo2
{
    int    d;
};

struct bar7 : foo2
{
    bar2    v;
    int        d;
};

C89
    sizeof(foo) == 0
    sizeof(bar) == 4
    rest are C++-only (inheritance)

C99
    empty "struct foo" not allowed
    sizeof(bar) == 4
    rest are C++-only (inheritance)

C++ Standard (comments show where the C++
        standard requires padding / wasted space)
    sizeof(foo) == 1 (* typical value)
        -- sizeof(foo) != 0   (usually 1 but 
        possibly some other value that is
        compiler/alignment dependent)
    sizeof(bar) == 8
        !!! Wasting space on empty struct !!!
    C++-only:
    sizeof(bar2) == 4
    sizeof(bar3) == 8
        OK - no padding before first member
    sizeof(bar4) == 12
        !!! pad before first member due to
        identical-empty-base conflict between
        base class and first member
    sizeof(bar5) == 4
    sizeof(bar6) == 8
    sizeof(bar7) == 8

GCC C++ (PS3): -- Fully compliant to Standards
        with best-allowed empty-base-optimization
    sizeof(foo)  == 1
    sizeof(foo2) == 1
    sizeof(bar)  == 8
    sizeof(bar2) == 4
    sizeof(bar3) == 8
    sizeof(bar4) == 12
    sizeof(bar5) == 4
    sizeof(bar6) == 8
    sizeof(bar7) == 8

MSVC++
    sizeof(foo)  == 1
    sizeof(foo2) == 1
    sizeof(bar)  == 8
    sizeof(bar2) == 4
    sizeof(bar3) == 8
    sizeof(bar4) == 8
        !!! NONCOMPLIANCE !!! -- sizeof() should be 12
         - overaggressive empty-base-optimization
        (bar4::foo not allowed to resolve to
        same address as bar4.var3::foo) 
    sizeof(bar5) == 8
        Wasted Space - standard allows
        empty-base-optimization of foo & foo2
    sizeof(bar6) == 12
        Wasted Space - standard allows
        empty-base-optimization of foo & foo2
    sizeof(bar7) == 8



-------------------



struct NullCounterNoInit
{
    FORCEINLINE void Inc()            { }
};


struct ThreadOwnedCounter
{
    UINT32    m_nCountVal;
    FORCEINLINE UINT32 Inc() { return(++m_nCountVal); }
};


template 
class Test1
{
    TCounter    counter;
    int            foo;
    int ReadFoo() { counter.Inc(); return(foo); }
}

template 
class Test2 : TCounter
{
    int        foo;
    int ReadFoo() { TCounter::Inc(); return(foo); }
}

sizeof(Test1) == 8
    !!! Wasting space on empty struct !!!
sizeof(Test2) == 4

sizeof(Test1) == 8
sizeof(Test2) == 8

Friday, August 22, 2008

Vista UAC not compatible with VS2005

So I tried installing Visual Studio 2005 on my Vista machine at home. After installing a default install of VS2005, you need to install three service packs to run it on a Vista machine:

  1. Visual Studio 2005 Service Pack 1
  2. Visual Studio 2005 Service Pack 1 Update for Windows Vista
  3. SQL Server Express Service Pack 2 (the SQL Server Express is installed by the default VS2005 installation but it's not Vista compatible without the service pack update)

So anyhow after that, it is recommended that you set the VS2005 app to "Run As Administrator".

Even then you'll probably run into a whole hose of issues noted by Microsoft.

The big three issues I ran into immediately even after doing this were:

  • Double-clicking on a file (*.cpp) launches VS2005 but fails to open the file in VS2005
  • Drag-and-Drop of a file(*.cpp) from Explorer to the VS2005 Editor Pane fails to open the file in the editor
  • Drag-and-Drop of a file(*.cpp) from Explorer to the VS2005 Project Pane fails to add the file to the project

Now the Drag-and-Drop issues (where VS2005 is the target for the 'Drop') also seem to occur for P4 and other programs.

Supposedly there are two ways to fix this:

  1. Set all your programs that could Drag-and-Drop to VS2005 to "Run as Administrator"
  2. Disable UAC

#1 is a bad idea since I'd have to Run as Administrator for Explorer which defeats a big chunk of UAC anyhow. Plus it'd be a pain to enable this for any program that could Drag-And-Drop to VS2005 (although right now that's probably only 3 programs for me: Explorer, P4, and FileLocator Pro).

I ended up disabling UAC (#2) for now which is unfortunate since UAC would be a good idea if it worked without extreme inconvenience to VS2005 users. However, disabling UAC also causes the Windows Security Center to put an angry icon in the system tray :(

Update: I tried re-enabling UAC and doing #1 but it turns out that #1 doesn't work. VS2005 only allows drag-and-drop with UAC disabled!

Monday, August 11, 2008

The VirtualBox Snapshot Manager Sucks

If you use the snapshot manager under VirtualBox, this post may keep you from inadvertently losing your most recent work in your VM.

I had VirtualBox mostly working but I borked my VM hard (disk errors on the vdi file) by trying to run DPaint (yup old DOS program) under it just for kicks because running crappy old software that's not compatible with your current OS is an ideal way to test a Virtual Machine. Well, VirtualBox didn't like DPaint. Not only did it hang the VM instance, but the VirtualBox app itself hung and I had to kill the app. This ended up corrupting my VDI (virtual disk image) file.

No harm done though... I made a snapshot after my clean install, and then another snapshot after applying all the XP updates, ie 7, WMP11, antivirus, etc, etc. Just revert to the last snapshot and I'd be fine.

So I did a revert but thanks to their crappy snapshot manager, I actually jumped back past my last snapshot and ended up blowing away changes (which was several hours of updating, installing, and tweaking to get XP running just right after the clean install).

Turns out in VirtualBox, if you "Revert to Previous Snapshot", it deletes your current state *AND* your last snapshot and goes to the second-to-last snapshot (while destroying your last actual snapshot). If you want to just revert to your latest snapshot, there is something like "Discard Current State" which really isn't that intuitive. If you have something that could potentially throw away a bunch of work in a non-recoverable fashion, your choices and explanation of the choices should be a bit more clear.

In VirtualBox, snapshots are linear -- there is no branching. Reverting to a snapshot is a destructive process that cannot be undone, and it's confusing because you can either revert to your latest snapshot (which they call reverting to current rather than revert to snapshot) or revert to the snapshot before that (which throws away all current changes as well as throws away your latest snapshot). It's not intuitive and you can lose work.

VMWare is definitely nicer for snapshots. The have snapshot trees (they allow branching points for a VM) which you can selectively revert to any arbitrary snapshot in the tree. Moving to another snapshot is non-destructive and you can move back and forth between branches -- i.e. ABCD revert to C have ABCE and then go back to D.

Oh well... now that I know how the sucky snapshot editor in VirtualBox works, I'm less likely to screw it up in the future.

BTW, one other little annoyance on top of all this... if you do a disk-check at startup under XP with VirtualBox, for some reason, VirtualBox won't reboot itself after the diskcheck completes so you have to do that manually.

Sunday, August 10, 2008

VirtualBox Free VM from Sun

Virtual Box from Sun is available here:

http://www.virtualbox.org/wiki/Screenshots

So I'm a big fan of VMWare (I own VMWare 5.5) and I have been thinking about upgrading to VMWare 6.0. However, I just heard of a free competitor called VirtualBox from Sun that's supposed to be pretty good.

So last night, I played around with VirtualBox and set up an XP VM under Vista with it. It's not as slick as VMWare but for $free$ it's not bad. The seamless window integration is particularly nice.

Even though I only played with it for a couple hours, it lags behind my VMWare 5.5 in the following features:

  • VMWare has better snapshot / revision handling
  • VMWare has all-in-one-directory portable VM's (currently VirtualBox has a machine file in one dir, disk files in another dir, and entries in a global xml table in a third dir)
  • Much faster 3D acceleration (VMWare does fairly decent DX8.1 in 5.5 and below and DX9 in 6.0 and above)
  • Multicore support (VMWare supports two virtual cores for multithreading)
  • Networking support (NAT only / I couldn't get bridging to work so I couldn't get Windows File Sharing between host and guest with my Vista Host since the guest didn't map to the same subnet)
  • Audio issues (the SB16 emu didn't work at all / you have to use the ICH for audio in XP guest)
  • Configuration is more painful than it should be... the default setup values are all too low (i.e. memory at 192MB, Vid Mem at 4 MB when you need at least 10 for seamless windowing) You need to tweak all the values and you won't find out that a feature isn't available until it fails and you have to shutdown the VM and go back and tweak.
  • Built-in shared directory implementation is non-obvious (you'll have to actually follow a walkthrough or manual to use them on VirtualBox)

I'm sure it would lag even further behind VMWare 6.0 (or the beta 6.5). However, for casual non-3D use (i.e. safe browsing, backwards app compatibility) it's not bad. If you were doing a lot of revisioning and deployment, needed reliable audio or 3D, or need bridged networking, you're better off with VMWare.

Here's where VirtualBox better than VMWare:

  • Free (vs $189 full price / $99 upgrade)
  • Vista Host support (my VMWare 5.5 only does XP and I have to pay to get VM6.0 if I want to run under Vista)
  • Seamless window mode is very nice (makes VM windows appear similar to host windows but I think this is in VMWare 6.0 as well)
  • Supposedly better 64-bit OS support (host or guest)
  • Supposedly better performance for non-3D software (although they both feel about the same speed in the tests I've done)


My out-of-the-box experience is that VMWare is much easier to use and setup and easier to make portable VM's. VMWare is easier to maintain with it's advanced snapshot management as well. Most of the reasons why VirtualBox is better from my simple testing boils down to the fact that it's free but if it's good enough, why pay for an alternative ?