Be Careful With Bitfields

Be Careful With Bitfields

Consider the following piece of code (adapted from a real-world bug):

BOOL IsDirectory(LPCTSTR strPathName)
{
    DWORD dwAtts = GetFileAttributes(strPathName);
    if (dwAtts == INVALID_FILE_ATTRIBUTES)
        return FALSE;
    return (dwAtts == FILE_ATTRIBUTE_DIRECTORY);
}

This function will work most of the time, but every now and again it will run across a directory which it will claim isn’t one. Why?

The problem is caused because dwAtts is a bitfield (see the GetFileAttributes() documentation). Simple equality comparison isn’t appropriate, as if the directory has any other attributes (such as compressed, hidden, offline, etc.) the comparison will fail.

To test if a bit is set in a bitfield, use code of the form (dwAtts & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY or (dwAtts & FILE_ATTRIBUTE_DIRECTORY) != 0.