I want to use gnuplot in my code in Linux, so I wrote this line:
FILE *gnuplotPipe = popen ("gnuplot -persistent", "w");
And the compiler gave me this warning:
warning: initialization makes pointer from integer without a cast
Can someone explain me what is this warning? and what should I do in order to do it correctly?
You forgot to put
#include <stdio.h>
at the top of your file.
The header file contains the definitions for functions, including that of popen(). It tells the compiler popen() returns a FILE *.
If you don't include the header file, the compiler will assume a default return value, which is an int. Hence the warning can be explained: the compiler thinks popen() returns an int, and then wants to assign it to a FILE *.
Related
I had an interview question where the interviewer asked me what error would we get from the below output:
int main()
{
printf("hello world");
return 0;
}
#include <stdio.h>
I answered "no error" and it will display the output.
can anyone help me with this???
Please note"the missing angular brackets is intentionally done by me so dont bother about that"
It depends on the compiler.
Most C compilers will probably accept that code (perhaps with a warning) and produce an executable that prints the expected output.
Under C90 rules, the behavior of the printf call is undefined; it's invalid to call a variadic function with no visible prototype. Variadic functions can have a different calling convention from ordinary functions, and you have to let the compiler know that printf is variadic so it can generate correct code for the call.
Under C99 and later rules, calling any function with no visible declaration (which may or may not be a prototype) is a constraint violation, requiring at least a compile-time warning.
The standard doesn't hint at what happens if you call printf without the required prototype, but in practice most compilers will handle it "correctly".
The missing '\n' at the end of the output means that the program's behavior is undefined if the implementation requires a newline at the end of the output; whether that's required or not is implementation-defined. In any case, adding a newline is a good idea.
The #include <stdio.h> at the end of the source file should be useless but harmless.
I'm assuming that the source file actually contains #include <stdio.h> and not #include stdio.h; the latter would be a syntax error.
(Practically speaking, of course, the #include <stdio.h> should be at the top. In a professional setting, the output is irrelevant, since the program will never survive a code review.)
You will get an error for missing quotes or <> in the filename for the #include. It should be:
#include <stdio.h>
Apart from that, it should compile with a warning about an implicit declaration to printf(). On Clang, it gives me:
test.c:3:5: warning: implicitly declaring library function 'printf' with type 'int (const char *, ...)'
printf("hello world");
^
When your main() function is being declared, the compiler will run into the first line of main() and it will have no idea what printf() is. You will get an error about the compiler complaining about an undeclared function.
Assuming, of course, the missing < and > was a mistake introduced when you copied your question over.
There are two errors here. The first is that the include directive must happen before the code that requires that header information, in this case printf() is declared in stdio.h, and the second is that the filename in the include directive must be enclosed in angle brackets, <>, or quotes, "".
My situation is as follows. I obtain FILE * pointer. I know it can point to FILE type that does not support seek (can be PIPE). So to make things easier I thought of loading parts of the file to memory as a string buffer.
The problem is, that my file contains, next to some other stuff, C structures, that I need to load to memory. And so far, everything I have tried had failed.
Most promising seemed to be fmemopen, but when I added it to my code I got
warning: implicit declaration of function ‘fmemopen’ [-Wimplicit-function-declaration]
stream = fmemopen (buffer, p_header.bytes, "r");
warning and that is certainly nothing I want. It remained implicit declared even though I added stdio.h include.
Can anything be done about that? Can I somehow create something of FILE * type in memory so I can call fread on it?
Or is there a way how to read structure from string?
I have used fread as follows:
fread(&var_of_type_love_struct_t, sizeof(love_struct_t), 1, myfile);
The warning about fmemopen is that the compiler didn't find the prototype, add
#define _GNU_SOURCE
before including all the headers, or, if using GCC, add -D_GNU_SOURCE to the options.
My compiler (gcc) throws warnings (not errors!) on the line which declares fp:
int fd = open("filename.dat", O_RDONLY);
FILE* fp = fdopen(fd, "r"); // get a file pointer fp from the file descriptor fd
These are the warnings:
main.c: In function ‘main’:
main.c:606: warning: implicit declaration of function ‘fdopen’
main.c:606: warning: initialization makes pointer from integer without a cast
I do not understand these warnings since the return value of fopen is a FILE*. What is the mistake I am making here?
EDIT: I am including stdio.h (and I am also on Linux).
Short answer: use -std=gnu99 when compiling, the usual standard is non-POSIX and does not have fdopen.
warning: implicit declaration of function ‘fdopen’
Means you have forgot to include the header file which the declaration of fdopen() resides in. Then an implicit declaration by the compiler occurs - and that means the return value of the unknown function will be assumed to be int - thus the second warning. You have to write
#include <stdio.h>
Edit: if you properly include stdio.h, then fdopen() might not be available on the system you're targeting. Are you on Windows? This function is POSIX-only.
Edit 2: Sorry, I really should have perceived this. C99 means the ANSI C99 standard - and standard C doesn't force the concept of file descriptors in order to support non-POSIX systems, so it provides fopen() only. fdopen() is related to file descriptors, so it's POSIX-only, so it's not part of standard C99. If you use the -std=gnu99 switch for GCC, it gets rid of the standard's restrictions and lets in the POSIX and GNU-only extensions, essentially fixing your problem.
#define _XOPEN_SOURCE 600
#include <stdio.h>
This conforms perfectly with strict c99
gcc -std=c99 -pedantic -Wall -Wextra -Werror
You are not including #include <stdio.h> in C the compiler therefore "guesses" the declaration of the function you're trying to call. (Taking the parameters you've based and using int as return value). Usually you don't want such guesses therefore the compiler warns you.
Solution: Add proper #includes.
The fdopen function is not part of the C standard and is not available as part of the standard headers if you compile in standard C mode. So you either need to use -std=gnu99 instead of -std=c99 to compile your source or declare the function yourself.
There's a good explanation for the compiler's diagnostic in #H2CO3's answer, so let's only look on the why of things: if you're using glibc (and you probably are), certain POSIX functions may require specific feature test macros to show up.
In particular, you may need to put the following line:
#define _POSIX_SOURCE
// or #define _XOPEN_SOURCE
before
#include <stdio.h>
Certain compilers (such as gcc) also have command line options to the same effect (all the gnu* standards options in gcc).
I write "hello world" program in C.
void main()
{ printf("Hello World"); }
// note that I haven't included any header file
The program compiles with warning as
vikram#vikram-Studio-XPS-1645:~$ gcc hello.c
hello.c: In function ‘main’:
hello.c:2:2: warning: incompatible implicit declaration of built-in function ‘printf’
vikram#vikram-Studio-XPS-1645:~$ ./a.out
Hello Worldvikram#vikram-Studio-XPS-1645:~$
How is this possible? How does the OS link a library without including any header?
The compiler builds your source file with a reference to a function called printf(), without knowing what arguments it actually takes or what its return type is. The generated assembly contains a push of the address of the string "Hello World" in the static data area of your program, followed by a call to printf.
When linking your object file into an executable, the linker sees a reference to printf and supplies the C standard library function printf(). By coincidence, the argument you have passed (const char*) is compatible with the declaration of the real printf(), so it functions correctly. However, note that the printf() that your program implicitly declares has return type int (I think), which the standard printf() also has; but if they differed, and you were to assign the result of calling printf() to a variable, you would be in the land of undefined behaviour and you would likely get an incorrect value.
Long story short: #include the correct headers to get the correct declarations for functions you use, because this kind of implicit declaration is deprecated, because it is error-prone.
The printf function is in the C library (libc in your case) which is linked implicitly (actually gcc has a printf builtin but it's outside the point).
Including the header doesn't bring in any functions for the linker, it simply informs the compiler about their declarations (i.e. "what they look like").
Obviously you should always include headers otherwise you force the compiler into making assumptions about what the functions look like.
In C, if you use a standard library function, you have to include the standard header where the function is declared. For printf you have to include stdio.h header file.
In C89 (and GNU C89 which is the language by default on gcc), a function declaration can be sometimes omitted because there is a feature called implicit function declaration: when a function identifier foo is used and the function has not been declared, the implementation would use this declaration:
/* foo is a function with an unspecified number of arguments */
extern int foo();
But this declaration is OK only for functions that return int with an unspecified but fixed number of arguments. If the function accepts a variable number of arguments (like printf) such program would invoke an undefined behavior.
Here is what C89/C90 says:
(C90, 6.7.1) "If a function that accepts a variable number of arguments is defined without a parameter type list that ends with the ellipsis notation, the behavior is undefined.
So gcc is kind enough to compile even in C89 and GNU C89: a compiler could refuse to compile.
Also note that
void main() { ... }
is not a valid definition for main (at least on hosted implementations which is probably your case).
If your main function doesn't take any argument use this valid definition:
int main(void) { ... }
The header usually1 contains only function declarations, symbolic constants, and macro definitions; it doesn't usually include function definitions.
All stdio.h gives you is the prototype declaration for printf:
int printf(const char * restrict format, ...); // as of C99
The implementation of printf is in a separate library file that your code links against.
Your code "works" for two reasons:
Under C89 and earlier versions, if the compiler sees a function call
before a declaration or definition of that function, it will assume
that the function returns int and takes an unspecified number of
parameters;
The implementation of printf returns an int, and you passed in
an argument that just happens to be compatible with what the
implementation of printf expects for the first argument.
And to echo what everyone else says, use int main(void) or int main(int argc, char **argv); unless your compiler documentation explicitly lists void main() as a legal signature, using it will invoke undefined behavior (which means everything from your code running with no apparent issues to crashing on exit to failing to load completely).
I say "usually"; I've run across some headers that contained code, but those were usually written by people who didn't know what they were doing. There may be very rare occasions where putting code in a header is justified, but as a rule it's bad practice.
hello.c:2:2: warning: incompatible implicit declaration of built-in function ‘printf’
To deal with this warning, you should include the header file (stdio.h). You're accidently using an old feature of C that has been deprecated since 1999.
Also, the fact that the link doesn't fail simply means that the standard C library is linked in by default. Whether or not you have included the relevant header is immaterial.
I am following the C programming tutorial at http://www.cprogramming.com/tutorial/c/lesson10.html. This particular tutorial teaches file I/O in C; in particular, the fopen command is discussed. At one point, they give the following example (which I think should print the contents of file test.txt):
FILE *fp;
fp=fopen("c:\\test.txt", "w");
fprintf(fp, "Testing...\n");
So, I made a text file called test.txt and saved it in my current, working directory (C:\cygwin\home\Andrew\cprogramming). Then I created a c file in this same directory, and it contains the following code:
#include <stdio.h>
int main()
{
FILE *fp;
fp=open("test.txt","w");
fprintf(fp,"Testing...\n");
}
When I compile this c file (which I've called helloworld2.c) using gcc, I get the following messages:
helloworld2.c: In function `main':
helloworld2.c:40: warning: assignment makes pointer from integer without a cast
Then when I try to run the executable, I get:
Segmentation fault (core dumped)
Do you have any ideas about what I should try next?
Thank you very much for your time.
This is because you use open instead of fopen. Open is from the POSIX standard and returns an (integer) handle; fopen returns the memory address of a FILE structure. You cannot use both in an interchangeable way. As it stands, your code implicitly casts the received integer (likely 4) to a FILE* pointer, making it point to the memory address 4. This segfaults your program when fprintf attempts to access it.
fopen is cross-platform, but open is POSIX-only. You may want to stick to fopen for now.
fopen() returns a pointer to a FILE object while open() returns a file descriptor which is a plain int.
Unless you need low-level functions it's usually better to work with fopen and FILE objects.
I'm guessing this was just an unfortunate typo - open() instead of fopen() - which just happens to work well enough to build a final executable (rather than a deliberate attempt to use open())...
You see warning: assignment makes pointer from integer without a cast because there is no "prototype" - a declaration of the argument and return types - for open() in <stdio.h>.
In the absence of such a prototype, the compiler assumes that such a function exists and returns an int, which your code assigns to the pointer variable fp.
It does in fact link successfully because there is a function called open() in the C library, but it does something different (as others have mentioned). But if (for example) you'd written fpen() instead, things would have gone more obviously wrong - it would have failed at the link stage, as there is no library function of that name.
If you compile with more warnings enabled - e.g. -Wall for GCC - you'll get some more helpful errors:
$ gcc -Wall -o helloworld2 helloworld2.c
helloworld2.c: In function 'main':
helloworld2.c:6: warning: implicit declaration of function 'open'
helloworld2.c:6: warning: assignment makes pointer from integer without a cast
helloworld2.c:8: warning: control reaches end of non-void function
$
The warning: implicit declaration of function 'open' tells you that there is a mismatch between the headers you've included, and the function you're trying to use.