C++ sizeof运算符宏#define MYSIZEOF(X)((X*)0+;1) #包括 #定义MYSIZEOF(X)((X*)0+1) int main() { printf(“%ld”,MYSIZEOF(int)); 返回0; }

C++ sizeof运算符宏#define MYSIZEOF(X)((X*)0+;1) #包括 #定义MYSIZEOF(X)((X*)0+1) int main() { printf(“%ld”,MYSIZEOF(int)); 返回0; },c++,c,C++,C,有人能解释一下它是如何工作的吗? 提前感谢这里的想法很简单:对类型T指针的算术是以sizeof(T)的倍数执行的,因此((X*)0+1)有望成为指向内存中地址sizeof(X)字节的指针 不幸的是,行为未定义为(X*)0会创建一个空指针,编译器可能会将一些非零值替换为它编译的系统上的哨兵。此外,代码假定%ld是指针的正确格式,但可能不是%p如果printf实现支持它,那么它将是一种改进 当然,不直接使用sizeof操作符是愚蠢的……这里的想法很简单:对类型T的指针执行的算术是sizeof(T)的

有人能解释一下它是如何工作的吗?
提前感谢这里的想法很简单:对类型
T
指针的算术是以
sizeof(T)
的倍数执行的,因此
((X*)0+1)
有望成为指向内存中地址
sizeof(X)
字节的指针

不幸的是,行为未定义为
(X*)0
会创建一个空指针,编译器可能会将一些非零值替换为它编译的系统上的哨兵。此外,代码假定
%ld
是指针的正确格式,但可能不是<代码>%p如果
printf
实现支持它,那么它将是一种改进


当然,不直接使用
sizeof
操作符是愚蠢的……

这里的想法很简单:对类型
T
的指针执行的算术是
sizeof(T)
的倍数,因此
((X*)0+1)
有望成为指向内存中地址
sizeof(X)
字节的指针

不幸的是,行为未定义为
(X*)0
会创建一个空指针,编译器可能会将一些非零值替换为它编译的系统上的哨兵。此外,代码假定
%ld
是指针的正确格式,但可能不是<代码>%p如果
printf
实现支持它,那么它将是一种改进


当然,不直接使用
sizeof
运算符是愚蠢的……

@ChrisBeck unrelated(这是查找数组的大小,其中该代码查找指向隐式单元素数组(在C++中有效)的PTE“迭代器”的指针,但它尝试解释结果地址的整数值…?)@是的,我现在意识到,实际上那里没有任何“尺寸”。。。我想是时候睡觉了:为什么投票会被否决?@MichaelWalz人们倾向于不喜欢/双重标签,而看到“(X*)0”表明这是不必要的与UB调情。另外,“这段代码做什么”基本上是“亲爱的懒网”,可能会引发一些人。这个问题没什么好谈的,老实说(我没有投反对票),我不认为这是一个合适的重复。副本仅涵盖与此相关的一个小方面question@ChrisBeck无关(即查找数组的大小,其中此代码查找隐式单元素数组(在C++中有效)的PTE“迭代器”指针,但它尝试解释结果地址的整数值…?)@是的,我现在意识到,实际上那里没有任何“尺寸”。。。我想是时候睡觉了:为什么投票会被否决?@MichaelWalz人们倾向于不喜欢/双重标签,而看到“(X*)0”表明这是不必要的与UB调情。另外,“这段代码做什么”基本上是“亲爱的懒网”,可能会引发一些人。这个问题没什么好谈的,老实说(我没有投反对票),我不认为这是一个合适的重复。副本只涉及与此问题相关的一个小方面,因此,指针的整数值可能不适合直接解释。相反,它可以再次与nullptr进行比较。我不认为取nullptr的整数值本身就是UB(但解释它是IB)@venki是的。它只是在您的实现上添加数字。谷歌“指针算术”@sehe:“我不认为获取nullptr的整数值本身就是UB”-但加上它可能会使它跨越段边界或其他东西。。。我认为这是未定义的(您只能在特定数组中对指针算法进行推理,直到超过结束地址的数组为止)。然后,指针的整数值可能不适合直接解释。相反,它可以再次与nullptr进行比较。我不认为取nullptr的整数值本身就是UB(但解释它是IB)@venki是的。它只是在您的实现上添加数字。谷歌“指针算术”@sehe:“我不认为获取nullptr的整数值本身就是UB”-但加上它可能会使它跨越段边界或其他东西。。。我认为这是未定义的(您只能对特定数组中的指针算法进行推理,直到超过结束地址的那个数组为止)。
#include<stdio.h>
#define MYSIZEOF(X) ((X*)0 +1)
int main()
{
    printf("%ld", MYSIZEOF(int));
    return 0;
}