一篇关于intptr_t 和 uintptr_t的文章【英文的】
Last updated May 6, 2005.
The latest C standard ISO/IEC 9899 (known as C99) introduced quite a few core and library extensions that aren't supported in ISO C++ yet. The C++ standards committee is working with WG14 (the ISO C standards committee) to resolve these incompatibilities. The aim is to adopt C99 features that can be useful or necessary in C++, while rejecting features and library extensions that C+ doesn't need. Here, I present two of these C99 features: long long and intptr_t, and discuss their future in C++.
A long long Story
The C99 long long type and its unsigned counterpart aren't really needed in core C++. Since K&R days, C has always had at least one redundant integral type which is identical to at least one more integral type. In 32-bit systems, int and long are identical; in 16-bit systems, short and int were interchangeable, and so on. Therefore, it was possible to redefine long as a 64-bit integral type in 64-bit systems, while retaining int as a 32-bit integral type in 32/64-bit systems. Indeed, this is exactly what many 64-bit systems have done, including Solaris and Win64.
The main reason for introducing long long into C99 was the C99 <math.h> library. For example, take this minimal pair:
#include <math.h>
long int lrint(double x); //32-bit
long long llrint(double x);//64-bit
If you omit one long from each prototype, a 32-bit platform sees these two functions as having the same return type.
However, long long is incompatible with C++98. If you try to compile a C program that uses long long, you get a compilation error. Look at the following program:
int main()
{
long long x=0LL;
x++;
}
Using Comeau C/C++ 4.3.3, it compiles successfully in C mode. When compiled in strict C++ mode, you get a compilation error:
Line 3: error: the type "long long" is nonstandard,
Consideration: Use --long_long for this to work in strict mode
long long x=0LL;
^
The proposed recommendation to use long_long is problematic because other compilers don't recognize this token. Furthermore, if you fix the code as recommended and compile it once more as a C program, you're in trouble again:
int main()
{
long_long x=0LL; //compiled in C mode
x++;
}
"ComeauTest.c", line 3: error: identifier "long_long" is undefined
long_long x=0LL;
^
This is a serious compatibility issue, especially for programmers who use both C++ and C99. The only workaround, at present, is conditional compilation. To solve this problem, the C++ standards committee has decided to add long long as well as their corresponding LL and ULL affixes to C++.
intptr_t and uintptr_t
The C99 header <inttypes.h> declares sets of typedefs for portable integral types, such as fastest minimum-width integer types. For example:
int_fast8_t int_fast16_t int_fast32_t int_fast64_t
exact-width signed integer types such as:
int8_t int16_t int32_t int64_t
And more. In addition, this header also declares the following typedef name:
intptr_t
Any valid pointer to an object (the original C99 text speaks of "any valid pointer to void") can be converted to this type, and then converted back safely to void *. The result must compare equal to the original pointer. In other words, intptr_t legalizes a popular yet non-portable tradition of converting data pointers to integral types, and vice versa. The POSIX API defines several functions that rely on such conversions; similarly, Windows frameworks often store the this pointer as an integer. C++0x will support intptr_t, too.
The introduction of intptr_t is chiefly important in 64-bit computing. The problem is that most 64-bit systems use the LP64 model, whereby long and data pointers have the same size of 64-bits, whereas int has only 32-bits. If you want to write dually-targeted code for 32/64-bit platforms, intptr_t is guaranteed to work correctly on both.
uintptr_t is the unsigned counterpart of this typedef.
intptr_t and GC
Interestingly, intptr_t has recently drawn the standards committee's attention with reference to a standard garbage collector (GC). A typical GC keeps track of pointers in the program, ensuring that the memory to which they point is released when they are no longer referenced in the program. In simples cases such as
void f()
{
S * ptr = new S;
}//ptr's memory can now be collected
The GC can easily recognize that ptr cannot be referenced after f() returns, so it knows that the memory to which ptr points can be reclaimed. However, if you use an intptr_t variable to disguise a pointer, the GC might not recognize that the object to which ptr is bound is still referenced outside f():
void f(intptr_t & alias)
{
S * ptr = new S;
alias=(intptr_t)ptr;
}
The caller can still access the dynamically allocated object through the disguised pointer alias. The GC can't know that; after all, alias might be used as an ordinary integer, too. If the GC decides to reclaim the memory of ptr after f() returns, the caller might still access it via alias. This is just as bad as accessing an object to a pointer after deleting it. By contrast, if the GC decides to mark ptr's value as referenced (i.e., its memory shouldn't be reclaimed), this program might cause a memory leak.
That said, intptr_t is here to stay. It was introduced to permit commonplace C programming practices. C++ will have to follow suit. GC challenges notwithstanding, intptr_t is one of the smallest problems that any standard C++ GC will have to deal with.
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=223
相关推荐
C#中的IntPtr
C#中的IntPtr类型称为“平台特定的整数类型”,它们用于本机资源,如窗口句柄。 资源的大小取决于使用的硬件和操作系统,但其大小总是足以包含系统的指针(因此也可以包含资源的名称)。 例如,我们可以在vs2008中用C#做基于OpenCV的图像处理开发,下面两行代码就可以完成打开一幅图像的操作。 IntPtr img = CvInvoke.cvLoadImage(openFileDialog.FileName, Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_UNCHANGED); CvInvoke.cvShowImage("打开图片", img);
C#后台模拟键盘鼠标:PostMessage与SendInput实战指南
在Windows桌面自动化领域,模拟键盘和鼠标输入通常有两条技术路线:前台发送与后台发送。前台发送依赖SendInput,将输入事件注入系统输入流,效果与真实操作一致,但会抢占焦点;后台发送则基于Win32消息机制,通过PostMessage向指定窗口句柄直接投递WM_KEYDOWN、WM_LBUTTONDOWN等消息,无需激活窗口,真正实现“隐形操作”。理解这两种机制的差异,是设计C#上位机工具和自动化测试脚本的关键。后台模拟不干扰用户操作,特别适合控制老旧工业软件、数据采集程序或自绘界面,但需注意消息参
C语言指针的长度和类型深入分析
指针是C语言的精髓,本文就以实例的形式详细分析了C语言的长度和类型。对于初学者深入理解C语言程序设计有很好的参考价值。具体分析如下: 一般来说,如果考虑应用程序的兼容性和可移植性,指针的长度就是一个问题,在大部分现代平台上,数据指针的长度通常是一样的,与指针类型无关,尽管C标准没有规定所有类型指针的长度相同,但是通常实际情况就是这样。但是函数指针长度可能与数据指针的长度不同。 指针的长度取决于使用的机器和编译器,例如:在现代windows上,指针是32位或是64位长 测试代码如下: #include<stdio> #include<math.h> #include<stdlib> #
Nginx源代码分析.pdf
Nginx源代码分析.pdf
C语言:指针的长度和类型
如果考虑应用程序的兼容性和可移植性,指针的长度就是一个问题,在大部分现代平台上,数据指针的长度通常是一样的,与指针类型无关,尽管C标准没有规定所有类型指针的长度相同,但是通常实际情况就是这样。但是函数指针长度可能与数据指针的长度不同。


