本文介绍了使用GCC编译C项目时采用哪些默认库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有简单的应用程式:

I have simple application:

#include <stdio.h>
int main( int argc, char ** argv )
{
    printf( "hello");
    exit( 0 );
}

当我使用命令编译它时

When I compile it with command

gcc -c count_words.c

I有警告:

I have warning:

warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
     exit( 0 );

我试图找到 exit()功能被定义。并发现它在 stdlib.h 中定义。但它不包含在我的项目中,并且在编译命令中没有定义其他库。

I was trying to find where exit() function is defined. And found that it is defined in stdlib.h. But it is not included in my project and no additional libs defined in compile command.

如果我错了,纠正我,但看起来像 gcc 将一些库作为默认值。什么是这些库,是否有可能告诉gcc不包括它们?

Correct me if I'm wrong, but looks like gcc takes some libs as default. What are these libs and is it possible to tell gcc not include them?

为什么编译器不满意 exit(0)假设它以某种方式包含 stdlib.h 作为默认值?

Why compiler is not happy regarding exit(0) assuming that it somehow includes stdlib.h as default?

推荐答案


Let's take your example:

#include <stdio.h>

int main( int argc, char ** argv )
{
    printf("hello\n");
    exit(56);
}

虽然我们在汇编时收到警告:

Although we get a warning on compilation:

~$ gcc test.c -o test
test.c: In function ‘main’:
test.c:6:5: warning: implicit declaration of function ‘exit’ [-Wimplicit-function-declaration]
     exit(56);
     ^
test.c:6:5: warning: incompatible implicit declaration of built-in function ‘exit’
test.c:6:5: note: include ‘<stdlib.h>’ or provide a declaration of ‘exit’

无论如何,我想你已经尝试过运行它并确保它可以正常工作:

Anyway, I think you have tried to run it and make sure it works:

~$ ./test
hello
~$ echo $?
56

是正确的,当他说:

@Mat was right when he said that:

C 编译器和链接器是完全单独的工具。让我们看看这个。实际上,这个程序依赖于标准的C库(如果你没有将 -nostdlib 传递给编译器)以及一些系统库(如loader和vdso) 。您可能会看到它:

The C compiler and linker are totally separate tools. Let's look on this. Actually, this program depends on the standard C library (as all programs if you didn't pass -nostdlib to compiler) and a couple of system libraries (like loader and vdso). You may see it with:

~$ ldd test
    linux-vdso.so.1 (0x00007fff1b128000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f804389f000)
    /lib64/ld-linux-x86-64.so.2 (0x0000557744537000)

这三个库是任何程序的最小集合。在我们的例子中, exit 函数是在标准库中定义的,或者是 libc.so.6 。现在我们来看看详细模式下的编译过程。您可以通过将 -v - verbose 选项传递给编译器来实现此目的:

These three library is a minimal set for any program. The exit function is defined in the standard library or libc.so.6 in our case. Now let's look on the compilation process in verbose mode. You can achieve this by the passing -v or --verbose option to compiler:

gcc test.c -o test --verbose

如果您执行此操作,您会发现如下所示的行:

If you will execute this, you will find lines like these:

#include <...> search starts here:
/usr/lib/gcc/x86_64-redhat-linux/5.3.1/include
/usr/local/include
/usr/include

因此,compile知道在哪里搜索 stdlib 的头文件,搜索它以查找非本地功能的声明。请注意,它仅在您的源代码文件中包含的头文件中进行搜索。它可以在 stdio.h 中找到 printf 声明,但找不到退出。

So, compile knows where to search header files for stdlib and it starts to search it to find declaration for non-local functions. Note that it searches only in header files which are included in your source code file. It can find printf declaration in thestdio.h, but can't locate declaration of the exit.

在此步骤之后,编译开始将程序与库链接起来:

After this step, the compile starts to link your program with libraries:

/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/collect2 ... -lc ...

其中 collect2 是gcc util,它试图将您的程序与 lc 这是标准的C库。请注意,该过程由两个步骤组成:编译和链接。这就是为什么你的程序能正常工作。

Where collect2 is gcc util which tries to link your program with lc which is standard C library. Note that the process consists from two steps: compilation and linking. That's why your program works.

另外, gcc 支持 -M 选项,它会告诉你主文件的依赖关系。所以,如果你要执行它,你会看到一组头文件,包括 stdio.h ,但不是 stdlib.h

Additionally, gcc supports -M option which will tell you about dependencies of the main file. So, if you will execute it, you will see the set of header files including stdio.h, but not stdlib.h:

$ gcc -M test.c
test.o: test.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/sys/cdefs.h \
 /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
 /usr/include/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.h \
 /usr/include/bits/types.h /usr/include/bits/typesizes.h \
 /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stdarg.h \
 /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h

甚至尝试将 -E 选项传递给 gcc

Or even better, try to pass -E option to gcc:

$ gcc -E test.c

第一次看到结果舞台 - 预处理阶段。我认为这是理解你为什么得到这个警告的最简单的方法。

and you will see result right after the first stage - preprocessing stage. I think it is the easiest way to understand why you are getting this warning.

这篇关于使用GCC编译C项目时采用哪些默认库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 15:52