开发者

IN/OUT Parameters and how to work with them in C++

When reading documentation on functions from external libraries of different kinds I have always seen the documentation state that a variable has to be [IN/OUT]. Could someone give me a detailed understanding on how [IN/OUT] relates to parameters of a function being passed by reference or by value.

Here is an example of a function I have come ac开发者_JAVA技巧ross that tells me it needs an [IN/OUT] parameter:

Prototype: ULONG GetActivationState( ULONG * pActivationState );

Parameters

  • Type: ULONG*
  • Variable: pActivationState
  • Mode: IN/OUT


This part applies to all types of paramters - most library interfaces try to be C compatible, so it is more common to pass parameters by pointer, rather than by reference.

IN: When a parameter is listed as IN it is a guarantee being offered by the interface that it won't modify that parameter. In my opinion, this is better conveyed by marking the parameter as const, then the language itself will prevent modifications to the value. If this parameter is being passed by value, it is inconsequential whether it is marked IN in the documentation (or const in the prototype) since the parameter is local to the function anyway. But to avoid copying it may be passed by reference or by pointer, in which case the const keyword becomes very important.

OUT: A parameter marked OUT usually means that the value of the parameter when it is being passed to the function is not of any importance. In fact, if it being passed by pointer, it may even be required to be NULL, and the function will allocate memory and pass a value back to you.

IN/OUT: An IN/OUT parameter usually indicates something where both the input and output values are meaningful. For instance, if you have a library function that fills a buffer, it may require you to pass a pointer to the buffer, along with another pointer indicating the length of the buffer. When the function returns, the second pointer may contain the actual number of bytes that have been written to the buffer.


This parameter is in/out because you provide a value that is used inside the function, and the function modifies it to inform you about something that happened inside the function. The usage of this function would be something like this:

ULONG activationState = 1; // example value
ULONG result = GetActivationState(&activationState);

note that you have to supply the address of the variable so that the function can get the value and set the value outside the function. For instance, the GetActivationState function can perform something like this:

ULONG GetActivationState(ULONG* pActivationState)
{
    if (*pActivationState == 1)
    {
    // do something
    // and inform by the modification of the variable, say, resetting it to 0
       *pActivationState = 0;
    }
    // ...
    return *pActivationState; // just an example, returns the same value
}

Note how:

  1. The function accepts the parameter as a non-const pointer to an UINT. This means it may modify it.
  2. The function can access the value you gave to the parameter by dereferencing it
  3. The function can modify the parameter again by dereferencing it.
  4. The calling function sees the activationState variable holding the new value (0 in this case).

This is an example of "pass by reference", which is performed by using pointers in C (and also with references in C++.)


Generally, things marked as IN/OUT will be passed via a non-const pointer or reference, allowing the function to modify the variable directly, as well as read it. Be sure to check the documentation to see if it expects the value to be set prior to passing it in.

Parameters marked as IN will be passed by value, or by constant pointer or constant reference, disallowing the function from modifying the variable.

C++ doesn't enforce OUT-only parameters, but generally they will be passed using non-const pointer or references, similar to IN/OUT.


If a parameter is OUT, it has to be passed by reference. A purely IN parameter would be usually passed by value or const reference, if the cost of copying is too high (nothing prevents the designed from passing it by reference, but it's not very good design IMHO). An IN/OUT parameter must be passed by reference.


I'm of a mixed mind regarding the use of in, out, and in/out.

Upside: When done properly, it communicates intent to the reader of the documentation.

Downside: Far too often it is not done properly. Those designations obviously are not a part of the language; they are either in comments or are in some document that is maintained separately from the code. I've seen far too many cases where a parameter was marked as "out" but the first thing done in the code with that parameter is to use it as a right-hand side value.


You can use by value (simply types) or by constant reference const & for input only parameters. Use non-const reference & or pointer * as in/out parameter to change the value of the variable. You can also use a pointer reference * & to allow you to change the address the actual pointer points to (in/out). As Dave Smith pointed out there is no out only parameter in C++.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜