简体   繁体   English

不同编译器中的指针大小

[英]Pointer sizes in different compilers

Let's say we're targetting one particular hardware architecture, one particular operating system (if applicable) and one particular "bitness" (32 vs. 64 etc). 假设我们的目标是一个特定的硬件架构,一个特定的操作系统(如果适用)和一个特定的“位数”(32对64等)。 In such case, is it safe to assume that different compilers will use the same sizeof(T*) for the same T ? 在这种情况下,它是安全的假设,不同的编译器将使用相同sizeof(T*)对同一T Does the standard rule on this one way or another? 标准是否适用于这种或那种方式?

Even if it's not guaranteed by the standard, would/does this hold for "most normal compilers intended for normal use and efficiency?" 即使标准没有保证,对于“用于正常使用和效率的大多数正常编译器”,它是否适用? I can imagine a theoretical Hell++ would use different sizes if allowed, but how about compilers people actually use? 我可以想象一个理论上的Hell ++会在允许的情况下使用不同的大小,但是人们实际使用的编译器呢?

I would also be interested in other types I see as closely related to pointers ( std::size_t , std::ptrdiff_t , std::intptr_t ). 我也会对我看到与指针密切相关的其他类型感兴趣( std::size_tstd::ptrdiff_tstd::intptr_t )。

As a "bonus question," can anything be said about other built-in types (eg char , int , float , long )? 作为一个“奖金问题”,可以说其他内置类型(例如charintfloatlong )吗? However, encountering different sizes across compilers wouldn't really surprise me with these. 但是,在编译器中遇到不同的大小并不会让我感到惊讶。

EDIT 编辑

One more piece to consider: would this be affected by extern "C" linkage? 还需要考虑一件事:这会受到extern "C"联动的影响吗? As an example of application, if I have a library which publishes this function: 作为应用程序的一个例子,如果我有一个发布此函数的库:

extern "C" void foo(void *);

is it theoretically possible I will not be able to call the function correctly, because the library's compiler used a different sizeof(void*) than my compiler does? 从理论上讲,我无法正确调用函数,因为库的编译器使用了与我的编译器不同的sizeof(void*)吗?

No, pointers to different data types are not required to be of the same size. 不,指向不同数据类型的指针不需要具有相同的大小。 One particular case when a pointer may not have an "expected" size is pointers to member functions. 指针可能没有“预期”大小的一个特殊情况是指向成员函数的指针。 In order to be able to support virtual functions, member function pointers are usually implemented using some sort of struct, an array of pointers, whatever. 为了能够支持虚函数,成员函数指针通常使用某种结构,指针数组等来实现。 For example, on my architecture, void * is 8 bytes long, but (Foo::*)() is 16: 例如,在我的架构上, void *是8个字节长,但是(Foo::*)()是16:

h2co3-macbook:~ h2co3$ cat quirk.cpp
#include <iostream>
#include <algorithm>

class Foo {
    public:
    void bar()
    {
        std::cout << "bar()" << std::endl;
    }
};

int main()
{
    std::cout << "sizeof void *: " << sizeof(void *) << std::endl;
    std::cout << "sizeof (Foo::*)(): " << sizeof(&Foo::bar) << std::endl;
    return 0;
}
h2co3-macbook:~ h2co3$ clang++ -Wall -o quirk quirk.cpp
h2co3-macbook:~ h2co3$ ./quirk
sizeof void *: 8
sizeof (Foo::*)(): 16

The size of other types ( int , float , etc.) will also vary widely depending on compiler, architecture, and even some compiler flags and settings. 其他类型( intfloat等)的大小也会因编译器,体系结构甚至一些编译器标志和设置而有很大差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM