C++ 静态_cast能否将非空指针转换为空指针?

C++ 静态_cast能否将非空指针转换为空指针?,c++,visual-c++,pointers,static-cast,C++,Visual C++,Pointers,Static Cast,我需要为回调函数编写代码(它将从ATL中调用,但这并不重要): 第二张支票合理吗?static\u cast是否可以将非空指针转换为空指针?静态\u cast对指针所做的唯一更改是单词对齐。因此,理论上,如果myObjectVoid指向内存中的最后一个字节,那么它可能是“对齐的”“0,但我不认为这是一个实际问题。否。如果指针引用了有效对象,并且转换是有效的,那么结果也将引用有效对象,因此它不会为null。如果其中一个无效,则代码不正确,结果未定义。因此,有效用法给出null结果的唯一方法是从nu

我需要为回调函数编写代码(它将从ATL中调用,但这并不重要):


第二张支票合理吗?
static\u cast
是否可以将非空指针转换为空指针?

静态\u cast对指针所做的唯一更改是单词对齐。因此,理论上,如果myObjectVoid指向内存中的最后一个字节,那么它可能是“对齐的”“0,但我不认为这是一个实际问题。

否。如果指针引用了有效对象,并且转换是有效的,那么结果也将引用有效对象,因此它不会为null。如果其中一个无效,则代码不正确,结果未定义。因此,有效用法给出null结果的唯一方法是从null开始

在对象指针和无效指针之间转换的特定情况下,标准规定(5.2.9/10):

类型为“指向对象的指针”的值转换为“指向
void
的指针”并返回到原始指针类型将具有其原始值

而这个(4.10/3)

将“指向T的指针”转换为“指向
void的指针”
”的结果指向T类型对象所在的存储位置的起点


因此,原始和最终的对象指针将是相同的,
void
指针将为空,当且仅当对象指针为空时。

static\u cast可以更改指针值,如果在不同偏移上的对象部分之间进行转换:

class A{ int x; }; class B{ int y; };
class C : A,B {};

C *c=new C(); 

B *b=c; 
// The B part comes after the A part in C. Pointer adjusted

C *c2=static_cast<C*>(b); 
// Pointer gets adjusted back, points to the beginning of the C part
A类{intx;};B类{int y;};
C类:A,B{};
C*C=新的C();
B*B=c;
//B部分位于C中A部分之后。指针已调整
C*c2=静态铸件(b);
//指针被调整回来,指向C部分的开头
但是,“空指针值(4.10)被转换为
目的地类型。”(5.2.9-8),即如果
c
NULL
,则
b
也为
NULL
(未调整),因此
c2
设置为
NULL
。这意味着:如果静态强制转换非NULL
myObjectVoid
产生
NULL
,那么
myObjectVoid
的值是通过某种方式绕过类型系统获得的。这意味着,编译器可能会丢弃您的第二个检查,因为“无论如何它都不会发生”

不,第二次检查不合理。
static\u cast
无法将非空指针转换为空指针。在您的情况下,
static\u cast
提供的值(指针)唯一可能发生的变化是调整地址。否则,它会严格地通知编译器的其余类型分析,将表达式的结果视为目标类型。对于指针,这意味着取消引用可以在目标对象中找到正确的地址,并且递增和递减步长适合类型的大小。

为什么不直接无条件强制转换,并在强制转换后检查null?static_cast不会取消指针的引用。@Logan Capaldo:尽早检查感觉更好。如果这是可能的,这不是一个大问题吗?我一直认为0是唯一一个有效指针不能拥有的值。真正的问题是地址是向上舍入还是向下舍入,还是定义了实现?好了。在非真实场景中,传入一个精心编制的指向static_cast的指针可能会导致它被一个使其为NULL的偏移量调整。当然,这在现实生活中永远不会发生。
    if( myObjectVoid == 0 ) {
       return E_POINTER;
    }
    CMyClass* myObject = static_cast<CMyClass*>( myObjectVoid );
    if( myObject == 0 ) {
       return E_POINTER;
    }
class A{ int x; }; class B{ int y; };
class C : A,B {};

C *c=new C(); 

B *b=c; 
// The B part comes after the A part in C. Pointer adjusted

C *c2=static_cast<C*>(b); 
// Pointer gets adjusted back, points to the beginning of the C part