MSDN-speak: What does it mean when a parameter contains a value?


I've seen some confusion over this, heck I've been confused by this, so I figured I'd share what I've learned.

In MSDN, you may see wording like this:

pdwResult [out] When the function returns, contains a pointer to a DWORD value that contains the result of the computation.

What they're trying to say is that the pdwResult is a pointer to a DWORD that receives the result of the computation. Personally, I take issue with both uses of the word "contains", but they tell me that that is their standard for describing [out] parameters, so you'd better get used to it.

When they say that the parameter contains a value, they mean that the you passed that value as the parameter. I prefer to think of the parameter being the value; the parameter is just a convenient name for the value that the caller passed. The MSDN approach is to think of the parameter as its own variable which therefore contains a value, as variables do. In this specific case, they are saying that pdwResult "contains a pointer" to mean that the parameter is itself a pointer that you pass in.

Now on to the second half. When they say that the pointed-to value contains the result, they mean that the function itself writes to the pointed-to value. The opening phrase "when the function returns" is intended to indicate this, but I have two issues with that approach.

First, it seems to modify the wrong verb. Since it's at the beginning of the sentence, the temporal clause appears to modify the first "contains" and not the second. "When the function returns, the parameter contains a pointer...", suggesting that perhaps when you initially called the function, the parameter didn't contain the pointer and that the statement becomes true only when the function returns.

Second, it doesn't emphasize that the function itself sets the value. You can read the sentence passively, as if to say, "Well, when the function returns, there's stuff there, who knows how it got there, maybe it was there all along, maybe you were expected to put it there first, sometimes things just happen to be that way, you know?" Sort of like, "When I get home, the lights are on." Maybe you turned on the lights remotely from work before you left for home. Maybe they are on a timer so they turn on at the same time every day. Maybe they were on all day. Heck, you're not even ruling out the possibility that the lights have psychic powers and turn themselves on as a way of welcoming you home.

Anyway, now you know what that sentence means when you read it in MSDN. It's not how I would've written it, but I'm not the chief editor of MSDN.

Comments (32)
  1. John says:

    It’s hard to come up with a good standard for documenting APIs; sometimes certain APIs just need their own "natural language" description that doesn’t fit into the standard.  I prefer something like this:

    pdwResult [out] The function sets the value pointed to by pdwResult to the result of the computation.

    or maybe even:

    pdwResult [out] The result of the computation is stored in the location pointed to by pdwResult.

  2. Steve Nuchia says:

    Maybe the MSDN-speak version of MSDN content should be regarded as the source form and English should be one of the many natural languages into which it gets translated.  Then somebody who has a passing familiarity with at least one of the dialects of English used outside of Redmond might have a whack at it.

  3. Neil says:

    Even a simple tweak to the word order makes the phrase much more understandable:

    Contains a pointer to a DWORD value that, when the function returns, contains the result of the computation.

    Note that this is virtually true in the case of a system call as even your user-mode debugger doesn’t get to see the exact time at which the value gets to contain the result!

  4. daves561 says:

    The entire “when the function returns” clause should be omitted, because it is implicit in the [out] specification. If you don’t know what [out] means, you need to back up and read some introductory literature. Readers who are familiar with the construct shouldn’t be punished every time MSDN needs to refer to an [out].

    That being the case, I vote for:

    pdwResult [out]: A pointer to a DWORD value that is the result of the computation.

    [And then you get people who read that and say, “But that’s a Catch-22! How can I pass a pointer to the result of the computation into the function? I don’t have the result of the computation. If I did, I wouldn’t need to call the function!” -Raymond]
  5. Brian says:

    We have a similar problem here where our new documentation writer is trying to "standardize" our documentation, thereby turning it in to an unreadable mess.

    but hey, at least it’s consistently an unreadable mess now.

  6. Illuminator says:

    I say:

    pdwResult [out]: A pointer to a DWORD that will receive the result of the computation.

  7. SuperKoko says:

    daves561 wrote:

    "

    pdwResult [out]: A pointer to a DWORD value that is the result of the computation.

    "

    If you do know what [out] is, you probably know what a C prototype is, and so, "A pointer to a DWORD value" is useless.

    So, the sentence becomes:

    pdwResult [out]: Points to the result of the computation

    The name of the variable says it all. This can be condensed to:

    pdwResult [out]: Self-describing.

  8. Stefan says:

    I sympathize with the writing team’s job. It’s very hard to accurately describe thousands of functions, structures, classes, etc. Unfortunately, all developers suffer because MSDN’s text is sloppy (and downright inaccurate) in many, many places. If the MSDN doc had more example code, such awkward text wouldn’t be as much of an issue. (Although you’d still have inaccurate descriptions and code.) It’d be nice if there were test code used by the developers that could also be posted to the doc.

    I like the Community Content feature that lets people correct and expand the doc.

  9. daves561 says:

    SuperKoko:

    "The name of the variable says it all. This can be condensed to:

    pdwResult [out]: Self-describing."

    Yup. Works for me. :^) (tho you could argue that pdw is a convention thusly deserving a clarification, whereas [out] is a defined axiom of the syntax)

    Must be something in the coffee this morning; I find myself curmudgeonly defending the terseness. This is technical documentation for an engineering discipline. I don’t look at, e.g., fancy VLSI diagrams and identify every component immediately, but presumably an electrical engineer would. And that’s okay. This just seems like excessive hand-holding. I’m not endorsing arcaneness as an end in and of itself. I’m just trying to spare programmers’ brains from sifting through a zillion function header comments that start with "This purpose of this function is to…"

    Color me grumpy. I’ll lighten up tomorrow…

  10. Dodgson says:

    Name/Is/Called argument, continued. AKA, semantics are fun to play with.

    If the following bit from "Through the Looking Glass" makes sense, then you’ve programmed in C

    "The name of the song is called ‘Haddocks’ Eyes.’"

    "Oh, that’s the name of the song, is it?" Alice said trying to feel interested.

    "No, you don’t understand," the Knight said, looking a little vexed.

    "That’s what the name is called. The name really is ‘The Aged Aged Man.’"

    "Then I ought to have said ‘That’s what the song is called’?" Alice corrected herself.

    "No, you oughtn’t: that’s quite another thing! The song is called ‘Ways and Means’: but that’s only what it’s called, you know!"

    "Well, what is the song, then?" said Alice, who was by this time completely bewildered.

    "I was coming to that," the Knight said. "The song really is ‘A-sitting On A Gate’: and the tune’s my own invention."

  11. Greg D says:

    Interestingly (and perhaps sadly), phrasing such as described in the article is largely responsible for my kneejerk fear of older MSDN docs.  I applaud the effort that’s gone into the .Net docs as I personally find them to be vastly more readable and, correspondingly, more useful.

  12. JamesNT says:

    While we do have to deal with the occassionally poorly wording documentation, I don’t take exception to anything I’ve seen in MSDN or TechNet.  I have certainly seen documentation far worse on many "professional" websites and MS’s very on competition.

    JamesNT

  13. mikeb says:

    FWIW, I like Neil’s phrasing. It has the advantage of (apparently) not needing a change to MSDN’s phrasing rules.

  14. Poochner says:

    As for Looking Glass, it’s not surprising that he also wrote a couple of volumes on symbolic logic.

  15. Joe says:

    I’ve never been confused by this.  I agree with MSDN’s approach, it describes thing quite clearly.

  16. MikeWasson says:

    In my docs, I use "Receives [whatever]". I feel that "Pointer to a DWORD" is redundant, given the syntax block immediately preceding. Sometimes a parameter really is self-describing, but consider:

    http://msdn.microsoft.com/en-us/library/ms700182.aspx

    Would this be better with no parameter description? I pulled this example almost at random. Not to say that it’s a perfect ref page, but hopefully it’s better than NO ref page.

  17. Triangle says:

    Why deal with pointer semantics at all? You just write:

    *pdwResult = (The result of the function);

  18. nathan_works says:

    I wonder if the advent of COM makes it confusing with the IUnknown and casting it (void**)&x. Versus here you just pass in &x to get the result.

    I’d also guess the API standardization of returning an HRESULT (or some other pass/fail/failed-this-way) return means you have to push other information to return into the parameter list. (I’m sure some obscure programming language folks will tell us that’s why $LANGUAGE is so much better, or SEH folks will say that’s why failures should be throw(), etc)

  19. MS says:

    I’m just glad that MSDN documentation is generally up to date and extensive.  I don’t know how many APIs and libraries from various places have little or no documentation at all.  And I guess once you get used to how things are generally worded, it gets to be second nature.  Of course, a little experimentation is in order if you’re not sure how it works.

  20. Ulric says:

    It’s true, you’re totally right about that temporal clause, plus the word ‘contains’, completely confuses the meaning.  In fact it seems to be wrong, but we understand it because we’re C programmers.

    A pointer to a DWORD value that will contain the result of the computation when the function returns.

  21. R says:

    Not sure how critical one should be… The order of words in a sentence can be different in non-English languages. I will speculate: perhaps the bad wording reveals that the original writer was not a native Englih speaker?

  22. Weiguo says:

    certainly not everyone everywhere is expected to have perfect English, but when one’s job entails writing documentation in English, isn’t near-native fluency important?

    as far as the documention itself goes, I do think it could be less confusing and much less awkward.  I know what it means, but only because I can tell what it’s trying to say.

  23. Peter Donnelly (MSFT) says:

    I have been writing API docs at MSFT for more than a decade, and I can’t tell you how many times this issue of [out] parameters has been discussed and how many efforts have been made to standardize the wording. In fact, I recall Raymond raising this issue with me many years ago, back when we were both working on DirectInput.

    Personally, I prefer that parameters be described as what they are when they are parameters, i.e. when they are passed. When an [out] parameter is passed, it is nothing more than the address of a variable that’s going to be initialized by the function, so I’ve always leaned towards something like "The address of a variable that receives the foo." I don’t like "A pointer to foo," since it isn’t any such thing until the function returns.

  24. steveg says:

    If [out] was a tooltip or linked to the page of MSDN documentation conventions (I presume it exists, I tried briefly to find it, SNR) then that page could what an out parameter is, which means we could have a succinct description.

    All up the MSDN documentation is excellent, although I wish it was more prescriptive. As JamesNT said, you need to see what else is out there to really appreciate it.

    Raymond, I’m a little surprised you didn’t suggest your own wording.

  25. bubbel urp says:

    "they mean that the you passed that value as the parameter."

    Sorry to the be such a grammar nazi but…

  26. 640k says:

    The parameter contains a pointer containing the address to the value.

  27. yme says:

    C has no concept of [out] parameter.  The effect of an [out] parameter of type T can be gotten in C by using a parameter of type pointer-to-T.  It is a confusion of different levels of abstraction to consider the pointer as being an [out] parameter, but it is notated as such in the documentation, and perhaps this led to the confused English description of the parameter.

  28. Michiel says:

    Really confusing, that wording in combination with the prefix. I’d expect DWORD** ppdwResult. Otherwise, there is no way that the callee can make it contain a pointer after the callee returns.

    As Raymond pointed out before, APIs are contract specifications. The caller has the obligation to set pdwResult to the address of a DWORD. This should be the first part of the documentation, so the caller knows that NULL ("I don’t need the result") isn’t allowed. The second part of the documentation is for the callee: it must store the function result in *pdwResult. Trying to combine the two sides of the contract in one sentence doesn’t help.

  29. NickS says:

    I agree with JamesNT, the MSDN docs are generally pretty good compared to what else you can find out there.  But here’s another example that had me puzzled for quite a while:

    http://msdn.microsoft.com/en-us/library/ms706241(VS.85).aspx

    "A pointer to a variable that, on successful return, points [to] an array of pointers to IDot11AdHocInterfaces."  It took me quite a while to figure out that the function does not allocate the array for you, it is the caller’s responsibility.

  30. dave says:

    I think ‘yme’ has it best, above.

    The pointer is the *mechanism* by which the output *value* can be returned.

    Note that there’s a similar potential for mechanism/value confusion on input args as well.  For example, to my way of thinking, strcpy’s input argument is a character string value; the mechanism used to pass that value is pointer-to-first-char.

    (The ‘argument value’ is the thing that strcpy operates on, namely the actual characters).

    DEC’s VMS documentation used to use a horrible parameter notation that at least had the benefit of (when correctly written) distinguishing between value and mechanism.

  31. pyrochild says:

    You lost me at "temporal clause."

  32. I’ve certainly gotten tripped up by the misordered "when" clause – it left me wondering what they meant until I found some example code.  "Oh, they just mean, ‘pass in a pointer’!  How silly of me…"

    I have no issue at all with "excessive" specificity, but while that particular inversion isn’t grammatically incorrect, it’s certainly poor usage.

    It remains a source of bafflement to me that there can be simultaneously the "hacker love of screwing with language" (http://www.catb.org/jargon/html/introduction.html) and the stereotype of programmers not knowing how to write coherently (e.g., how much *really* poorly written documentation/comments/etc. have you seen…?)  How do these states coexist?

Comments are closed.

Skip to main content