使用指针算法计算类型大小的替代方法

Pra*_*rav 8 c c++ portability pointers casting

以下代码是100%可移植的吗?

int a=10;
size_t size_of_int = (char *)(&a+1)-(char*)(&a); // No problem here?

std::cout<<size_of_int;// or printf("%zu",size_of_int);
Run Code Online (Sandbox Code Playgroud)

PS:问题仅限于学习目的.所以请不要给出答案Use sizeof()

Nor*_*ame 13

从ANSI-ISO-IEC 14882-2003,p.87(c ++ 03):

"75)接近指针算法的另一种方法是首先将指针转换为字符指针:在此方案中,首先将转换指针中添加或减去的表达式的整数值乘以其大小.最初指向的对象,并将结果指针转换回原始类型.对于指针减法,字符指针之间的差异结果同样除以最初指向的对象的大小.

这似乎表明指针差异等于对象大小.

如果我们删除UB'ness从指针增加到标量a并将a转换为数组:

int a[1];
size_t size_of_int = (char*)(a+1) - (char*)(a);

std::cout<<size_of_int;// or printf("%zu",size_of_int);
Run Code Online (Sandbox Code Playgroud)

然后这看起来没问题.如果对齐要求始终可以被对象的大小整除,则有关对齐要求的条款与脚注一致.

更新:有趣.正如大多数人可能知道的那样,GCC允许指定类型的显式对齐作为扩展.但我无法用它破坏OP的"sizeof"方法,因为GCC拒绝编译它:

#include <stdio.h>

typedef int a8_int __attribute__((aligned(8)));

int main()
{
 a8_int v[2];

 printf("=>%d\n",((char*)&v[1]-(char*)&v[0]));
}
Run Code Online (Sandbox Code Playgroud)

信息是error: alignment of array elements is greater than element size.

  • 如果用`&a [0] + 1`或`a + 1`替换`&a [1]`,则大小为1的数组就足够了,因为指向一个数组的末尾是合法的.另外,你应该用`&a [0]`或`a`替换`&[0]`;-) (2认同)