"William Xuuu" <william_xuuu@163.com> wrote in message
news:87oefozb8g.fsf@163.com...[color=blue]
> This's a way of defining size_t and ssize_t in Linux:
>
> //"linux/types.h"
> typedef __kernel_size_t size_t;
> typedef __kernel_ssize_t ssize_t;
>
> //"asm/posix_types.h"
> typedef unsigned int __kernel_size_t;
> typedef int __kernel_ssize_t;
>
> It seems so tricky to me. What benefits do we get from such a tricky
> typedef ? better name (size_t is shorter than unsigned int) ?[/color]
On some 64-bit platforms, 'int' and 'unsigned int' may be 32-bits,
while addresses and even memory sizes could require 64 bits
(e.g. for the size of an allocated memory block > 4GB).
On such platforms, size_t could be typedef'd to a different
type, such as 'unsigned long long'.
Note also that 'size_t' is a typedef required by the ISO C standard
(it must be available if <stddef.h> is included). However, 'ssize_t'
does not exist in the C standard -- the standard 'ptrdiff_t'
typedef is nearly equivalent.
news:87oefozb8g.fsf@163.com...[color=blue]
> This's a way of defining size_t and ssize_t in Linux:
>
> //"linux/types.h"
> typedef __kernel_size_t size_t;
> typedef __kernel_ssize_t ssize_t;
>
> //"asm/posix_types.h"
> typedef unsigned int __kernel_size_t;
> typedef int __kernel_ssize_t;
>
> It seems so tricky to me. What benefits do we get from such a tricky
> typedef ? better name (size_t is shorter than unsigned int) ?[/color]
On some 64-bit platforms, 'int' and 'unsigned int' may be 32-bits,
while addresses and even memory sizes could require 64 bits
(e.g. for the size of an allocated memory block > 4GB).
On such platforms, size_t could be typedef'd to a different
type, such as 'unsigned long long'.
Note also that 'size_t' is a typedef required by the ISO C standard
(it must be available if <stddef.h> is included). However, 'ssize_t'
does not exist in the C standard -- the standard 'ptrdiff_t'
typedef is nearly equivalent.
#
3
| |||
| |||
![]()
William Xuuu wrote:[color=blue]
> > Hi, > > This's a way of defining size_t and ssize_t in Linux: > > //"linux/types.h" > typedef __kernel_size_t size_t; > typedef __kernel_ssize_t ssize_t; > > //"asm/posix_types.h" > typedef unsigned int __kernel_size_t; > typedef int __kernel_ssize_t; > > It seems so tricky to me. What benefits do we get from such a tricky > typedef ? better name (size_t is shorter than unsigned int) ?[/color] On ssize_t I have no comment, since the C language's definition does not incorporate such a type. The size_t type is defined by ISO for use by functions such as malloc and strlen (among others, of course), for representing size information. It is required to be an unsigned integral type, but need not be unsigned int. It could equally be unsigned long or unsigned long long on some systems. It could even (perhaps a touch pathologically) be unsigned char! Consider the following code: size_t len = strlen(s); If we didn't have size_t, and wanted our code to run on the Zag, Zeg, Zig, Zog, and Zug compilers, all of which have different types to represent the size returned by strlen, we'd have to do something like: #if _ZAG unsigned char len = strlen(s); #elif _ZEG unsigned short len = strlen(s); #elif _ZIG unsigned int len = strlen(s); #elif _ZOG unsigned long len = strlen(s); #elif _ZUG unsigned long long len = strlen(s); #else #error Unsupported platform. #endif The obvious step would be to add a typedef to handle this: #if _ZAG typedef unsigned char size_type; #elif _ZEG typedef unsigned short size_type; #elif _ZIG typedef unsigned int size_type; #elif _ZOG typedef unsigned long size_type; #elif _ZUG typedef unsigned long long size_type; #else #error Unsupported platform. #endif size_type len = strlen(s); This is still a nuisance, although not such a bad nuisance, because we can hide the cpp nonsense in a header. If only we could persuade each implementor to include a standard definition for strlen's return type, and put it in, say, stddef.h. Then we wouldn't have to put all this nonsense in our own header, and our code would be simpler as a result (and easier to port). We're in luck. Fortunately, the C Standard actually /requires/ conforming implementations to do this; the name they settled on was size_t. I hope that answers your question. |
| |||
![]()
William Xuuu wrote:[color=blue]
> Hi, > > This's a way of defining size_t and ssize_t in Linux: > > //"linux/types.h" > typedef __kernel_size_t size_t; > typedef __kernel_ssize_t ssize_t; > > //"asm/posix_types.h" > typedef unsigned int __kernel_size_t; > typedef int __kernel_ssize_t; > > It seems so tricky to me. What benefits do we get from such a tricky > typedef ? better name (size_t is shorter than unsigned int) ? > > thanks. >[/color] Remember to use `size_t` as the type for indexing variables used to index into C-strings. For example, #include <stdio.h> int main () { size_t index; char * foo = "Example string."; for (index = 0; index < (size_t) 5; ++index) (void) putchar (foo[ index ]); return 0; } Just my two cents. :) Regards, Jonathan. -- "If unsigned integers look like two's complement (signed) integers, it's because two's complement integers look like unsigned integers." -Peter Nilsson |
#
5
|
![]()
Jonathan Burd wrote:[color=blue]
> > Remember to use `size_t` as the type for indexing variables > used to index into C-strings. For example, > > #include <stdio.h> > > int > main () > { > size_t index; > char * foo = "Example string.";[/color] char const *foo = "Example string."; [color=blue] > > for (index = 0; index < (size_t) 5; ++index)[/color] Obfuscatory cast. 5 will be converted to size_t anyway. Admittedly there are inferior compilers that will issue a warning for signed-unsigned comparison in the case of (index < 5). [color=blue] > (void) putchar (foo[ index ]);[/color] useless cast. Sorry, but I disagree with the philosophy of putting (void) before every unused return value. It adds volumes of useless crap to your source code and achieves almost nothing. If you want to search your code for failure to check malloc's return value then you can grep for malloc, etc. [color=blue] > > return 0; > }[/color] |
#
6
|
![]()
infobahn <infobahn@btinternet.com> writes:
[...][color=blue] > Consider the following code: > > size_t len = strlen(s); > > If we didn't have size_t, and wanted our code to run on the Zag, > Zeg, Zig, Zog, and Zug compilers, all of which have different > types to represent the size returned by strlen, we'd have to do > something like: > > #if _ZAG > unsigned char len = strlen(s); > #elif _ZEG > unsigned short len = strlen(s); > #elif _ZIG > unsigned int len = strlen(s); > #elif _ZOG > unsigned long len = strlen(s); > #elif _ZUG > unsigned long long len = strlen(s); > #else > #error Unsupported platform. > #endif[/color] Actually, if strlen() returned some unknown unsigned type, we could just use: unsigned long long len = strlen(s); and let the result be converted implicitly. (It gets slightly more complex if we need to worry about implementations that don't support long long). But of course size_t is still a useful thing to have. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst> We must do something. This is something. Therefore, we must do this. |
#
7
|
![]()
Old Wolf wrote:[color=blue]
> Jonathan Burd wrote: >[color=green] >>Remember to use `size_t` as the type for indexing variables >>used to index into C-strings. For example, >> >>#include <stdio.h> >> >>int >>main () >>{ >> size_t index; >> char * foo = "Example string.";[/color] > > > char const *foo = "Example string."; > >[color=green] >> for (index = 0; index < (size_t) 5; ++index)[/color] > > > Obfuscatory cast. 5 will be converted to size_t anyway. > Admittedly there are inferior compilers that will > issue a warning for signed-unsigned comparison in the > case of (index < 5). > > >[color=green] >> (void) putchar (foo[ index ]);[/color] > > > useless cast. Sorry, but I disagree with the philosophy > of putting (void) before every unused return value. It > adds volumes of useless crap to your source code and > achieves almost nothing. If you want to search your code > for failure to check malloc's return value then you can > grep for malloc, etc. > >[color=green] >> return 0; >>}[/color] > >[/color] Perhaps, splint should be a bit more forgiving in that case. -- "If unsigned integers look like two's complement (signed) integers, it's because two's complement integers look like unsigned integers." -Peter Nilsson |
#
8
|
![]()
infobahn <infobahn@btinternet.com> writes:
[color=blue] > On ssize_t I have no comment, since the C language's definition > does not incorporate such a type. > > The size_t type is defined by ISO for use by functions such as > malloc and strlen (among others, of course), for representing[/color] Hmm, thanks. So i.e, for portable reasons, some special functions concerning with memeory or address manipulations need size_t. [...][color=blue] > We're in luck. Fortunately, the C Standard actually /requires/ > conforming implementations to do this; the name they settled on > was size_t. > > I hope that answers your question.[/color] -- William size_t 是为了方便系统之间的移植而定义的 在32位系统上 定义为 unsigned int 在64位系统上 定义为 unsigned long 更准确地说法是 在 32位系统上是32位无符号整形 在 64位系统上是64位无符号整形 size_t一般用来表示一种计数,比如有多少东西被拷贝等 sizeof操作符的结果类型是size_t, 该类型保证能容纳实现所建立的最大对象的字节大小。 它的意义大致是“适于计量内存中可容纳的数据项目个数的无符号整数类型”。 ssize_t: 这个数据类型用来表示可以被执行读写操作的数据块的大小.它和size_t类似,但必需是signed.
|