Home > Mobile >  ERROR :- passing argument 1 of 'get_string' from incompatible pointer type [-Wincompatible
ERROR :- passing argument 1 of 'get_string' from incompatible pointer type [-Wincompatible

Time:12-29

guys please tell what's wrong with my code. I have added the cs50 library and the header file but can't seem to do it correct. I am a begginer and like to know your advice.

CODE :-

#include <stdio.h>
#include <cs50.c>
#include <string.h>

int main(void)
{
    string s = get_string("Input:   ");
    printf("Output: ");
    int n = strlen(s);
    for( int i = 0; i < n; i  )
    {
        printf("%c", s[i]);
    }
    printf("\n");
}

ERROR :-

3.c: In function 'main':
3.c:7:27: warning: passing argument 1 of 'get_string' from incompatible pointer type [-Wincompatible-pointer-types]
    7 |     string s = get_string("Input:   ");
      |                           ^~~~~~~~~~~
      |                           |
      |                           char *
In file included from 3.c:2:
C:/msys64/mingw64/x86_64-w64-mingw32/include/cs50.c:78:28: note: expected 'char **' but argument is of type 'char *'        
   78 | string get_string(va_list *args, const char *format, ...)
      |                   ~~~~~~~~~^~~~
3.c:7:16: error: too few arguments to function 'get_string'
    7 |     string s = get_string("Input:   ");
      |                ^~~~~~~~~~
In file included from 3.c:2:
C:/msys64/mingw64/x86_64-w64-mingw32/include/cs50.c:78:8: note: declared here
   78 | string get_string(va_list *args, const char *format, ...)

CodePudding user response:

The cs50 docs states you should be including cs50.h, not cs50.c. https://cs50.readthedocs.io/libraries/cs50/c/#c.get_char https://cs50.readthedocs.io/libraries/cs50/c/#c.get_string

You need to add the header file in your include path.

CodePudding user response:

It was already stated in comments and the previous answer that you should not include the cs50.c file but only include the cs50.h file and link the cs50.c file to your project.

That is generally true unless you have very specific reasons to do it differently.

But... normally this should not cause the error we see in the question. This is because the cs50.c file included cs50.h on its own and we should have all definitions and declaration visible.

In this specific case we hit some specific implementation detail of CS50 libary which comes a bit as a surprise. And would not be necessary also...

Let's take a closer look at the header:

// cs50.h
string get_string(va_list *args, const char *format, ...) __attribute__((format(printf, 2, 3)));
#define get_string(...) get_string(NULL, __VA_ARGS__)

After these 2 lines we can use get_string as intented by the author of this question: string s = get_string("Input: ");

It is not really obvious why anyone might think it is a good idea to hide a function behind a macro with same name but different parameters. In most other APIs that function would have a different name than the macro. But, nevermind...

Now let's look at the C file:

// cs50.c
#include "cs50.h"
...
#undef get_string
string get_string(va_list *args, const char *format, ...)
{
...
}

If you compile this file on its own, everything is fine. The .c file does not need the macro and can just get rid of it before defining the function.

But if you include this in your own file, where you are supposed to use the macro instead, this is not possible any more. The undef breaks the API if you include the file directly.

This emphasises the fact that you should only include the headers. They are meant to be included and they are made accordingly. The .c files holding the implementation are not necessarily made that way, as we can see...

As a side note: This #undef is not necessary at all. You could simply do this instead:

// cs50.c
#include "cs50.h"
...
string (get_string)(va_list *args, const char *format, ...)
{
...
}

With enclosing () the indentifier get_string does not match the macro get_string() any more and no replacement is done. This would even allow to include the .c file directly.

Maybe they chose that way intentionally to prevent including the c file, but I would not bet on that.

  • Related