Anything to worry about (compiler warnings)?

Z

Zach

My program opens a file then associates a stream with it using fdopen.
Then it reads from the stream into the buffer. I am getting a few
warnings. I compiled with very strict options:

gcc -g -W -Wall -std=c99 -pedantic

So I wanted to know if these warnings are something to worry about
(need fixing) or if I can just ignore them:

main5.c: In function ‘main’:
main5.c:30: warning: implicit declaration of function ‘fdopen’
main5.c:30: warning: assignment makes pointer from integer without a
cast
main5.c: At top level:
main5.c:11: warning: unused parameter ‘argc’

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#define MAXLINE 90

int main(int argc, char *argv[])
{
char buf[MAXLINE];
int *psz;
int file = 0;
FILE *fpin = {0};

struct stat fileStat;

if((file = open(argv[1], O_RDONLY)) == -1)
{
printf("Cannot open file.\n");
perror("Unable to open sample.dat");
return EXIT_FAILURE;
exit(1);
}

printf("Leaving first if loop...\n");

if((fpin = fdopen(file, "r")) == NULL)
{
printf("Cannot get file descriptor.\n");
perror("fdopen failed");
close(file);
return EXIT_FAILURE;
exit(1);
}

printf("About to call fstat()...\n");

if ((fstat(file,&fileStat)) == 0)
{
printf("Just entered fstat while loop...\n");
psz = malloc(fileStat.st_size);
printf("Just finished malloc'ing...\n");
}

printf("Entering fgets while loop...\n");

while(fgets(buf, MAXLINE - 1, fpin) != NULL)
{

printf("Inside fgets while loop...\n");

char sub_string1[MAXLINE];
char sub_string2[MAXLINE];
char sub_string3[MAXLINE];

sscanf (buf,"%s %s %s",sub_string1,sub_string2,sub_string3);

printf("Finished sscanf...\n");

printf ("%s\n %s\n %s\n",sub_string1,sub_string2,sub_string3);

}

printf("About to fclose...\n");

fclose(fpin);

printf("File closed...\n");

printf("About to free...\n");

free(psz);

printf("Free finished...\n");

return 0;

}

If you have any other critiques or suggestions on my program I'd be
glad to hear them.

Thanks,
Zach
 
H

Harald van Dijk

My program opens a file then associates a stream with it using fdopen.
Then it reads from the stream into the buffer. I am getting a few
warnings. I compiled with very strict options:

gcc -g -W -Wall -std=c99 -pedantic

So I wanted to know if these warnings are something to worry about (need
fixing) or if I can just ignore them:

main5.c: In function ‘main’:
main5.c:30: warning: implicit declaration of function ‘fdopen’
main5.c:30: warning: assignment makes pointer from integer without a
cast

This is because fdopen is not a standard function. Your code includes
various non-standard headers, and some standard headers. By choosing
strict C99 mode, you still don't get an error for those non-standard
headers, but you've disabled your system's extensions in the standard
ones. One such extension is fdopen. Your system's documentation (probably
`man fdopen`) should tell you what you need to do to fix this.
main5.c: At top level:
main5.c:11: warning: unused parameter ‘argc’

You don't check argc before assuming argv[1] is a valid file name. You
should either make sure argc is at least 2 (in which case the warning
should go away), or check argv[0] and argv[1] to see if either is a null
pointer (in which case you can ignore the warning).
 
H

Harald van Dijk

[Cross-posted to c.u.p and followups set to that group.]
Zach said:
main5.c: In function ?main?:
main5.c:30: warning: implicit declaration of function ?fdopen?

You might have to de-strictify your compilation to pick up a declaration
of fdopen. Alternatively, add:

#define __USE_POSIX 1

before your inclusion of <stdio.h>

__USE_POSIX is not a macro any programmer should define except possibly
when implementing the C library. Posted to comp.lang.c, to hope make sure
Zach actually reads it. Better macro to define not posted to comp.lang.c
for the obvious reasons.
 
K

Keith Thompson

Zach said:
My program opens a file then associates a stream with it using fdopen.
Then it reads from the stream into the buffer. I am getting a few
warnings. I compiled with very strict options:

gcc -g -W -Wall -std=c99 -pedantic

So I wanted to know if these warnings are something to worry about
(need fixing) or if I can just ignore them:

main5.c: In function ‘main’:
main5.c:30: warning: implicit declaration of function ‘fdopen’
main5.c:30: warning: assignment makes pointer from integer without a
cast
main5.c: At top level:
main5.c:11: warning: unused parameter ‘argc’

Yes, you definitely should worry about both warnings.

The first is telling you that the compiler can't see a declaration for
fdopen. Note that fdopen is not a standard C function; it's specified
by POSIX, a separate standard. The man page on my system says it's
declared in <stdio.h>, but I think you have to do some other magic to
make it visible; consult your own system's documentation or post to
comp.unix.programmer for details. Note that "-std=c99 -pedantic"
tells gcc to attempt to conform to the C99 standard; standard C
doesn't allow extra declarations in standard headers.

The second points out a problem that I'll mention later.

More comments inline.
Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

The above 4 headers are specific to Unix/POSIX. The folks over in
comp.unix.programmer will be glad to help you with any questions
related to them.
#define MAXLINE 90

int main(int argc, char *argv[])
{
char buf[MAXLINE];
int *psz;
int file = 0;
FILE *fpin = {0};

struct stat fileStat;

if((file = open(argv[1], O_RDONLY)) == -1)

And how do you know that argv[1] exists? Without checking the value
of argc (remember that warning?), you don't know how many arguments
the user gave you. You could be passing a null pointer to open().
(You could also traverse argv and check for a null pointer, but using
argc us usually more convenient).
{
printf("Cannot open file.\n");
perror("Unable to open sample.dat");
return EXIT_FAILURE;
exit(1);

The exit(1) will never be executed. If it were, it would be
non-portable; the only portable values you can return from main or
pass to exit() are 0, EXIT_SUCCESS, and EXIT_FAILURE. But if your
program is Unix-specific anyway, that's not an issue.
}

printf("Leaving first if loop...\n");

It's an if statement, not a loop.
if((fpin = fdopen(file, "r")) == NULL)
{
printf("Cannot get file descriptor.\n");
perror("fdopen failed");
close(file);
return EXIT_FAILURE;
exit(1);

As above.
}

printf("About to call fstat()...\n");

if ((fstat(file,&fileStat)) == 0)

fstat() is Unix-specific. When you read the documentation, you'll
probably find that it has a way to report failure. Use it; don't just
assume that it will give you a valid result.
{
printf("Just entered fstat while loop...\n");
psz = malloc(fileStat.st_size);

malloc() reports failure by returning a null pointer. Check it, and
take some action if it fails, even if you just abort the program.
Since you appear to be trying to allocate the size of a file, failure
is entirely possible.

What if the input file doesn't have a defined size, for example if
it's not an ordinary file? What if the size changes while the program
is running?

[snip]
If you have any other critiques or suggestions on my program I'd be
glad to hear them.

You're mixing standard C I/O functions (based on FILE*) with
Unix-specific ones (based on small integer file descriptors). That's
not necessarily a bad thing, but you might consider using the standard
C functions as much as possible. <OT>fileno will give you file
descriptor corresponding to an existing FILE*.</OT>
 
R

Richard Tobin

Harald van Dijk said:
__USE_POSIX is not a macro any programmer should define except possibly
when implementing the C library. Posted to comp.lang.c, to hope make sure
Zach actually reads it. Better macro to define not posted to comp.lang.c
for the obvious reasons.

I can't see any obvious reasons.

As far as I know, the correct way to enable Posix functions in an
otherwise-standard-C compiler is to define _POSIX_C_SOURCE or
_XOPEN_SOURCE.

See
http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
for more details.

-- Richard
 
H

Harald van Dijk

I can't see any obvious reasons.

Alright. The primary reason is that comp.unix.programmer, as RH had
already redirected follow-ups to, is a much more appropriate newsgroup
for this question and its answers. A secondary reason is that I had
already responded to Zach myself, telling him that his system's
documentation should answer his question, and I'd have liked for him to
have a need to actually check it out.
 
A

Antoninus Twink

As far as I know, the correct way to enable Posix functions in an
otherwise-standard-C compiler is to define _POSIX_C_SOURCE or
_XOPEN_SOURCE.

Yes - Heathfield was just plain wrong.

See also the feature_test_macros manpage.
 
C

CBFalconer

Zach said:
My program opens a file then associates a stream with it using
fdopen. Then it reads from the stream into the buffer. I am
getting a few warnings. I compiled with very strict options:

gcc -g -W -Wall -std=c99 -pedantic

So I wanted to know if these warnings are something to worry
about (need fixing) or if I can just ignore them:

main5.c: In function ‘main’:
main5.c:30: warning: implicit declaration of function ‘fdopen’
main5.c:30: warning: assignment makes pointer from integer
without a cast
main5.c: At top level:
main5.c:11: warning: unused parameter ‘argc’

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

Yes, you need to worry. You are asking for compilation to C99
standards (the -std=c99 and -pedantic above). The last four
include files specified don't exist in C99, and neither does
fdopen.

I don't know where you are getting the 'pointer from integer'
error. If due to "psz = malloc(fileStat.st_size);" then you are
failing to compile with a C compiler. If the source file extension
is not a lower case c then this can happen with gcc.

You are also calling other things that don't exist in standard C.
Such as 'open'. Use fopen. You should have gotten warnings on
this. Maybe there is something around that lets you access the
non-existing standard headers mentioned above.

Failure to use argc implies that you can access missing parameters.
 
K

Keith Thompson

CBFalconer said:
Yes, you need to worry. You are asking for compilation to C99
standards (the -std=c99 and -pedantic above). The last four
include files specified don't exist in C99, and neither does
fdopen.

The last four include files may (or may not) exist in a conforming C99
implementation. They make the code non-portable, not incorrect.

Are you under the impression that the C99 standard forbids
non-portable code? Shall I cite the section of the C99 standard that
specifically permits extensions?
I don't know where you are getting the 'pointer from integer'
error.

It's on the same line as the warning about the fdopen function.
Because the declaration of fdopen is not visible to the compiler, the
compiler is implicitly assuming that it returns int, and he's
assigning the result to a pointer object. (Making this assumption in
C99 mode is questionable, but as long as the required diagnostic is
printed, it's not a conformance problem.)
You are also calling other things that don't exist in standard C.
Such as 'open'. Use fopen. You should have gotten warnings on
this. Maybe there is something around that lets you access the
non-existing standard headers mentioned above.

Why on Earth should the compiler warn about a call to open()? As it
happens, the open function is declared in the (non-standard) header
<fcntl.h>. He has a "#include <fcntl.h>" at the top of his code. The
call is perfectly valid *for an implementation that supports it*.

And why should he call fopen() rather than open()? If he wants to ask
about open(), he should do so in comp.unix.programmer (as he's already
been advised several times), but there are valid system-specific
reasons to use open() rather than fopen(). (In this case, he later
calls fstat().)
Failure to use argc implies that you can access missing parameters.

Correct.
 
M

Martin Ambuhl

Zach said:
My program opens a file then associates a stream with it using fdopen.

There is, of course, no standard C function named fdopen.
Unfortunately said:
Then it reads from the stream into the buffer. I am getting a few
warnings. I compiled with very strict options:

gcc -g -W -Wall -std=c99 -pedantic

And this makes sure that functions which are improperly declared in
<stdio.h> are never declared. It is very common for the header
<stdio.h> supplied with gcc to (quite correctly) have something like:

#ifndef __STRICT_ANSI__

int fileno(FILE *_stream);
FILE * fdopen(int _fildes, const char *_type);
int mkstemp(char *_template);
int pclose(FILE *_pf);
FILE * popen(const char *_command, const char *_mode);
char * tempnam(const char *_dir, const char *_prefix);

By asking for strict compilation you have asked it _not_ to include the
prototype for fdopen, leading to ...
> main5.c: In function ‘main’:
> main5.c:30: warning: implicit declaration of function ‘fdopen’


So I wanted to know if these warnings are something to worry about
(need fixing) or if I can just ignore them:

Never ignore warnings. Decide whether you want to compile with those
options. If you do, then type the prototype for fdopen into your code
yourself.
 
K

Keith Thompson

Martin Ambuhl said:
There is, of course, no standard C function named
fdopen. Unfortunately, many implementations place the declaration in
<stdio.h>

POSIX *requires* fdopen to be declared in <stdio.h>.
 
A

Antoninus Twink

Why on Earth should the compiler warn about a call to open()? As it
happens, the open function is declared in the (non-standard) header
<fcntl.h>.

This point seems to cause lots of confusion, so perhaps it's worth
spelling out what's going on.

POSIX adds many features to the bare-bones "standard" C library. Some of
these add-ons get their own header files that aren't included in the
base ISO C specification. We have an example here: open(2), which is
declared in fcntl.h.

If you #include one of these headers, then there can be no question that
you want to go beyond ISO C and make use of the extra POSIX
functionality.

On the other hand, there are some POSIX functions that get declared in
one of the header files that *do* already exist in ISO C. The OP
discovered an example: fdopen(3) is found in stdio.h.

So if you #include <stdio.h>, the implementation has a dilemma: are you
compiling "strict ISO C", in which case you don't want these extra
functions declared, or are you compiling code for your POSIX platform,
when you do want them? To put it another way, conceptually there are two
different stdio.h files (though in practice there's only one that uses
conditional compilation tricks to pretend to be more than one): there's
the "ISO C stdio.h file" and the "POSIX stdio.h file". They both have
the same name, stdio.h, so there's an ambiguity about which one you're
referring to.

The way gcc resolves this is to assume that you want the full POSIX
functionality, unless you specifically tell it that you don't, e.g. by
providing a -std command line option. However, even if you do ask for
strict ISO C compliance, you can still override this to get access to
the POSIX symbols by using a "feature test macro", i.e. by defining a
macro like _XOPEN_SOURCE (either in your code, or on the command-line:
-D_XOPEN_SOURCE=500.
And why should he call fopen() rather than open()? There are valid
system-specific reasons to use open() rather than fopen(). (In this
case, he later calls fstat().)

That doesn't seem like a very compelling reason. He could use fopen()
then fileno() to get the file descriptor to pass to fstat(). This would
still give him the benefits of buffered I/O.
 
R

Richard Tobin

The last four include files may (or may not) exist in a conforming C99
implementation.
[/QUOTE]
The statement wasn't that they may not exist in an implementation, but
that don't exist in C99.

The obvious interpretation of the quoted statement is that you
shouldn't use -std=c99 if you want to use Posix features. I don't
think that's true; it's just that if you specify -std=c99 you will
need to take the actions appropriate to C99 to enable Posix
declarations, which you might not have to otherwise.

-- Richard
 
C

CBFalconer

Mark said:
Keith Thompson wrote:
.... snip ...


If there's no declaration in scope, it should warn. If there is,
then it need not. It depends where open() is declared. Your
implementation sticks it in fcntl.h, others stick it in stdio.h.


To be portable and avoid messy issues like this one?

Because open doesn't exist in C99. fopen does. Delete the include
files that also don't exist in C99, and watch the compiler complain
about open. There is no standard about what open does, how it is
called, etc. in C99 (or C90).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top