Username
Username

Reputation: 3663

warning: passing argument 2 of ‘fopen’ makes pointer from integer without a cast

I have this function to check if a file exists:

#include <stdio.h>

int main(int argc, char **argv) {
    int textFileExists(const char *filename){
        FILE *fp=   fopen(filename,'r');
        if(fp==NULL){
            printf("%s %s.\n","There was an error opening ", filename);
            return -1;
        }
        return 1;
    }

    textFileExists("text.txt");
    return 0;
}

But when I compile this code, I get this warning.

warning: passing argument 2 of ‘fopen’ makes pointer from integer without a cast
  FILE *fp= fopen(filename,'r');

Running this code gives me a segmentation fault.

What is going on here?

Upvotes: 1

Views: 13021

Answers (3)

Zdeněk Jel&#237;nek
Zdeněk Jel&#237;nek

Reputation: 2913

The usage of literal 'r' as fopen parameter is equivalent to using the following:

const char* filename = ...;
char mode = 'r';
fopen(filename, mode);

The 'r' is therefore assumed to be of type char and has the value of 0x72 (ASCII). This is then passed to the char* mode, converting the 0x72 to a memory address (pointer) to be read from to obtain the characters of mode string by fopen. Accessing the memory location at 0x72 fails as that location is most probably not available to your application.

For a char* literal, you need to use "r" as in

const char* filename = ...;
const char* mode = "r";
fopen(filename, mode);

Upvotes: 5

Peter
Peter

Reputation: 36597

'r' is a single character which, when passed to a function, has type int.

The function fopen() expects the second argument to be a (const) pointer to char (i.e. a const char *). Hence the warning message. A conversion from an int to a pointer is permitted in C, for various reasons, but compilers often treat such conversions as suspicious, and warn you.

The function expects the passed pointer to be a string, which means it assumes the value points to the first character of an array of char. It doesn't (since you have passed an int) so exhibits undefined behaviour. One symptom of undefined behaviour is a segmentation violation (caused by your operating system detecting your program accessing memory it shouldn't, and sending a SIGSEGV signal to your program).

To fix the problem pass "r" instead of 'r'. Note the double quotes rather than single quotes. "r" is a string literal, which is represented using two characters, 'r' and '\0', which is what fopen() expects. Doing this will eliminate both the warning and the error when running the program.

Get in the habit of checking warning messages from your compiler BEFORE running the program. Warnings often indicate a potential problem - in this case, the cause of the warning is also the cause of the abnormal program exit.

Upvotes: 5

Alexey Frunze
Alexey Frunze

Reputation: 62048

In C there's a difference between 'r' and "r". Check your C book.

Upvotes: -2

Related Questions