Look at following statement:
HANDLE hFile = ::CreateFile( instructions, 0, 0, NULL, CREATE_ALWAYS, 0, NULL );
Can you guess what means 6-th parameter (with third 0 passed as argument)?
Do you know the type of 4-th parameter (with first NULL passed as argument)?
Stop maintenance nightmare
Your code includes tens to thousands function calls:
• to system API,
• to C++ standard library,
• to third-party libraries,
• to your own classes and free functions.
Readers of your code (including yourself) do not remember the exact ordering, type and purpose of each parameter/argument in each function call. So help your readers!
From in-place arguments to parameter descriptors
Instead of passing argument directly to the function, use parameter descriptors - appropriately named temporary variables, initialized with arguments you want pass to the function.
Now everybody instantly sees:
• the type of each parameter and argument,
• the role that parameter/argument plays during the function call.
Parameter descriptors are good documentation of the function being called.
Listing 2. Parameter descriptors make the code readable
{
LPCTSTR file_name = instructions;
DWORD access_mode = 0;
DWORD share_mode = 0;
LPSECURITY_ATTRIBUTES security_attributes = NULL;
DWORD actions_to_take_regarding_file_existence = CREATE_ALWAYS;
DWORD attributes_and_flags_or_security_quality_of_service = 0;
HANDLE template_file_supplying_attributes = NULL;
HANDLE hFile = ::CreateFile(
file_name, access_mode,
share_mode, security_attributes,
actions_to_take_regarding_file_existence,
attributes_and_flags_or_security_quality_of_service,
template_file_supplying_attributes
);
}Recommendations
When you create the parameter descriptor, make sure it has exactly the type of the correspondent function parameter. That will help you detect type mismatches between actual argument and formal parameter.
I recommend enclose parameter descriptors and the function call in curly braces in order to limit the visibility and the lifetime of parameter descriptors.
Do not copy brainlessly
When inexperienced developers create parameter descriptors for WinAPI functions, they often copy the names of parameters from API documentation to names of parameter descriptors. That shortcoming reduces the usefulness of parameter descriptors, because API names often are too cryptic. Can you guess the purpose of the parameter
My advice: do not copy parameter names from the documentation. Instead, describe their meaning. Well, copy - not the name, but the sentence describing the parameter - to your code. Then convert sentences to parameter names.
When inexperienced developers create parameter descriptors for WinAPI functions, they often copy the names of parameters from API documentation to names of parameter descriptors. That shortcoming reduces the usefulness of parameter descriptors, because API names often are too cryptic. Can you guess the purpose of the parameter
dwCreationDisposition? My advice: do not copy parameter names from the documentation. Instead, describe their meaning. Well, copy - not the name, but the sentence describing the parameter - to your code. Then convert sentences to parameter names.
Summary
Do not assume the reader of your code knows the type and purpose of arguments passed to the function or returned from the function. State them explicitly via parameter descriptors.
No comments:
Post a Comment