-2

I may be missing something, or I may be asking CC for something I shouldn't be, but -

Is there a way to specify that a parameter "may or may not be null" without coming off as entirely redundant?

For instance, imagine this contrived example:

string F(string x)
{
    Contract.Requires(x == null || x != null);
    return x ?? "Hello world!";
}

With the above, the ccchecker kindly lets me know of the redundancy:

CodeContracts: Suggested requires: This precondition is redundant: Consider removing it.


Update: Matt Burland summed up the intent, if that changes responses any,

[What the] OP wants to be able to do is make a note that they didn't forget about adding a requirement ..

user2864740
  • 60,010
  • 15
  • 145
  • 220
  • The precondition is redundant. I'd follow it's advice and remove it too. If it can be null or not null then it can be anything. – Matt Burland Jan 06 '15 at 16:20
  • @MattBurland Is there a way to make this assumption explicit in CC? Say if I am the next programmer coming through.. – user2864740 Jan 06 '15 at 16:21
  • I don't know. Add a comment? I see what you are saying, but I'd hope the lack of a precondition would be interpreted as "this can be null or not null". – Matt Burland Jan 06 '15 at 16:25
  • Your code actually takes into account the fact that x can be null, you are using "??". A future developer shouldn't think you forgot about it. They could think you had forgotten about it if you returned x directly. In a case like this I would add a comment, notice that adding the contract doesn't really clarify anything. If you think is important to place the contract, do it but add a comment. This is a subjective matter and you should do as you consider it will best for your project, that is way it only suggest to remove the contract and doesn't force you to. – Dzyann Jan 06 '15 at 17:12
  • @Dzyann It's a very trivialized case. I chose `??` on the subsequent line precisely it shows the code doesn't care (and can be trivially verified) if there is a null or not. In real code the final condition and/or usage would be more complex. The goal is to make that assumption, that both cases follow as valid static analysis paths that don't violate other constraints, more explicit within the context of CC. Basically I'd like to add a "verification hint" much as some languages support "type hints". – user2864740 Jan 06 '15 at 17:16
  • I realize it is trivial, but even in a none trivial case, your code, unless it has errors (most likely), takes into account the fact that it can be null. What I am saying is that I don't think you will be able to find a simpler way to place the contract in CC, but I don't think what you doing is wrong if you think is important. – Dzyann Jan 06 '15 at 17:20

3 Answers3

2

If there is a requirement that the value can be anything, then just don't require anything, rather than explicitly adding a requirement that the value can be anything.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • Is there a way to make this assumption explicit in CC, even when removing the Requires? – user2864740 Jan 06 '15 at 16:22
  • @user2864740 Why would you want to, even if you could? You're trying to explicitly require *nothing*. What you already have does succeed in requiring nothing; it's a superfluous requirement. If you want that, you already have it. It'd be the same as just writing a comment though, as it wouldn't ever accomplish anything. – Servy Jan 06 '15 at 16:24
  • I accept that using Requires is redundant - but how can I tell CC about this anyway? – user2864740 Jan 06 '15 at 16:27
  • 1
    @user2864740 You *don't*. That's the whole point. You don't need to explicitly state that you don't have any requirements, you just don't state any requirements. That's the entire text of the answer. If you want to add a redundant requirement, you can; if you don't, then you don't. There is no way to both add and not add a superfluous requirement. – Servy Jan 06 '15 at 16:29
  • 3
    I'm guessing what the OP wants to be able to do is make a note that they didn't *forget* about adding a requirement, there really isn't one. I don't know that there's a meaningful way to express that however. – Matt Burland Jan 06 '15 at 16:34
  • @MattBurland As I said, he can add the superfluous requirement if he really wants, or just leave a comment. There is no *meaningful* way to express a meaningless requirement. There are of course plenty of meaningless ways of expressing a meaningless requirement. – Servy Jan 06 '15 at 16:36
  • @lrineau In what way does this not answer the question? It explicitly answers the exact question asked. – Servy Jan 06 '15 at 17:15
1

Code Contracts does not need to be told that a parameter can be null. Users need to be told that a parameter can be null. For this, you have XML Documentation Comments:

/// <param name="x">
/// <para>The string...</para>
/// <para>-or-</para>
/// <para><see langword="null"/> if ...</para>
/// </param>
/// <returns>
/// <para><paramref name="x"/> if it is not <see langword="null"/>.</para>
/// <para>-or-</para>
/// <para>The string <c>Hello World!</c> if <paramref name="x"/> is <see langword="null"/>.</para>
/// </returns>
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • True, but say I am a developer in the code (and assuming that I'm using the CC feature to annotate the comments based off of requires/ensures) - how can I get the assertions more visible (in the code)? – user2864740 Jan 06 '15 at 16:51
0

This can be done with Code Contracts, but not with Require. With require the checker always warns that it is redundant: even though the redundancy is the "correct" intent it is expressed incorrectly.

Instead, Assert can be used as it is treated slightly differently and doesn't cause the warning. (However I cannot find where this warning behavior difference is documented.)

This tells the checker that the condition, even though it is a tautology, should be true and statically validated. There are also slight difference in the resulting runtime artifacts, if any, but this solved the goal of the question.

string F(string x)
{
    // No Requires as there is no external restriction on x
    // .. but we can still ask the analyzer to play along.
    Contract.Assert(x == null || x != null);
    return x ?? "Hello world!";
}
user2864740
  • 60,010
  • 15
  • 145
  • 220