C++

Be Careful With Bitfields
C++ c win32
Published: 2005-09-07
Be Careful With Bitfields

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

1
2
3
4
5
6
7
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?

Read more...
Use Constant References For Input-Only Parameters, Pointers Otherwise
C++ c++
Published: 2005-09-06
Use Constant References For Input-Only Parameters, Pointers Otherwise

This is a style issue, so there is no right or wrong, but I suggest using a const reference for an input-only paramater to a C++ function and a pointer for an input/output or output-only parameter. This makes it slightly more obvious that the parameter might be modified by the function.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ReturnType Function
    (
    const ParamType& inputParam,
    ParamType* inputOutputParam,
    ParamType* outputParam
    )
{
    // ...
}

void User()
{
    ParamType inputParam;
    ParamType inputOutputParam;
    ParamType outputParam;

    // Note the &s -- this is a bit of a warning something
    // might happen to inputOutputParam or outputParam...
    ReturnType ret = Function
        (
        inputParam,
        &inputOutputParam,
        &outputParam
        );
}
Write Functions Which Take Iterators, Not Collections
C++ c++ stl
Published: 2005-09-05
Write Functions Which Take Iterators, Not Collections

If my experience is typical, this is a very common construct:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
ReturnType Function
    (
    const std::vector<T>& container
    )
{
    typedef std::vector<T>::const_iterator iterator_t;
    for (iterator_t iter = container.begin();
         iter != container.end();
         ++iter)
    {
        // Work with *iter
    }
}

The problem with this construct is that you have forced a container choice upon the user of your function. Slightly better, and basically your only choice when interoping with C, is this:

Read more...
Prefer Iteration To Indexing
C++ c++ stl
Published: 2005-09-02
Prefer Iteration To Indexing

I’ve seen the following STL construct countless times:

1
2
3
4
std::vector<T> container;
for (int i = 0; i < container.size(); ++i) {
    // Work with container[i]
}

Unless otherwise necessary, it is better to use an STL iterator because it enables you to more easily change the underlying container. You can isolate the code changes required to one line by using typedef, as in:

Read more...