3

Having this:

#define _DEFAULT_SOURCE 1
#include <stdio.h>
#include <string.h>

int main(){
    char *token, org[] = "Cats,Dogs,Mice,,,Dwarves,Elves:High,Elves:Wood";
    while((token=strsep(&org,",")))
        printf("Token: %s\n",token);
}

gives err (incompatible pointer type):

/usr/include/string.h:439:14: note: expected ‘char ** restrict’ but argument is of type ‘char (*)[47]’
 extern char *strsep (char **__restrict __stringp,
  1. I know it is different type (one has memory initialized -> org[], but the function wants pointer without any memory initialized), but they have the same behaviour, so why it complain anyway?

  2. And can somone explain me, what is the meaning of this keyword restrict or __restrict in case of *strsep (char **__restrict __stringp, (on the other hand, I assume the __stringp is not a internal datatype (because of double underscores) but only a fancy variable name).

Edit: I think an array is stored in stack, but the strsep wants a pointer that points to a heap, which could be done with having org allocated with malloc and then memcpy, or even better, copy the string via strdup (which does internally memcpy). But anyway, way does strsep wants pointer that points to heap and not to stack? Both are just pointers, point only to different addresses, but that should not mind.

2
  • @Inian have you read the question title? You just said, what I am asking Commented Jun 21, 2020 at 14:20
  • This question could be a partial duplicate of stackoverflow.com/questions/17687429/… Commented Jun 21, 2020 at 17:18

3 Answers 3

2

The strsep function requires the address of a modifiable pointer as its first argument (or NULL, in which case it does nothing); you are passing it the (fixed) address of an array. You can fix this by declaring a separate char* variable and assigning to that the (address of the) org array:

int main()
{
    char* token, org[] = "Cats,Dogs,Mice,,,Dwarves,Elves:High,Elves:Wood";
    char* porg = org; // "porg" is a MODIFIABLE pointer initialized with the start address of the "org" array
    while ((token = strsep(&porg, ",")))
        printf("Token: %s\n", token);

    return 0;
}

From the Linux manual page (bolding mine):

If *stringp is NULL, the strsep() function returns NULL and does nothing else. Otherwise, this function finds the first token in the string *stringp, that is delimited by one of the bytes in the string delim. This token is terminated by overwriting the delimiter with a null byte ('\0'), and *stringp is updated to point past the token. In case no delimiter was found, the token is taken to be the entire string *stringp, and *stringp is made NULL.

On the meaning and use of the restrict keyword, maybe this will help: Realistic usage of the C99 'restrict' keyword?.

Sign up to request clarification or add additional context in comments.

4 Comments

In what sense you refer fix address vs modifiable address? Both are just address. You car perform a pointer arithmetic on both of them. Can you please explain, what do you mean by fixed address?
@milanHrabos org is an array declared in a function (main, in this case, but it could be any function). Normally, memory for such data (known as "automatic variables") is assigned on the stack, and the address of that data item is thus 'fixed' for the duration of the function in which it is defined. You can't change where that data is. Although arrays and pointers have some syntactic similarities, they are not the same thing.
I know only about args, that are passed to function, that thay no longer live after function return, but not about automatic vars. The reason for args is they are pushed onto the stack (on x32, x64 uses registers for args), and at the end of function, the stack pointer is added (so deleted the pushed args). Is that the case of org?, because org is not arg to function main. In generated assembly, I only see leave instruction, but not adding back stack pointer. That means I can access org address from stack after main returns, which makes it movable, not fixed
my bad, just read stackoverflow.com/questions/29790175/…, where leave does excatly what I refered to adding, so now I see, the org cannot be access anymore, once the function returns. But anyway, why some function require to have modifiable (meaning anytime accessible) pointers, when they are called with the main function stack anyway (they are called inside main function, so they have access to stack), heap accessing is superfluous
1

Address of the array references the place where the array starts, it has only the different type - pointer to the array. It is not pointer to pointer.

    char *token, org[] = "Cats,Dogs,Mice,,,Dwarves,Elves:High,Elves:Wood";
    char *pointer = org;
    while((token=strsep(&pointer,",")))
    /* ... */

You cant cast reference to array to double pointer.

restrict it a quite advanced topic. It promises the compiler that if the object referenced by pointer is modified, the access to this object can be only done by this pointer. It helps the compiler in the code optimisations

Generally speaking I would not expect you to use this qualifier before you get proficient in the C language.

1 Comment

so only if a object referenced by restrict pointer is modified, then the pointer is the only entry? How otherwise it could be modified, then with the pointer referencing that object? Can you please give a minimal example, where its usage is appropriate?
0
#include <stdio.h>
#include <string.h>

int main()
{
    char org[] = "Cats,Dogs,Mice,,,Dwarves,Elves:High,Elves:Wood";
    char *token = strtok(org, ",");
    while (token != NULL) {
        printf("Token: %s\n", token);
        token = strtok(NULL, ",");
    }
}

I think you should take a look at this page : Restrict type qualifier

1 Comment

No, I do not want to use strtok function, If I would I would post a question with that function, please look at my post, where I am using strsep defined by glibc. This is offtopic

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.