查找系统定义size_t , va_list , va_start , va_end 等不常见宏(变量)头文件所在

1.序

在创建一个新项目时,往往我们会使用到如: size_t , va_list , va_start , va_end ,false , true 等不常见宏(变量),经常会报错,说未定义。而这些宏(变量)又不是在标准的glibc库当中实现的,而是gcc中实现/定义。使用man命令压根找不到信息,这里我们需要一点技巧。

2.例子

#include 
int os_sprintf(char *buf,int size,const char *fmt, ...)
{
    int ret;
    va_list args;
    va_start(args, fmt);
    ret = vsnprintf(buf, size, fmt, args);
    va_end(args);
    buf[size - 1] = '\0';
    return ret;
}
int main()
{
    size_t i;
    char buf[128];
    int ret;
    bool bl;
    ret = os_sprintf(buf,sizeof(buf),"%s%s","hello","world");
    if(ret < 0)
        bl = false;
    else
        bl = true;
    return 0;
}

编译

leon@netview:~/test/test$ gcc -o test test.c 
test.c: In function 'os_sprintf':
test.c:7:2: error: unknown type name 'va_list'
  va_list args;
  ^
test.c: In function 'main':
test.c:20:2: error: unknown type name 'bool'
  bool bl;
  ^
test.c:23:8: error: 'false' undeclared (first use in this function)
   bl = false;
        ^
test.c:23:8: note: each undeclared identifier is reported only once for each function it appears in
test.c:25:8: error: 'true' undeclared (first use in this function)
   bl = true;
        ^
leon@netview:~/test/test$ 
leon@netview:~/test/test$ 

详细编译信息:

leon@netview:~/test/test$ gcc -v -o test test.c 
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.8/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04.3' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-i386/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-i386 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-i386 --with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-targets=all --enable-multiarch --disable-werror --with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3) 
COLLECT_GCC_OPTIONS='-v' '-o' 'test' '-mtune=generic' '-march=i686'
 /usr/lib/gcc/i686-linux-gnu/4.8/cc1 -quiet -v -imultiarch i386-linux-gnu test.c -quiet -dumpbase test.c -mtune=generic -march=i686 -auxbase test -version -fstack-protector -Wformat -Wformat-security -o /tmp/ccCzslr9.s
GNU C (Ubuntu 4.8.4-2ubuntu1~14.04.3) version 4.8.4 (i686-linux-gnu)
        compiled by GNU C version 4.8.4, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/i386-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/i686-linux-gnu/4.8/../../../../i686-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/i686-linux-gnu/4.8/include
 /usr/local/include
 /usr/lib/gcc/i686-linux-gnu/4.8/include-fixed
 /usr/include/i386-linux-gnu
 /usr/include
End of search list.
GNU C (Ubuntu 4.8.4-2ubuntu1~14.04.3) version 4.8.4 (i686-linux-gnu)
        compiled by GNU C version 4.8.4, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 9dadfc6552e733d9314bd8a1f66914a8
test.c: In function 'os_sprintf':
test.c:7:2: error: unknown type name 'va_list'
  va_list args;
  ^
test.c: In function 'main':
test.c:20:2: error: unknown type name 'bool'
  bool bl;
  ^
test.c:23:8: error: 'false' undeclared (first use in this function)
   bl = false;
        ^
test.c:23:8: note: each undeclared identifier is reported only once for each function it appears in
test.c:25:8: error: 'true' undeclared (first use in this function)
   bl = true;
        ^
leon@netview:~/test/test$ 
leon@netview:~/test/test$ 

我们可以看到如下段:

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/i686-linux-gnu/4.8/include
 /usr/local/include
 /usr/lib/gcc/i686-linux-gnu/4.8/include-fixed
 /usr/include/i386-linux-gnu
 /usr/include

可以看出GCC默认搜索的头文件。后面通过搜索得知,
缺少的东西都在以下几个文件当中:

#include              //定义了size_t
#include             //定义了bool,false,true
#include              //定义了va_list , va_start , va_end

3.修改后的代码

#include 
#include 
#include 
#include 

int os_sprintf(char *buf,int size,const char *fmt, ...)
{
    int ret;
    va_list args;
    va_start(args, fmt);
    ret = vsnprintf(buf, size, fmt, args);
    va_end(args);
    buf[size - 1] = '\0';
    return ret;
}

int main()
{
    size_t i;
    char buf[128];
    int ret;
    bool bl;
    ret = os_sprintf(buf,sizeof(buf),"%s%s","hello","world");
    if(ret < 0)
        bl = false;
    else
        bl = true;
    return 0;
}

再次编译就不报错了。

当然有些头文件包含了以上头文件,同样也不会报错。但原理是一样的。

I.拓展

默认的可执行程序搜索路径,环境变量为 $PATH

export PATH="/home/leon/cross-arm/usr/local/arm/4.3.2/bin:$PATH"

默认的库搜索路径,环境变量为 $LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/home/leon/nvc/arm-hisiv300-linux/lib:$LD_LIBRARY_PATH

你可能感兴趣的:(Linux,命令,编译器)