Simon
Simon

Reputation: 13

I have not included the <unistd.h> header file, why can I still invoke the getpid() function successfully?

Code as below:

int main (int argc, char *argv[]) {
    long pid = (long)getpid();
    long test = pid + 1;
}

Have not included any head files, still can compile code successfully and still can run program successfully.

Why?

Environment info: Ubuntu 18.04.2 LTS, gcc (Ubuntu 4.8.5-4ubuntu8) 4.8.5

Upvotes: 1

Views: 788

Answers (2)

Marco Bonelli
Marco Bonelli

Reputation: 69346

Normally, to use a dynamic library function you would have to link against the specified library at compile time through the -l switch, like for example gcc -lm prog.c when using the mathematic functions (from libm).

However, since it's so common, GCC always links the standard C library by default, meaning that doing gcc prog.c is actually the same as doing gcc -lc prog.c. This is always done whether you include any header or not.

The second thing that makes this work, is that GCC assumes any function that has not been declared at compile time to have the signature int func(void). In this case, the signature is quite similar to the one of the real getpid() function.

If you take a look at your compiled program with the ldd tool to show which dynamic libraries are required, you'll see that the program is linked against libc:

$ ldd prog
    linux-vdso.so.1 (0x00007ffede7d0000)
==> libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0f47018000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f0f475b9000)

When your program runs, it asks the dynamic loader where (at which address) to find the getpid function before calling it the first time. The dynamic loaders checks the loaded libraries, and finds a function with that name in libc, so everything seems to work without a problem.

You can tell GCC to not link against the standard library by default using the -nostdlib compiler switch, but this is not that useful in your case. The real solution is to always treat warnings about implicit function declarations as errors (-Werror=implicit-function-declaration).

If your compiler doesn't give this warning by default, I would suggest you to upgrade it to a newer version. GCC 4 is definitely not the latest version available for Ubuntu 18.

$ sudo apt update
$ sudo apt upgrade

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 180236

Have not included any head files,
still can compile code successfully.
still can run program successfuly.
Why?

Why not?

All question of whether the particular code presented conforms to the language standard notwithstanding, language non-conformance does not imply that compilation or execution must fail. Instead, you get undefined behavior, which can manifest in any manner within the power of the machine to produce, including compiling successfully and running as intended.

In your particular case, however, you are using GCC 4.8.5. The GCC 4.8 series defaults to compiling for the C90 standard, with GNU extensions. C90 allows calls to functions with no in-scope declaration, for compatibility with earlier, pre-standardization practice. That is no longer allowed in C99 or later, but many implementations nevertheless continue to accept it as an extension.

It should be understood, however, that C interprets some argument lists differently when the called function has an in-scope prototype than when it doesn't (which may be the case even for functions that are declared, because not all declarations provide prototypes). You may be able to get away with calling undeclared functions under some circumstances, but it is poor style, and if you do it enough then it will bite you at some point.

Note also that GCC 4 definitely has the ability to emit warnings about usage such as yours, even when compiling in C90 or GNU90 mode. You would be well served to turn on the -Wall option when you compile, and maybe additional warning options as well.

Upvotes: 2

Related Questions