相关疑难解决方法(0)

为什么代码会通过空指针显式调用静态方法?

我在几个旧项目中看到过这样的代码:

class Class {
    static void Method() {}
};

((Class*)0)->Method();
Run Code Online (Sandbox Code Playgroud)

此代码包含未定义的行为,因为它包括取消引用空指针(无论之后发生什么).这真的没有意义 - 演员是在那里将类型名称提供给编译器,并且编写上面代码的人可以写这个:

Class::Method();
Run Code Online (Sandbox Code Playgroud)

而后者也没关系.

为什么有人会写前代码?它是来自一些美好时光的已知成语还是什么?

c++ pointers static-members undefined-behavior dereference

57
推荐指数
1
解决办法
3033
查看次数

c ++使用空指针访问静态成员

最近尝试了以下程序,它编译,运行正常并产生预期的输出,而不是任何运行时错误.

#include <iostream>
class demo
{
    public:
        static void fun()
        {
            std::cout<<"fun() is called\n";
        }
        static int a;
};
int demo::a=9;
int main()
{
    demo* d=nullptr;
    d->fun();
    std::cout<<d->a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果未初始化的指针用于访问类和/或结构成员,则行为未定义,但为什么允许使用空指针访问静态成员.我的计划有什么危害吗?

c++ static-members nullptr language-lawyer c++11

22
推荐指数
1
解决办法
3618
查看次数

通过无效指针访问静态成员:保证"工作"?

建立

给定此用户定义的类型:

struct T
{
    static int x;
    int y;

    T() : y(38);
};
Run Code Online (Sandbox Code Playgroud)

并在某处有用的必要定义:

int T::x = 42;
Run Code Online (Sandbox Code Playgroud)

以下是将标准int值传递给stdout的规范方法:

std::cout << T::x;
Run Code Online (Sandbox Code Playgroud)

控制

同时,由于T不存在的实例,以下(当然)无效:

T* ptr = NULL; // same if left uninitialised
std::cout << ptr->y;
Run Code Online (Sandbox Code Playgroud)

现在考虑以下代码的可怕和邪恶和坏:

T* ptr = NULL;
std::cout << ptr->x; // remember, x is static
Run Code Online (Sandbox Code Playgroud)

ptr如上所述,取消引用无效.即使这里没有物理内存解除引用,我相信它仍然算作一个,使上面的代码UB.或者......是吗?

14882:2003 5.2.5/3明确表示a->b转换为(*(a)).b,并且:

评估点或箭头之前的后缀表达式; 即使结果不必确定整个后缀表达式的值,也会发生此评估,例如,如果id-expression表示静态成员.

但目前尚不清楚这里的"评估"是否涉及实际的解除引用.实际上,14882:2003和n3035似乎都没有明确地说明指针表达式在处理静态成员时是否必须求值为指向有效实例的指针.

我的问题是,这有多么无效?它是否真的被标准特别禁止(即使没有物理解除引用),或者它只是我们可以逃脱的语言的怪癖?即使它被禁止,我们还期望GCC/MSVC/Clang在多大程度上安全地对待它?

我的g ++ 4.4似乎生成的代码永远不会尝试将[invalid] this指针推入堆栈,并关闭优化.

BTW如果T是多态的,那么这不会影响这一点,因为静态成员不能是虚拟的.

c++

9
推荐指数
1
解决办法
862
查看次数

函数调用返回null对象时返回的布尔值

在C++中对空对象进行fucntion调用时返回的布尔值是多少?

ClassDummy* dummy = NULL;
if (!dummy->dummy_function(1,2,3)) {
  // Do Something
}
Run Code Online (Sandbox Code Playgroud)

根据C++ 11标准,这不应该返回错误吗?

c++ c++11

5
推荐指数
2
解决办法
284
查看次数

给定一个指向C++对象的指针,调用静态成员函数的首选方法是什么?

说我有:

class A {
public:
    static void DoStuff();

    // ... more methods here ...
};
Run Code Online (Sandbox Code Playgroud)

后来我有一个想要调用DoStuff的函数:

B::SomeFunction(A* a_ptr) {
Run Code Online (Sandbox Code Playgroud)

是否更好地说:

    a_ptr->DoStuff();
}
Run Code Online (Sandbox Code Playgroud)

或者更好,即使我有一个实例指针:

    A::DoStuff()
}
Run Code Online (Sandbox Code Playgroud)

这纯粹是一种风格问题,但在做出决定之前,我想得到一些明智的意见.

c++ static coding-style

4
推荐指数
3
解决办法
1531
查看次数

通过统一指针UB访问静态类成员吗?

问题的后续问题

我们有以下代码:

#include <iostream>

struct A 
{
    static int n;
};

int A::n = 5;

int main() 
{
    A* a; //uninitialized on purpose
    std::cout << a->n; //UB?
}
Run Code Online (Sandbox Code Playgroud)

这样的访问是否为未定义行为?一方面,不需要对象来访问静态类成员,另一方面,operator->在未初始化的指针正在请求麻烦的情况下。

注意:GCC和MSVC会在没有任何警告的情况下编译此代码,Clang抱怨未初始化的用法。https://godbolt.org/z/Gy5fR2

c++ static undefined-behavior language-lawyer

2
推荐指数
1
解决办法
73
查看次数

这是C++中的未定义行为从悬空指针调用函数

这里出现了一个问题,当一个指针变得晃来晃去时,问"为什么这个工作".答案是它是UB,这意味着它可能起作用.

我在一个教程中学到了:

#include <iostream>

struct Foo
{
    int member;
    void function() { std::cout << "hello";}

};

int main()
{
    Foo* fooObj = nullptr;
    fooObj->member = 5; // This will cause a read access violation but...
    fooObj->function(); // Because this doesn't refer to any memory specific to
                        // the Foo object, and doesn't touch any of its members
                        // It will work.
}
Run Code Online (Sandbox Code Playgroud)

这相当于:

static void function(Foo* fooObj) // Foo* essentially being the "this" pointer
{
    std::cout << "Hello";
    // Foo …
Run Code Online (Sandbox Code Playgroud)

c++ pointers undefined-behavior dangling-pointer

1
推荐指数
1
解决办法
182
查看次数