errno.h

2008年12月23日 06:54

终于到了一个稍微轻松一点儿的地方。:) 但是依然很重要。

这个文件的内容相对来说是比较简单的,就是定义了一些宏,在这里我不打算贴出GNU C lib里面的代码,原因其一是里面的红开关太多,以至于我弄不大清楚到底是用了哪个文件。不过对于linux来说,就是include下面的那个没错啦。当然这个还是“指向”了/include/sys/errno.h

在cygwin下的:

$ less errno.h
/* errno is not a global variable, because that would make using it
   non-reentrant.  Instead, its address is returned by the function
   __errno.  */


#ifndef _SYS_ERRNO_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _SYS_ERRNO_H_

#include <sys/reent.h>

#ifndef _REENT_ONLY
#define errno (*__errno())
extern int *__errno _PARAMS ((void));
#endif

/* Please don't use these variables directly.
   Use strerror instead. */

extern __IMPORT _CONST char * _CONST _sys_errlist[];
extern __IMPORT int _sys_nerr;
#ifdef __CYGWIN__
extern __IMPORT const char * const sys_errlist[];
extern __IMPORT int sys_nerr;
#endif

#define __errno_r(ptr) ((ptr)->_errno)

#define EPERM 1         /* Not super-user */
#define ENOENT 2        /* No such file or directory */
#define ESRCH 3         /* No such process */
#define EINTR 4         /* Interrupted system call */
#define EIO 5           /* I/O error */
#define ENXIO 6         /* No such device or address */
#define E2BIG 7         /* Arg list too long */
#define ENOEXEC 8       /* Exec format error */
#define EBADF 9         /* Bad file number */
#define ECHILD 10       /* No children */
#define EAGAIN 11       /* No more processes */
#define ENOMEM 12       /* Not enough core */
#define EACCES 13       /* Permission denied */
#define EFAULT 14       /* Bad address */
#define ENOTBLK 15      /* Block device required */
#define EBUSY 16        /* Mount device busy */
#define EEXIST 17       /* File exists */
#define EXDEV 18        /* Cross-device link */
#define ENODEV 19       /* No such device */
#define ENOTDIR 20      /* Not a directory */
#define EISDIR 21       /* Is a directory */
#define EINVAL 22       /* Invalid argument */
#define ENFILE 23       /* Too many open files in system */
#define EMFILE 24       /* Too many open files */
#define ENOTTY 25       /* Not a typewriter */
#define ETXTBSY 26      /* Text file busy */
#define EFBIG 27        /* File too large */
#define ENOSPC 28       /* No space left on device */
#define ESPIPE 29       /* Illegal seek */
#define EROFS 30        /* Read only file system */
#define EMLINK 31       /* Too many links */
#define EPIPE 32        /* Broken pipe */
#define EDOM 33         /* Math arg out of domain of func */
#define ERANGE 34       /* Math result not representable */
#define ENOMSG 35       /* No message of desired type */
#define EIDRM 36        /* Identifier removed */
#define ECHRNG 37       /* Channel number out of range */
#define EL2NSYNC 38     /* Level 2 not synchronized */
#define EL3HLT 39       /* Level 3 halted */
#define EL3RST 40       /* Level 3 reset */
#define ELNRNG 41       /* Link number out of range */
#define EUNATCH 42      /* Protocol driver not attached */
#define ENOCSI 43       /* No CSI structure available */
#define EL2HLT 44       /* Level 2 halted */
#define EDEADLK 45      /* Deadlock condition */
#define ENOLCK 46       /* No record locks available */
#define EBADE 50        /* Invalid exchange */
#define EBADR 51        /* Invalid request descriptor */
#define EXFULL 52       /* Exchange full */
#define ENOANO 53       /* No anode */
#define EBADRQC 54      /* Invalid request code */
#define EBADSLT 55      /* Invalid slot */
#define EDEADLOCK 56    /* File locking deadlock error */
#define EBFONT 57       /* Bad font file fmt */
#define ENOSTR 60       /* Device not a stream */
#define ENODATA 61      /* No data (for no delay io) */
#define ETIME 62        /* Timer expired */
#define ENOSR 63        /* Out of streams resources */
#define ENONET 64       /* Machine is not on the network */
#define ENOPKG 65       /* Package not installed */
#define EREMOTE 66      /* The object is remote */
#define ENOLINK 67      /* The link has been severed */
#define EADV 68         /* Advertise error */
#define ESRMNT 69       /* Srmount error */
#define ECOMM 70        /* Communication error on send */
#define EPROTO 71       /* Protocol error */
#define EMULTIHOP 74    /* Multihop attempted */
#define ELBIN 75        /* Inode is remote (not really error) */
#define EDOTDOT 76      /* Cross mount point (not really error) */
#define EBADMSG 77      /* Trying to read unreadable message */
#define EFTYPE 79       /* Inappropriate file type or format */
#define ENOTUNIQ 80     /* Given log. name not unique */
#define EBADFD 81       /* f.d. invalid for this operation */
#define EREMCHG 82      /* Remote address changed */
#define ELIBACC 83      /* Can't access a needed shared lib */
#define ELIBBAD 84      /* Accessing a corrupted shared lib */
#define ELIBSCN 85      /* .lib section in a.out corrupted */
#define ELIBMAX 86      /* Attempting to link in too many libs */
#define ELIBEXEC 87     /* Attempting to exec a shared library */
#define ENOSYS 88       /* Function not implemented */
#define ENMFILE 89      /* No more files */
#define ENOTEMPTY 90    /* Directory not empty */
#define ENAMETOOLONG 91 /* File or path name too long */
#define ELOOP 92        /* Too many symbolic links */
#define EOPNOTSUPP 95   /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define ECONNRESET 104  /* Connection reset by peer */
#define ENOBUFS 105     /* No buffer space available */
#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
#define EPROTOTYPE 107  /* Protocol wrong type for socket */
#define ENOTSOCK 108    /* Socket operation on non-socket */
#define ENOPROTOOPT 109 /* Protocol not available */
#define ESHUTDOWN 110   /* Can't send after socket shutdown */
#define ECONNREFUSED 111        /* Connection refused */
#define EADDRINUSE 112          /* Address already in use */
#define ECONNABORTED 113        /* Connection aborted */
#define ENETUNREACH 114         /* Network is unreachable */
#define ENETDOWN 115            /* Network interface is not configured */
#define ETIMEDOUT 116           /* Connection timed out */
#define EHOSTDOWN 117           /* Host is down */
#define EHOSTUNREACH 118        /* Host is unreachable */
#define EINPROGRESS 119         /* Connection already in progress */
#define EALREADY 120            /* Socket already connected */
#define EDESTADDRREQ 121        /* Destination address required */
#define EMSGSIZE 122            /* Message too long */
#define EPROTONOSUPPORT 123     /* Unknown protocol */
#define ESOCKTNOSUPPORT 124     /* Socket type not supported */
#define EADDRNOTAVAIL 125       /* Address not available */
#define ENETRESET 126
#define EISCONN 127             /* Socket is already connected */
#define ENOTCONN 128            /* Socket is not connected */
#define ETOOMANYREFS 129
#define EPROCLIM 130
#define EUSERS 131
#define EDQUOT 132
#define ESTALE 133
#define ENOTSUP 134             /* Not supported */
#define ENOMEDIUM 135   /* No medium (in tape drive) */
#define ENOSHARE 136    /* No such host or network path */
#define ECASECLASH 137  /* Filename exists with different case */
#define EILSEQ 138
#define EOVERFLOW 139   /* Value too large for defined data type */

/* From cygwin32.  */
#define EWOULDBLOCK EAGAIN      /* Operation would block */

#define __ELASTERROR 2000       /* Users can add values starting here */

#ifdef __cplusplus
}
#endif
#endif /* _SYS_ERRNO_H */

可以看到用到了139. 在POSIX中定义errno为extern int errno可见还有足够用的空间。 -_#

对标准的支持是不尽相同的。POSIX标准请看这里

为了证明这个,俺写了一点点代码来看看。

#include "stdio.h"
#include "errno.h"

int main(int argc, char * argv[])
{
        int i = 0;
        for(i = 0; i < 256; i++)
        {
                (void)fprintf(stderr,"%d error is %s",i,strerror(i));
                perror(argv[0]);
        }
        return 0;
}

分别用gcc:

$ gcc -v
Using built-in specs.
Target: i686-pc-cygwin
Configured with: ./configure
Thread model: single
gcc version 4.3.0 (GCC)

arm-elf-gcc:

Reading specs from /cygdrive/e/program files/gnuarm/bin/../lib/gcc/arm-elf/3.4.3/specs
Configured with: ../gcc-3.4.3/configure --target=arm-elf --prefix=/c/gnuarm-3.4.3 --enable-interwork --enable-multilib --with-float=soft --with-newlib --with-headers=../newlib-1.12.0/newlib/libc/include --enable-languages=c,c++,java --disable-libgcj Thread model: single
gcc version 3.4.3

和cl

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

来编译生成可执行文件。

gcc输出的是什么呢?

0 error is No error./a: No error
1 error is Operation not permitted./a: No error
2 error is No such file or directory./a: No error
3 error is No such process./a: No error
4 error is Interrupted system call./a: No error
5 error is Input/Output error./a: No error
6 error is No such device or address./a: No error
7 error is Argument list too long./a: No error
8 error is Exec format error./a: No error
9 error is Bad file descriptor./a: No error
10 error is No child processes./a: No error
11 error is Resource temporarily unavailable./a: No error
12 error is Cannot allocate memory./a: No error
13 error is Permission denied./a: No error
14 error is Bad address./a: No error
15 error is Block device required./a: No error
16 error is Device or resource busy./a: No error
17 error is File exists./a: No error
18 error is Invalid cross-device link./a: No error
19 error is No such device./a: No error
20 error is Not a directory./a: No error
21 error is Is a directory./a: No error
22 error is Invalid argument./a: No error
23 error is Too many open files in system./a: No error
24 error is Too many open files./a: No error
25 error is Inappropriate ioctl for device./a: No error
26 error is Text file busy./a: No error
27 error is File too large./a: No error
28 error is No space left on device./a: No error
29 error is Illegal seek./a: No error
30 error is Read-only file system./a: No error
31 error is Too many links./a: No error
32 error is Broken pipe./a: No error
33 error is Numerical argument out of domain./a: No error
34 error is Numerical result out of range./a: No error
35 error is No message of desired type./a: No error
36 error is Identifier removed./a: No error
37 error is Channel number out of range./a: No error
38 error is Level 2 not synchronized./a: No error
39 error is Level 3 halted./a: No error
40 error is Level 3 reset./a: No error
41 error is Link number out of range./a: No error
42 error is Protocol driver not attached./a: No error
43 error is No CSI structure available./a: No error
44 error is Level 2 halted./a: No error
45 error is Resource deadlock avoided./a: No error
46 error is No locks available./a: No error
47 error is error 47./a: No error
48 error is error 48./a: No error
49 error is error 49./a: No error
50 error is Invalid exchange./a: No error
51 error is Invalid request descriptor./a: No error
52 error is Exchange full./a: No error
53 error is No anode./a: No error
54 error is Invalid request code./a: No error
55 error is Invalid slot./a: No error
56 error is File locking deadlock error./a: No error
57 error is Bad font file format./a: No error
58 error is error 58./a: No error
59 error is error 59./a: No error
60 error is Device not a stream./a: No error
61 error is No data available./a: No error
62 error is Timer expired./a: No error
63 error is Out of streams resources./a: No error
64 error is Machine is not on the network./a: No error
65 error is Package not installed./a: No error
66 error is Object is remote./a: No error
67 error is Link has been severed./a: No error
68 error is Advertise error./a: No error
69 error is Srmount error./a: No error
70 error is Communication error on send./a: No error
71 error is Protocol error./a: No error
72 error is error 72./a: No error
73 error is error 73./a: No error
74 error is Multihop attempted./a: No error
75 error is Inode is remote (not really error)./a: No error
76 error is RFS specific error./a: No error
77 error is Bad message./a: No error
78 error is error 78./a: No error
79 error is Inappropriate file type or format./a: No error
80 error is Name not unique on network./a: No error
81 error is File descriptor in bad state./a: No error
82 error is Remote address changed./a: No error
83 error is Can not access a needed shared library./a: No error
84 error is Accessing a corrupted shared library./a: No error
85 error is .lib section in a.out corrupted./a: No error
86 error is Attempting to link in too many shared libraries./a: No error
87 error is Cannot exec a shared library directly./a: No error
88 error is Function not implemented./a: No error
89 error is No more files./a: No error
90 error is Directory not empty./a: No error
91 error is File name too long./a: No error
92 error is Too many levels of symbolic links./a: No error
93 error is error 93./a: No error
94 error is error 94./a: No error
95 error is Operation not supported./a: No error
96 error is Protocol family not supported./a: No error
97 error is error 97./a: No error
98 error is error 98./a: No error
99 error is error 99./a: No error
100 error is error 100./a: No error
101 error is error 101./a: No error
102 error is error 102./a: No error
103 error is error 103./a: No error
104 error is Connection reset by peer./a: No error
105 error is No buffer space available./a: No error
106 error is Address family not supported by protocol./a: No error
107 error is Protocol wrong type for socket./a: No error
108 error is Socket operation on non-socket./a: No error
109 error is Protocol not available./a: No error
110 error is Cannot send after transport endpoint shutdown./a: No error
111 error is Connection refused./a: No error
112 error is Address already in use./a: No error
113 error is Software caused connection abort./a: No error
114 error is Network is unreachable./a: No error
115 error is Network is down./a: No error
116 error is Connection timed out./a: No error
117 error is Host is down./a: No error
118 error is No route to host./a: No error
119 error is Operation now in progress./a: No error
120 error is Operation already in progress./a: No error
121 error is Destination address required./a: No error
122 error is Message too long./a: No error
123 error is Protocol not supported./a: No error
124 error is Socket type not supported./a: No error
125 error is Cannot assign requested address./a: No error
126 error is Network dropped connection on reset./a: No error
127 error is Transport endpoint is already connected./a: No error
128 error is Transport endpoint is not connected./a: No error
129 error is Too many references: cannot splice./a: No error
130 error is Too many processes./a: No error
131 error is Too many users./a: No error
132 error is Disk quota exceeded./a: No error
133 error is Stale NFS file handle./a: No error
134 error is Not supported./a: No error
135 error is No medium found./a: No error
136 error is No such host or network path./a: No error
137 error is Filename exists with different case./a: No error
138 error is Invalid or incomplete multibyte or wide character./a: No error
139 error is Value too large for defined data type./a: No error
140 error is Unknown error 140./a: No error
141 error is Unknown error 141./a: No error
142 error is Unknown error 142./a: No error

arm-elf-gcc的输出:

0 error is a.out:
1 error is Not ownera.out:
2 error is No such file or directorya.out:
3 error is No such processa.out:
4 error is Interrupted system calla.out:
5 error is I/O errora.out:
6 error is No such device or addressa.out:
7 error is Arg list too longa.out:
8 error is Exec format errora.out:
9 error is Bad file numbera.out:
10 error is No childrena.out:
11 error is No more processesa.out:
12 error is Not enough spacea.out:
13 error is Permission denieda.out:
14 error is Bad addressa.out:
15 error is Block device requireda.out:
16 error is Device or resource busya.out:
17 error is File existsa.out:
18 error is Cross-device linka.out:
19 error is No such devicea.out:
20 error is Not a directorya.out:
21 error is Is a directorya.out:
22 error is Invalid argumenta.out:
23 error is Too many open files in systema.out:
24 error is Too many open filesa.out:
25 error is Not a character devicea.out:
26 error is Text file busya.out:
27 error is File too largea.out:
28 error is No space left on devicea.out:
29 error is Illegal seeka.out:
30 error is Read-only file systema.out:
31 error is Too many linksa.out:
32 error is Broken pipea.out:
33 error is Math argumenta.out:
34 error is Result too largea.out:
35 error is No message of desired typea.out:
36 error is Identifier removeda.out:
37 error is a.out:
38 error is a.out:
39 error is a.out:
40 error is a.out:
41 error is a.out:
42 error is a.out:
43 error is a.out:
44 error is a.out:
45 error is Deadlocka.out:
46 error is No locka.out:
47 error is a.out:
48 error is a.out:
49 error is a.out:
50 error is a.out:
51 error is a.out:
52 error is a.out:
53 error is a.out:
54 error is a.out:
55 error is a.out:
56 error is a.out:
57 error is a.out:
58 error is a.out:
59 error is a.out:
60 error is Not a streama.out:
61 error is a.out:
62 error is Stream ioctl timeouta.out:
63 error is No stream resourcesa.out:
64 error is Machine is not on the networka.out:
65 error is No packagea.out:
66 error is Resource is remotea.out:
67 error is Virtual circuit is gonea.out:
68 error is Advertise errora.out:
69 error is Srmount errora.out:
70 error is Communication errora.out:
71 error is Protocol errora.out:
72 error is a.out:
73 error is a.out:
74 error is Multihop attempteda.out:
75 error is a.out:
76 error is a.out:
77 error is Bad messagea.out:
78 error is a.out:
79 error is a.out:
80 error is a.out:
81 error is a.out:
82 error is a.out:
83 error is Cannot access a needed shared librarya.out:
84 error is Accessing a corrupted shared librarya.out:
85 error is .lib section in a.out corrupteda.out:
86 error is Attempting to link in more shared libraries than system limita.o
87 error is Cannot exec a shared library directlya.out:
88 error is Function not implementeda.out:
89 error is No more filesa.out:
90 error is Directory not emptya.out:
91 error is File or path name too longa.out:
92 error is Too many symbolic linksa.out:
93 error is a.out:
94 error is a.out:
95 error is Operation not supported on socketa.out:
96 error is a.out:
97 error is a.out:
98 error is a.out:
99 error is a.out:
100 error is a.out:
101 error is a.out:
102 error is a.out:
103 error is a.out:
104 error is a.out:
105 error is No buffer space availablea.out:
106 error is Address family not supported by protocol familya.out:
107 error is Protocol wrong type for socketa.out:
108 error is Socket operation on non-socketa.out:
109 error is Protocol not availablea.out:
110 error is Can't send after socket shutdowna.out:
111 error is Connection refuseda.out:
112 error is Address already in usea.out:
113 error is Software caused connection aborta.out:
114 error is Network is unreachablea.out:
115 error is Network interface is not configureda.out:
116 error is Connection timed outa.out:
117 error is Host is downa.out:
118 error is Host is unreachablea.out:
119 error is Connection already in progressa.out:
120 error is Socket already connecteda.out:
121 error is Destination address requireda.out:
122 error is Message too longa.out:
123 error is Unknown protocola.out:
124 error is Socket type not supporteda.out:
125 error is a.out:
126 error is a.out:
127 error is Socket is already connecteda.out:
128 error is Socket is not connecteda.out:
129 error is a.out:
130 error is a.out:
131 error is a.out:
132 error is a.out:
133 error is a.out:
134 error is Not supporteda.out:
135 error is a.out:
136 error is a.out:
137 error is a.out:
138 error is a.out:

cl的输出:

0 error is No errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
1 error is Operation not permittedf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
2 error is No such file or directoryf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
3 error is No such processf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
4 error is Interrupted function callf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
5 error is Input/output errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
6 error is No such device or addressf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
7 error is Arg list too longf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
8 error is Exec format errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
9 error is Bad file descriptorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
10 error is No child processesf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
11 error is Resource temporarily unavailablef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
12 error is Not enough spacef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
13 error is Permission deniedf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
14 error is Bad addressf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
15 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
16 error is Resource devicef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
17 error is File existsf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
18 error is Improper linkf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
19 error is No such devicef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
20 error is Not a directoryf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
21 error is Is a directoryf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
22 error is Invalid argumentf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
23 error is Too many open files in systemf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
24 error is Too many open filesf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
25 error is Inappropriate I/O control operationf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
26 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
27 error is File too largef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
28 error is No space left on devicef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
29 error is Invalid seekf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
30 error is Read-only file systemf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
31 error is Too many linksf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
32 error is Broken pipef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
33 error is Domain errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
34 error is Result too largef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
35 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
36 error is Resource deadlock avoidedf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
37 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
38 error is Filename too longf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
39 error is No locks availablef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
40 error is Function not implementedf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
41 error is Directory not emptyf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
42 error is Illegal byte sequencef:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
43 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
44 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
45 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
46 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
47 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
48 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error
49 error is Unknown errorf:\MyDocument\Projects\TestEOF\Debug\TestEOF.exe: No error

哦,天,从这一点看来VC 6.0对POSIX的支持还真不怎么样。有没有兄弟有最新的VC编译器跑的结果让俺看看?谢谢!

哗啦哗啦贴了这么多东东,我们总是要总结出来一些东东的吧。

好,1,我首先就看到0这个errno是永远不会被认为是出错的!大名鼎鼎的APUE也是这么说的;2,对标准要支持,因此对于宏值要注意对应;3,我们应该选择对标准支持更好的系统。

ctype.h

2008年12月21日 19:00

本篇小文来讲述一下ctype.h中提供的函数有哪些以及应用场合和实现。并提出的我的疑问。

为什么有这个库函数族?
在我们写程序的时候经常会碰到对于英文字母,阿拉伯数字等等的判断,这样C库中的ctype.h就为我们提供这些功能。当然根据有些特殊的编码C库还提供了wctype.h的另一组库函数。这些函数都是以is开始的。
都提供了我们什么功能?

int isalnum(int c);

函数判断(大小写)字符以及阿拉伯数字。

int isalpha(int c);
函数判断(大小写)字符

int isblank(int c)
判断空字符,包括空格和制表符
int iscntrl(int c);
函数判断是不是控制字符。控制字符包括: BEL BS CR FF HT NL VT

int isdigit(int c);
函数判断是不是阿拉伯数字:0 1 2 3 4 5 6 7 8 9

int isgraph(int c);

函数判断是不是可打印字符(不包含空格)

int islower(int c);

函数判断是不是小写字符


int isprint(int c);
函数判断是不是可打印字符(包含空格)

int ispunct(int c);

函数判断是不是标点字符:! " # % & ' ( ) ; < = > ? [ \ ] * + , - . / : ^ _ { | } ~

int isspace(int c);

函数CR FF HT NL VT space

int isupper(int c);
函数判断如果不是如下字符则返回0
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

int isxdigit(int c);
函数判断如果不是如下字符则返回0
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

由于(仅)涉及到ascii字符的处理,我觉得有必要把ascii码表分区复习一下:

ascii码表简单说就是把char能表示的字符在一个表格中描述出来。用7bit表示的128个字符

接下来我们可以看一下ctype.c中的处理部分,这里我有对locale的内容的疑问,有哪位明白请指点指点。(我仅仅知道locale是用做区域设置,但没有了解过locale的根本原理。

# define isalnum(c)     __isctype((c), _ISalnum)
# define isalpha(c)     __isctype((c), _ISalpha)
# define iscntrl(c)     __isctype((c), _IScntrl)
# define isdigit(c)     __isctype((c), _ISdigit)
# define islower(c)     __isctype((c), _ISlower)
# define isgraph(c)     __isctype((c), _ISgraph)
# define isprint(c)     __isctype((c), _ISprint)
# define ispunct(c)     __isctype((c), _ISpunct)
# define isspace(c)     __isctype((c), _ISspace)
# define isupper(c)     __isctype((c), _ISupper)
# define isxdigit(c)    __isctype((c), _ISxdigit)
 

这里根据不同的类型使用了不同的mask值。

--isctype看起来就是从当前LC_TYPE指定的

int
__isctype (ch, mask)
     int ch;
     int mask;
{
  return (((uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS) + 128)
          [(int) (ch)] & mask);
}

{
  _ISupper = _ISbit (0),        /* UPPERCASE.  */
  _ISlower = _ISbit (1),        /* lowercase.  */
  _ISalpha = _ISbit (2),        /* Alphabetic.  */
  _ISdigit = _ISbit (3),        /* Numeric.  */
  _ISxdigit = _ISbit (4),       /* Hexadecimal numeric.  */
  _ISspace = _ISbit (5),        /* Whitespace.  */
  _ISprint = _ISbit (6),        /* Printing.  */
  _ISgraph = _ISbit (7),        /* Graphical.  */
  _ISblank = _ISbit (8),        /* Blank (usually SPC and TAB).  */
  _IScntrl = _ISbit (9),        /* Control character.  */
  _ISpunct = _ISbit (10),       /* Punctuation.  */
  _ISalnum = _ISbit (11)        /* Alphanumeric.  */
}

#if __BYTE_ORDER == __BIG_ENDIAN
#define _ISbit(bit)     (1 << (bit))
#else /* __BYTE_ORDER == __LITTLE_ENDIAN */
#define _ISbit(bit)     ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8))
#endif

这里是我比较困惑的地方,这种mask的是如何定义的?

__isctype又是为何这样实现的?

小结一下,虽然从代码中没有看出什么端倪,但是我明确了这些库函数的使用,以及彼此之间的区别。似乎还和locale有关,这个还是需要进一步了解一下的。

Assert

2008年9月05日 22:41

 

/* 以上为活跃c.c.l.c组内容乱写,版权所有,谢绝转载  */

/* ++ Assert.h */

/* 去掉头文件说明  */

/*
 *    ISO C99 Standard: 7.2 Diagnostics    <assert.h>
 */


#ifdef    _ASSERT_H

# undef    _ASSERT_H
# undef    assert
# undef __ASSERT_VOID_CAST

# ifdef    __USE_GNU
#  undef assert_perror
# endif

#endif /* assert.h    */

#define    _ASSERT_H    1
#include <features.h>

#if defined __cplusplus && __GNUC_PREREQ (2,95)
# define __ASSERT_VOID_CAST static_cast<void>
#else
# define __ASSERT_VOID_CAST (void)
#endif

/* void assert (int expression);

   If NDEBUG is defined, do nothing.
   If not, and EXPRESSION is zero, print an error message and abort.  */


#ifdef    NDEBUG

/* 为了当expr != 0 ,不输出任何内容 */
# define assert(expr)        (__ASSERT_VOID_CAST (0))

/* void assert_perror (int errnum);

   If NDEBUG is defined, do nothing.  If not, and ERRNUM is not zero, print an
   error message with the error text for ERRNUM and abort.
   (This is a GNU extension.) */


# ifdef    __USE_GNU
#  define assert_perror(errnum)    (__ASSERT_VOID_CAST (0))
# endif

/* 到这里可以看出如果定义了NDEBUG那么assert(expr) 这个宏就无效了  */

#else /* Not NDEBUG.  */

/* #ifdef    __cplusplus
 * # define __BEGIN_DECLS    extern "C" {
 * # define __END_DECLS    }
 * #else
 * # define __BEGIN_DECLS
 * # define __END_DECLS
 * #endif
 * 这个宏的目的就是给C++编译器看的,下面是C代码而不是C++的。实现如上
 */

__BEGIN_DECLS


/* 这里定义了两个宏, 这个assert是兼容标准C库,在assert.c会看到
 * __assert_fail()这个函数的实现。
 */

extern void __assert_fail (__const char *__assertion, __const char *__file,
               unsigned int __line, __const char *__function)
     __THROW __attribute__ ((__noreturn__));

/* 给GNU扩展用的  */
extern void __assert_perror_fail (int __errnum, __const char *__file,
                  unsigned int __line,
                  __const char *__function)
     __THROW __attribute__ ((__noreturn__));


/* 这个就是我们想看的宏  */
extern void __assert (const char *__assertion, const char *__file, int __line)
     __THROW __attribute__ ((__noreturn__));


/* 和上面的那个__BEGIN_DECLS对应  */
__END_DECLS


/* 这个是glibc的实现的宏  */

/* __STRING(expr)实现如下:
 * #define __STRING(x)    #x
 * 可以看到这个宏利用了宏定义的# 来达到传入表达式字符串的目的
 */


/* __ASSERT_FUNCTION实现如下:
 * # if defined __cplusplus ? __GNUC_PREREQ (2, 6) : __GNUC_PREREQ (2, 4)
 * #   define __ASSERT_FUNCTION    __PRETTY_FUNCTION__
 * # else
 * #  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
 * #   define __ASSERT_FUNCTION    __func__
 * #  else
 * #   define __ASSERT_FUNCTION    ((__const char *) 0)
 * #  endif
 * # endif
 *  可以看到这个宏的目的就是替代函数名
 * 但__STDC_VERSION__ >= 199901L是啥意思?
 */

 
/* 如下这种实现方式是规范要求
 * 规范的例子如下:
 * #undef assert
 * #ifdef NDEBUG
 * #define  assert(ignore)  ((void)0)  10
 * #else
 * extern void _ _gripe(char *_Expr, char *_File,
 *      int _Line, const char *_Func);
 * #define assert(expr) \
 *   ((expr) ? (void)0 :\  15
 *  _ _gripe(#expr, _ _FILE_ _,_ _LINE_ _,_ _func_ _))
 * #endif
 从这个例子中我们也可以看到glibc的实现和规范的参考设计有哪些不同
 */

 
# define assert(expr)                            \
  ((expr)                                \
   ? __ASSERT_VOID_CAST (0)                        \
   : __assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION))


/* 下面这个是GNU扩展用的。  */
# ifdef    __USE_GNU
#  define assert_perror(errnum)                        \
  (!(errnum)                                \
   ? __ASSERT_VOID_CAST (0)                        \
   : __assert_perror_fail ((errnum), __FILE__, __LINE__, __ASSERT_FUNCTION))
# endif

/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
   which contains the name of the function currently being defined.
   This is broken in G++ before version 2.6.
   C9x has a similar variable called __func__, but prefer the GCC one since
   it demangles C++ function names.  */

 
 
/* #if defined __GNUC__ && defined __GNUC_MINOR__
 * # define __GNUC_PREREQ(maj, min) \
 *     ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
 * #else
 * # define __GNUC_PREREQ(maj, min) 0
 * #endif
 * __GNUC_PREREQ就是一个方便看版本的宏,实现如上
 */

 
 
# if defined __cplusplus ? __GNUC_PREREQ (2, 6) : __GNUC_PREREQ (2, 4)
#   define __ASSERT_FUNCTION    __PRETTY_FUNCTION__
# else
#  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#   define __ASSERT_FUNCTION    __func__
#  else
#   define __ASSERT_FUNCTION    ((__const char *) 0)
#  endif
# endif

#endif /* NDEBUG.  */

/* -- Assert.h*/


/* 下面就是源文件 */

/*  ++ Assert.c */
/* Copyright (C) 1991,1994-1996,1998,2001,2002,2005
   Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */


#include <assert.h>
#include <libintl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysdep.h>
#include <unistd.h>

/* 从外部获得的执行的文件名,包含后缀  */
extern const char *__progname;

#ifdef USE_IN_LIBIO
# include <wchar.h>
# include <libio/iolibio.h>
# define fflush(s) INTUSE(_IO_fflush) (s)
#endif

/* This function, when passed a string containing an asserted
   expression, a filename, and a line number, prints a message
   on the standard error stream of the form:
       a.c:10: foobar: Assertion `a == b' failed.
   It then aborts program execution via a call to `abort'.  */


#ifdef FATAL_PREPARE_INCLUDE
# include FATAL_PREPARE_INCLUDE
#endif

#undef __assert_fail
void
__assert_fail (const char *assertion, const char *file, unsigned int line,
           const char *function)
{
  char *buf;

#ifdef FATAL_PREPARE
  FATAL_PREPARE;
#endif
/* __asprintf 的用法可以参考vasprintf用法基本相同:
 * 其实现在Vasprintf.c中
 */

   
   
  if (__asprintf (&buf, _("%s%s%s:%u: %s%sAssertion `%s' failed.\n"),
          __progname, __progname[0] ? ": " : "",
          file, line,
          function ? function : "", function ? ": " : "",
          assertion) >= 0)
    {
      /* Print the message.  */
/* __fxprintf的用法可以参考vfprintf,用法基本相同:  */
   
      (void) __fxprintf (NULL, "%s", buf);
/* 由于输出为标准错误输出,需要及时把错误刷上去          */
      (void) fflush (stderr);
      /* We have to free the buffer since the application might catch the
     SIGABRT.  */

/*     这里为什么必须要马上把这个buffer释放掉呢?  */
      free (buf);
    }
  else
    {
      /* At least print a minimal message.  */
/*         对于这种特殊的情况,那么需要特殊处理。
 *         那么这里就涉及到STDERR_FILENO和stderr有什么区别呢?
 *         STDERR_FILENO是标准文件输出,无缓冲IO,相当于直接调用系统调用,
 *         这也就解释了为什么要用_libc_write这个函数了。
 */

      static const char errstr[] = "Unexpected error.\n";
      __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
    }
/* 为了程序终止的不同可能性,规范要求以abort来结束。
    这里使用的还是库函数,规范要求的abort个人理解应当是系统调用,那么我们在读到
    库函数abort的时候要留意一下是否有关于系统调用的实现规范。
    Abort库函数会发一个SIGABRT的异常信号,在库函数中属于环境函数
    */

  abort ();
}
hidden_def(__assert_fail)

/* -- Assert.c */



问题:

1,一般情况下宏都是要大写的,但为什么要把一些宏要做成小写呢? 难道就仅仅是为了“看起来”
像是一个函数而已么?