是否合法/定义良好的C ++调用不通过空指针访问成员的非静态方法? [英] Is it legal/well-defined C++ to call a non-static method that doesn't access members through a null pointer?

查看:98
本文介绍了是否合法/定义良好的C ++调用不通过空指针访问成员的非静态方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了以下代码:

I came across the following code recently:

class Foo
{
public:
    void bar();
    // .. other stuff
};

void Foo::bar()
{
    if(!this) {
        // .. do some stuff without accessing any data members
        return;
    }

    // .. do normal actions using data members
}

代码编译,因为在C ++方法只是隐式传递一个指针为'this'和'this'可以被检查为NULL就像任何其他指针的函数。显然这个代码是混乱和坏的做法,即使它不崩溃;在调试器中逐步执行代码会很容易混淆,看到一个NULL指针将要调用一个方法,然后看不到预期的崩溃。我的问题是:它违反C ++标准调用 SomeFooPtr-> bar()其中 SomeFooPtr == NULL

The code compiles because in C++ methods are just functions that are implicitly passed a pointer for 'this' and 'this' can be checked to be NULL just like any other pointer. Obviously this code is confusing and bad practice even though it doesn't crash; it would be pretty confusing to step through the code in the debugger, see a NULL pointer is about to have a method called on it and then not see the expected crash. My question is: does it violate the C++ standard to call SomeFooPtr->bar() where SomeFooPtr == NULL?

我发现它可能不是因为用户定义的operator->返回一个指针,这意味着即使该指针是NULL,它肯定没有dereferenced(dereferencing一个NULL指针,我肯定被标准视为非法或未定义)。另一方面,原始指针的语义不一定必须匹配用户定义的指针的语义 - 即使编译器不会生成一个指针,它们也可能被认为是一个取消引用。

It occurs to me that it may not because the user defined operator-> returns a pointer, which means that even if that pointer is NULL it definitely hasn't been dereferenced (dereferencing a NULL pointer I'm sure is regarded by the standard as illegal or undefined). On the other hand the semantics of raw pointers don't necessarily have to match the semantics of user defined pointers -- perhaps operator-> on them is considered a dereference even though the compiler won't generate one.

推荐答案

这可能适用于大多数系统,但它是未定义的行为。标准:

This will probably work on most systems, but it is Undefined Behaviour. Quoth the Standard:


5.2.5.3

5.2.5.3

如果 E1 具有类型指向类X的指针,则表达式 E1-> E2 被转换为等价形式(*(E1))。E2 [...]

If E1 has the type "pointer to class X," then the expression E1->E2 is converted to the equivalent form (*(E1)).E2 [...]

>

And:


5.2.5.1

5.2.5.1

后缀后跟一个点或箭头 - > ,可选后跟关键字 template (14.8。 1),然后是一个 id-expression ,是一个后缀表达式。 ...

A postfix expression followed by a dot . or an arrow ->, optionally followed by the keyword template (14.8.1), and then followed by an id-expression, is a postfix expression. The postfix expression before the dot or arrow is evaluated;58) [...]

58)这个即使结果不需要确定整个后缀表达式的值,例如如果id-expression表示静态成员,则会发生评估。

58) This evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.

评估 * x 其中 x 是空指针导致未定义行为,的UB,在功能甚至输入之前。

Evaluation of *x where x is a null pointer results in Undefined Behaviour, so yours is clearly a case of UB, before the function is even entered.

这篇关于是否合法/定义良好的C ++调用不通过空指针访问成员的非静态方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆