Greetings,

Are the following inferences of mine correct?

1.  #include 
    char *strcpy(char * restrict s1,
        const char * restrict s2);

    a.  s1 != s2
    b.  That means,

            char s[10] = "vijoeyz";
            (void) strcpy ( s, s ); /* though useless */

        is not allowed!

2.  #include 
    size_t strlen(const char *s);

    a.  If there is only one parameter of type "pointer to T", for any type
        T, then the `restrict' qualifier need not be used.

--
Women and cats do as they please.  Men and dogs
should sit back, and learn to relax.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Vijay Kumar R Zanvar"  wrote:

> Are the following inferences of mine correct?
> 
> 1.  #include 
>     char *strcpy(char * restrict s1,
>         const char * restrict s2);
> 
>     a.  s1 != s2

Yes.

>     b.  That means,
> 
>             char s[10] = "vijoeyz";
>             (void) strcpy ( s, s ); /* though useless */
> 
>         is not allowed!

Yes. Note that the definition following this declaration in the Standard
makes this explicit, even in C89:

# If copying takes  place  between  objects that overlap, the behavior
# is undefined.

> 2.  #include 
>     size_t strlen(const char *s);
> 
>     a.  If there is only one parameter of type "pointer to T", for any type
>         T, then the `restrict' qualifier need not be used.

Yes.

Richard
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On Tue, 27 Apr 2004, Vijay Kumar R Zanvar wrote:
>
> Are the following inferences of mine correct?
>
> 1.  #include 
>     char *strcpy(char * restrict s1,
>         const char * restrict s2);
>
>     a.  s1 != s2

  Not necessarily.  Yes, if we're to assume that when you
wrote 'strcpy' above you really meant 'strcpy', the function
that copies the target of 's2' into the target of 's1'.  But
generally, no, we could have the pathological case

    int ptreq(const char * restrict s1, const char * restrict s2)
    {
        return (s1 == s2);
    }

that would be perfectly conforming and unable to generate
undefined behavior, no matter the values of 's1' and 's2'.

>     b.  That means,
>
>             char s[10] = "vijoeyz";
>             (void) strcpy ( s, s ); /* though useless */
>
>         is not allowed!

  Naturally.  In the case of 'strcpy', the Standard explicitly
rules this sort of thing out (see 7.21.2.3 #2).  But
again, in the general case, you *could* pass 's' twice to the
'ptrcmp' function I defined above, because that function never
tries to access the targets of those pointers --- only their
values.

> 2.  #include 
>     size_t strlen(const char *s);
>
>     a.  If there is only one parameter of type "pointer to T", for any type
>         T, then the `restrict' qualifier need not be used.

  No.  'restrict' guarantees that the pointer will have a sort of
a "lock" on its target for its entire lifetime.  This means that
the following program exhibits undefined behavior:

    char g[] = "hello world";
    void foo(const char * restrict s) {
        g[0] = 'J';
        puts(s);
    }
    int main(void) {
        foo(g);
    }

because the target of 's' is modified through 'g' during the
lifetime of 's'.  I'm almost positive that by writing

    char ga[] = "hello world";
    char * restrict g = ga;

at file scope, you would be "preventing" anyone's tampering with
that string except through 'g', for the entire run of the program.
Quotes around "preventing" because it's not something the compiler
can catch; it just means anyone who tampers with that array invokes
undefined behavior on himself.


  N.B.: You can't define

    char restrict ga[] = "hello world";

by itself; 'restrict' can only be applied to pointers.  I don't see 
why it can't apply to array objects too; perhaps someone will enlighten 
me.

-Arthur
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Arthur J. O'Dwyer"  writes:

>   N.B.: You can't define
>
>     char restrict ga[] = "hello world";
>
> by itself; 'restrict' can only be applied to pointers.  I don't see 
> why it can't apply to array objects too; perhaps someone will enlighten 
> me.

Two arrays can never alias, so there's no need to restrict qualify them,
just like there is no need to const qualify them, as they can never be
modified anyway.  If you like, you can think of arrays as implictly
const and restrict qualified.

(In case it's not clear: By "array", I mean the array object itself, not
its elements.)

An array and a pointer can alias, but that situation can be expressed by
(absence of) a restrict qualifier on the pointer.

Martin


-- 
   ,--.    Martin Dickopp, Dresden, Germany                 ,= ,-_-. =.
  / ,- )   http://www.zero-based.org/                      ((_/)o o(\_))
  \ `-'                                                     `-'(. .)`-'
   `-.     Debian, a variant of the GNU operating system.       \_/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Vijay Kumar R Zanvar"  writes:

> Are the following inferences of mine correct?

Yes.

> 1.  #include 
>     char *strcpy(char * restrict s1,
>         const char * restrict s2);
>
>     a.  s1 != s2
>     b.  That means,
>
>             char s[10] = "vijoeyz";
>             (void) strcpy ( s, s ); /* though useless */
>
>         is not allowed!

Not only that, but the arguments may not even overlap.

    strcpy (s, s + 1);

would likewise invoke undefined behavior.

Martin


-- 
   ,--.    Martin Dickopp, Dresden, Germany                 ,= ,-_-. =.
  / ,- )   http://www.zero-based.org/                      ((_/)o o(\_))
  \ `-'                                                     `-'(. .)`-'
   `-.     Debian, a variant of the GNU operating system.       \_/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Source: geocities.com/vijoeyz/faq/c

               ( geocities.com/vijoeyz/faq)                   ( geocities.com/vijoeyz)