0

So I have a function in C like this:

void crunch(const char *in, char *out, size_t inLen, size_t outLen)
{
    //...
}

If the two buffers overlap, the function may mess up the input buffer as well, while generating output.

  • What's the general practice?
  • Should I always consider overlapping buffers when implementing functions like this?
  • Should I assume that the user won't pass overlapping buffers?
  • Should I always document whether the function works well or not with overlapping buffers?
1
  • It this not a reason for restrict? If overlapped buffers have well defined functionality, use void crunch(const char *in, char *out, ...) else use void crunch(const restrict char *in, char restrict *out, .... Feb 17, 2014 at 19:13

2 Answers 2

2

That depends entirely on the philosophy of your software component.

Especially in the C world, it is considered perfectly normal to produce undefined behaviour on violated preconditions, if this makes the implementation simpler. In other contexts, your users and fellow implementers might find this completely unacceptable and would demand that you behave robustly by verifying the specified boundaries and doing an internal copy if necessary.

The only thing that all practitioners should agree on is that you have to explicitly declare what happens when the inputs overlap - even if the effect is undefined.

0

First, the method must declare a contract. A contract says: if you do X, I will do Y. See http://en.wikipedia.org/wiki/Design_by_contract.

It must either (a) require non-overlapping buffers as a pre-condition or (b) allow overlapping buffers.

In case (a), the contract should be enforced for at least some part of the development/testing lifecycle. That is, you should add code to the function that tests for non-overlapping buffers and asserts (fails) if it's not satisfied. Since this code probably has performance constraints, you probably want to be able to switch the test on for development and testing and off for production, but that's a choice you make.

in case (b), you add code to permit overlapping buffers. That might be a different, possibly slower, algorithm or whatever technique you choose.

  • What I describe is best practice. I have no way of knowing if it's general practice.
  • You must consider overlapping buffers.
  • You should assume nothing beyond your contract.
  • The contract provides the documentation.
4
  • On a related note, a method might specify a behavior or range of behaviors that may be caused by overlapping buffers. For example, a method might specify that it will copy the first item of the source to the first item of the destination, then second item to second item, etc. Such a method might be used to copy a pattern throughout the destination. A method which for efficiency tries to copy multiple items at once would have to special-case certain overlap scenarios, but a method which simply copies one item at a time could simply ignore the overlap scenario.
    – supercat
    Apr 28, 2014 at 22:54
  • @supercat: You are describing what was observed behaviour in naive implementations of memcpy() and similar, but not something that I have ever seen explicitly documented. Given the performance implications, it would not be a first choice.
    – david.pfx
    Apr 28, 2014 at 22:59
  • A method's caller should not rely upon such behavior unless it is expressly documented, and a method author should only document such behavior if it is apt to be sufficiently useful as to justify requiring future versions that might caching things or copying them in other more efficient sequence to ensure that the operation would match promised semantics. On the other hand, one could document a method as saying that it will behave as though it copies things in arbitrary sequence, and have a "debug" version that randomizes the sequence. Code which can work with such a version...
    – supercat
    Apr 28, 2014 at 23:10
  • ...might be fine even if the regions overlap (if it really doesn't care what happens to the particular parts of the array where the behavior is ambiguous).
    – supercat
    Apr 28, 2014 at 23:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.