[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: restrict

From: Paul Eggert
Subject: Re: restrict
Date: Sun, 16 Feb 2020 13:44:02 -0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1

On 2/9/20 7:02 PM, Bruno Haible wrote:

   - If all pointer parameters point to different types, excluding 'void *',
     ISO C forbids aliasing anyway, therefore 'restrict' is redundant.

The actual ISO C rule is a bit different, since it allows aliasing between 'char *', 'unsigned char *', 'signed char *', and the other types. This means one must use 'restrict' when some pointers are 'char *' and others are not. For example:

  FILE *freopen(const char *restrict pathname, const char *restrict mode,
       FILE *restrict stream);

The same rule applies when a type *might* cause problems. For example:

  int readdir_r(DIR *restrict dirp, struct dirent *restrict entry,
       struct dirent **restrict result);

because DIR might be either 'char' or 'struct dirent' (weird, but allowable).

  - If, among the parameters, there are N parameters of type
      [const] TYPE *
    adding the 'restrict' keyword to N-1 of them is equivalent to adding
    the 'restrict' keyword to all N of them.

It won't be equivalent in general, because if the function accesses nonlocal variables the compiler can't be sure they won't alias with the Nth parameter. We should add 'restrict' to all N args, as POSIX does.

     Example: void dfacomp (char const *, ptrdiff_t, struct dfa *, bool);
     and https://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html

In glob.html, 'glob' has 'restrict' on both data pointer args, so it's not an example of this principle. 'globfree' does not have 'restrict' for the same reason 'free' does not have 'restrict' - freers are not supposed to rely on noaliasing optimizations.

   - If a function has an input parameter of type
       const TYPE *
     and an output parameter of type
       TYPE *
     then the 'restrict' keyword means that the implementation may write
     the output before having finished reading all the input.
       void arctwo_encrypt (arctwo_context *context, const char *inbuf,
                            char * restrict outbuf, size_t length);
     Whereas the absence of the 'restrict' keyword means that the
     implementation will read all the input _before_ starting to store
     the output.
       int hmac_md5 (const void *key, size_t keylen,
                     const void *buffer, size_t buflen, void *resbuf);

Yes and no. By "the implementation" do you mean the C code that implements these functions with the usual naive interpretation of that C code? or do you mean the optimized version of the C code? If the latter, I don't think I agree. If the former, I'm not sure -- but why focus on the former?

Anyway, for hmac_md5 I would think 'restrict' would also be appropriate, as we don't want to preclude an implementation that double-checks the result.

   - 'restrict' should NOT be used for multiple output parameters of the
     same type, when only a single word is written through each parameter.
     Example: ssize_t copy_file_range (int ifd, off_t *ipos, int ofd, off_t 
                                       size_t len, unsigned flags);
     Rationale: It is OK to have ipos and opos point to different elements
     of the same off_t[] array.

Ouch, this is exactly the opposite of what I would have wanted, since I want 'restrict' to tell the caller "these should not be aliases" and I want that to be true for *IPOS and *OPOS. (I'm not sure what is meant by 'single word' here; surely it shouldn't matter whether the type is a struct....) Could you explain more where the 'same array' rule comes from?

-extern char * astrxfrm (const char *s, char *resultbuf, size_t *lengthp);
+extern char * astrxfrm (const char *s,
+                        char * restrict resultbuf, size_t *lengthp);

I'd expect 'restrict' on all three pointer args. strxfrm has 'restrict' on both its args.

I didn't look at all the decls in details, but I expect you'll want more 'restrict's in there.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]