4

I read this answer: Must declare function prototype in C?

My question is more specific:

In a program that uses system calls like access(), open(), creat(), write(), read()... Must I declare every system call function? Is that how C works? Because I'm getting the following:

hw1.c: In function ‘main’:
hw1.c:50:9: warning: implicit declaration of function ‘access’ [-Wimplicit-function-declaration]
hw1.c:131:9: warning: implicit declaration of function ‘lseek’ [-Wimplicit-function-declaration]
hw1.c: In function ‘writeFile’:
hw1.c:159:17: warning: implicit declaration of function ‘write’ [-Wimplicit-function-declaration]

Basically, it seems C is angry with every system call function I'm using. I am somewhat new to C and this appears strange to me even though I know I have to declare functions I write I would think C would know the system call functions and would not need me to declare them explicitly in the code.

Do I need to do something like this:

int access(const char *pathname, int mode);

If so why does that make sense? I use other languages and never have to do this.

Community
  • 1
  • 1
AturSams
  • 7,568
  • 18
  • 64
  • 98

3 Answers3

12

Yes, you should include the correct header for every system function call you make. You don't write the declarations yourself—you'll get them wrong. Use the header!

For the functions you cite, the relevant headers are:

#include <unistd.h>  /* Many POSIX functions (but not all, by a large margin) */
#include <fcntl.h>   /* open(), creat() - and fcntl() */

See POSIX 2008 to find the correct header for other POSIX functions.

The C99 standard requires that all functions are declared or defined before they are used.


For your own functions, you should emulate the 'system'. There will be a header that declares the function, the source file that implements it, and the other source files that use the function. The other source files use the header to get the declaration correct. The implementation file includes the header to make sure its implementation is consistent with what the other source files expect. So the header is the glue that holds it all together.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks! This solved everything. So basically I need to import functions and their headers. If I only import functions I get warnings and the functions may work depending on their signatures? I will heed this advice from now on – AturSams Nov 15 '12 at 20:05
  • You include the headers to declare the functions. The headers don't normally contain the implementation. These functions are usually in the C library that the compiler links with your application anyway, so you usually don't have to do anything more than include the header and use the function correctly. Sometimes you'll find you need to add an extra library (or several) to the link line for your program. – Jonathan Leffler Nov 15 '12 at 20:07
3

You do not have to declare each one, per se. What you need to do is include the proper header files that contain the declarations of these functions. For example:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

stdio.h, fcntl.h, and unistd.h (assuming you are coding for *nix) are the ones you need for the functions you mentioned. For specifics, consult your documentation (i.e. man lseek).

Will
  • 3,500
  • 4
  • 30
  • 38
1

You have to do that in almost all languages except for a set of "core" libraries. Java, C#, Perl, etc. all have forms of import or use, or making references in build configurations, or... for things outside the core library. C is no different, except that it has a very small (i.e. non-existent) "core libraries" - none of the library headers get included by default.

#include is what you're looking for. Check the man page for each of these functions, and you'll know what headers you need to include.

Mat
  • 202,337
  • 40
  • 393
  • 406
  • 1
    C's standard library is certainly limited compared to C++, Java, Python, Ruby, ... but calling it non-existent goes a bit far :) – Thomas Nov 15 '12 at 19:56
  • I meant that nothing of it is included by default. – Mat Nov 15 '12 at 19:57
  • The difference and cause for confusion for novice c users is that in language x I either can't use a function at all or I can use it without getting a warnings. In c the code works without #include and I get a warning. It is like C saying I kind of know what you mean but I would appreciate it if you were clearer. – AturSams Nov 15 '12 at 20:03
  • 1
    @ArthurWulfWhite: it's worse than that. Depending on what the function takes as arguments and what it returns, not having the right prototype will lead to real bugs. You really need to fix all those warnings by including the right headers. They must not be ignored. – Mat Nov 15 '12 at 20:04
  • Part of the reason for the behaviour is historical legacy. Before there was a C standard, the way code was written was considerably different (no prototypes, for example). When the standard was created, the legacy code had to be compilable still — outlawing the existing code would have made the standard fail. This means that there are various lax rules held over from the pre-standard days. One of those rules with C89 compilers is that if something looks like a function and isn't otherwise declared, it is a function with an indeterminate argument list that returns an `int`. C99 outlawed that. – Jonathan Leffler Nov 15 '12 at 20:11
  • This is exactly the kind of info I wanted but could not/ should not ask for cause it is "not a problem that needs to be solved" and I am glad I learned this now cause the behavior puzzled me. – AturSams Nov 15 '12 at 20:33