标题:请教大家关于代码中 #ifdef #ifndef 之类的问题, 在哪里找到或是定义这些变 ...
只看楼主
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
结帖率:98.63%
已结贴  问题点数:100 回复次数:14 
请教大家关于代码中 #ifdef #ifndef 之类的问题, 在哪里找到或是定义这些变量,百分诚心求教(4号字体,大行间距,易于阅读)
请教大家关于头文件中 #ifdef #ifndef 之类的问题

在linux中下一些源码来看,经常会在.c  文件中看到类似于下面的关于  #if  #ifdef  #ifndef 的语句

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* if compiling for Windows, use this separate set
  (too difficult to ifdef all the autoconf defines) */
#ifdef WIN32
/*** Windows includes ***/

#else
/*** autoconf includes ***/

#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <getopt.h>
#include <stdarg.h>
#include <netinet/in.h>
#include "config.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif /* HAVE_STDLIB_H */
#include <string.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#if HAVE_SYS_FILE_H
#include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#ifdef IPV6
#include <netinet/icmp6.h>
#endif
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <netdb.h>
/* RS6000 has sys/select.h */
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif /* HAVE_SYS_SELECT_H */
#endif /* WIN32 */
#include "options.h"
/*** externals ***/
extern char *optarg;
extern int optind,opterr;
extern int h_errno;
#ifdef __cplusplus
}
#endif /* __cplusplus */

比如#ifdef __cplusplus, #ifdef WIN32

更莫名其妙的如 #ifdef HAVE_STDLIB_H,#ifdef HAVE_UNISTD_H

这些都是什么意思, 我大体明白是说 如果定义了神码神码 就神码神码   之类

关键是我从哪里知道定义还是没有定义这些东西?

下载下来的源码在安装是一般会有 $ ./configure 这一步, 难道是这个配置过程中就自动检测了

机器已经定义了哪些变量?

gcc 编译器在编译时候有 -D name 这个选项 , name 可以是个宏,

难道从这个-D 这里也可以指定 定义哪些变量?

还有就是 最上面那个extern "C" 也经常看到, 又是什么意思?

类似于HAVE_STDLIB_H , HAVE_UNISTD_H 之类,它们的出处是哪里,从哪里可以找到,

我好像在gcc 的 predefined macros 中没有看到这几个变量

问题太多, 对不住了, 这个问题对我来说值200分,那就先放100分上来

诚心求教,希望大家支持



[ 本帖最后由 madfrogme 于 2012-11-9 01:45 编辑 ]
搜索更多相关主题的帖子: separate includes difficult linux 
2012-11-08 23:12
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:40 
你认为你写的#include中,那些文件里面写的有什么?为什么不一直跟下去看看?

授人以渔,不授人以鱼。
2012-11-08 23:49
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
得分:0 
问题补充 。直接在linux中 编译下面这个程序,不用什么特别的方法,直接 gcc test.c 就可以编译

运行结果是 Dude, it's 'PROBABLY' Linux!   otis = 2

貌似编译器就已经帮我们判断了这个机器不是 _WIN32 ,处理这个过程的应该是preprocessor 吧

#include <stdio.h>

#ifdef _WIN32       /* MSDOS msdos  _msdos win32  _win32  don't work*/

  #define otis 1

  #include <windows.h>

#else

  #define DWORD unsigned long int

  #define otis 2

#endif

int main(void)
{
  if(otis == 1)
    printf("Dude, it's Windows! (32 anyhow, need a test on 64)  otis = %d \n", otis);

  else
    printf("Dude, it's 'PROBABLY' Linux!   otis = %d \n", otis);
  return 0;
}


The quieter you become, the more you can hear
2012-11-08 23:56
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
得分:0 
查了一下 extern "C" ,好像解释这个的时候经常会说写C++代码的时候加上这句

就可以使用C 的run-time library 了,应该就是比如在些C++代码的时候想加入

一些C函数,就可以在 extern  "C" {...} 中加入头文件,这样用C++ 的编译器来编译的

时候就可以识别了


The quieter you become, the more you can hear
2012-11-09 00:17
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
得分:0 

$ touch test.h; cpp -dM test.h

可以输出 GCC 的 一大串 Predefined Macros

虽然不知道有什么用


The quieter you become, the more you can hear
2012-11-09 00:26
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
得分:0 
关于 #ifdef HAVE_STDLIB_H

这好像也是一个头文件移植性的问题


http://www.

这个链接里有一些说明


The quieter you become, the more you can hear
2012-11-09 00:45
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
得分:10 
貌似#ifdef后面那个东西可以随便写 越难看越好。

梅尚程荀
马谭杨奚







                                                       
2012-11-09 00:58
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
得分:0 
编译下面这段代码的时候 如果加上gcc -o test test.c -D IPV6 ,则结果打印 IPV6, 所以说手动设定已经解决

但是如果想让机器自动检测的话该怎么办? 好像要用到 autoconf 这个工具, 好吧,我在看看

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(int argc, char *argv[])
{
    int i;
#ifdef IPV6
    if( ( i = socket( AF_INET6, SOCK_STREAM, 0 ) ) < 0 )
#else
    if( ( i = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
#endif
        perror("error");
        else{
        printf("socket created %d\n");
#ifdef IPV6
        printf("IPV6\n");
#else
        printf("IPV4\n");
#endif
    }
    return 0;
}


The quieter you become, the more you can hear
2012-11-09 01:01
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
得分:0 
回复 7楼 有容就大
是说HAVE_STDLIB_H , HAVE_UNISTD_H  类似的这几个东西可以随便写?

那比如说安装的时候让机器检测有没有定义的话,用什么方法?

据我所知autoconf 这个东西好像可以,但不知道是不是平台之间通用的

The quieter you become, the more you can hear
2012-11-09 01:05
LShang
Rank: 4
来 自:China
等 级:业余侠客
威 望:3
帖 子:183
专家分:258
注 册:2010-12-24
得分:30 
额 感觉T版说的很有道理啊
可以弄个多标签的编辑器然后快速搜索关键词嘛,应该很容易找到定义的位置。
另外关于安装那个就不懂了,对Linux研究甚少

学如逆水行舟,不进则退
士不可以不弘毅,任重而道远
2012-11-09 01:31



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-386477-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.212697 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved