相关疑难解决方法(0)

何时在null实例上调用成员函数会导致未定义的行为?

请考虑以下代码:

#include <iostream>

struct foo
{
    // (a):
    void bar() { std::cout << "gman was here" << std::endl; }

    // (b):
    void baz() { x = 5; }

    int x;
};

int main()
{
    foo* f = 0;

    f->bar(); // (a)
    f->baz(); // (b)
}
Run Code Online (Sandbox Code Playgroud)

我们期望(b)崩溃,因为x空指针没有相应的成员.在实践中,(a)不会崩溃,因为this从不使用指针.

因为(b)取消引用this指针((*this).x = 5;),并且this为null,程序进入未定义的行为,因为取消引用null总是被称为未定义的行为.

(a)导致未定义的行为吗?如果两个函数(和x)都是静态的呢?

c++ standards-compliance null-pointer undefined-behavior language-lawyer

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

C++静态成员方法调用类实例

这是一个小测试程序:

#include <iostream>

class Test
{
public:
    static void DoCrash(){ std::cout<< "TEST IT!"<< std::endl; }
};

int main()
{
    Test k;
    k.DoCrash(); // calling a static method like a member method...

    std::system("pause");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在VS2008 + SP1(vc9)上编译很好:控制台只显示"TEST IT!".

据我所知,不应该在instanced对象上调用静态成员方法.

  1. 我错了吗?从标准角度来看,这段代码是否正确?
  2. 如果它是正确的,那为什么?我找不到为什么会被允许,或者可能是为了帮助在模板中使用"静态或非"方法?

c++ standards visual-c++

38
推荐指数
2
解决办法
6万
查看次数

复制空对象是否涉及访问它

灵感来自这个问题.

struct E {};
E e;
E f(e);  // Accesses e?
Run Code Online (Sandbox Code Playgroud)

访问

读取或修改对象的值

空类具有隐式定义的复制构造函数

非联合类的隐式定义的复制/移动构造函数X执行其基础和成员的成员复制/移动.[...]初始化顺序与用户定义构造函数中基数和成员的初始化顺序相同.让我们x为构造函数的任何参数,或者对于移动构造函数,x值指的是参数.以适合其类型的方式复制/移动每个基本或非静态数据成员:

  • [...]基础或成员使用相应的基础或成员进行直接初始化x.

c++ language-lawyer

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

C++静态const通过NULL指针访问

class Foo {
public:
 static const int kType = 42;
};

void Func() {
 Foo *bar = NULL;
 int x = bar->kType;
 putc(x, stderr);
}
Run Code Online (Sandbox Code Playgroud)

这是定义的行为吗?我阅读了C++标准但是找不到任何关于访问静态const值的内容......我已经检查了GCC 4.2,Clang ++和Visual Studio 2010生成的程序集,并且它们都没有执行NULL的解引用指针,但我想确定.

c++ static pointers

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

为什么在使用静态方法时取消引用 nullptr 而不是 C++ 中的未定义行为?

我正在阅读一篇关于nullptrC++ 中一些特性的文章,一个特定的例子在我的理解中引起了一些混乱。

考虑(来自上述帖子的简化示例):

struct A {   
    void non_static_mem_fn() {}  
    static void static_mem_fn() {}  
};


A* p{nullptr};

/*1*/ *p;
/*6*/ p->non_static_mem_fn();
/*7*/ p->static_mem_fn();
Run Code Online (Sandbox Code Playgroud)

根据作者的说法/*1*/,取消引用 the 的表达式nullptr本身不会导致未定义的行为。与/*7*/使用nullptr-object 调用静态函数的表达式相同。

理由基于C++ Standard Core Language Closed Issues, Revision 100中的issue 315

... *pis not an error when pis null 除非左值被转换为右值(7.1 [conv.lval]),它不在这里。

从而区分/*6*//*7*/

因此,对实际的间接引用nullptr 不是未定义行为在SO答案在C ++标准的问题232讨论,...)。因此,/*1*/在这个假设下, 的有效性是可以理解的。

但是,如何 …

c++ static-methods null-pointer undefined-behavior language-lawyer

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

取消引用null并不总是UB?

我一直都知道标准规定解除引用null是UB 的事实.然而,

(链接1)

p = 0;*P; 本质上不是一个错误.

并提供链接

(链接2)

当p为null时,*p不是错误,除非将左值转换为左值

(我认为这是一个错字,可能应该读取左值转换为右值)

Link 1也说

char*p = 0; char*q =&*(p)

是"未定义",我只能阅读定义明确或至少是实现定义

语言律师可以提供有关正在发生的事情的权威解释吗?

c++ undefined-behavior language-lawyer

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

C++20 中取消引用空指针 UB 吗?

&((T*)NULL)->member我从研究“ UB 是 C 语言吗?”这个问题开始。这是我教科书中的一个例子,它介绍了offsetof.

我知道offsetof现在无法在 C++ 中实现(通过 cppreference 页面)。
但在阅读了一些 C++ CWS 问题后,我的问题有点变成“取消引用空指针 UB 吗?”。
另外,我认为他们不会无缘无故地改变C 中offsetoffrom的实现&((T*)NULL)->member,但我不知道为什么,也许是因为它是 UB?但我在C中没有找到一个术语说&((T*)NULL)->member是UB。对于C++,如果不是标准布局类型,我认为它是UB。

一开始,我以为会有一个明确指定的术语,比如“取消引用 NULL 指针是 UB”
,但是,随着我深入研究,我发现它比我想象的要复杂。
看了很多stackoverflow的文章回复,发现答案并不统一。
有些帖子说它是明确定义的,有些帖子说它是UB,有些帖子说它未指定。

对于那些说它定义明确的帖子,他们引用“ CWG issues #232 ”和“ CWG issues #315 ”作为原因,就像c++ access static Members using null pointer中的答案一样 。
对于那些说未指定的帖子,他们说标准中没有明确指定。
对于那些说这是UB的帖子,他们说这个问题还没有包含在标准中,所以它仍然是UB。此外,他们还给出了“如果为指针分配了无效值,则一元运算符的行为*未定义”的术语。

上面 stackoverflow 中的例子是:

#include <iostream>
class demo {
public:
  static void fun()
  {
    std::cout << "fun() is called\n";
  }
  static int …
Run Code Online (Sandbox Code Playgroud)

c++ undefined-behavior language-lawyer c++20

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

通过统一指针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
查看次数

通过访问被禁止的内存位置来注入内存异常

我想测试我为嵌入式系统编写的异常处理程序函数,并想编写一个测试代码来注入对禁止的内存的访问。

void Test_Mem_exception
    {
    __asm(
    "LDR R0, =0xA0100000\n\t"
    "MOV R1, 0x77777777\n\t"
    "STR R1, [R0,#0]"
);
Run Code Online (Sandbox Code Playgroud)

这是我想在 0xA010000 处写入访问内存位置的代码。不知何故,这对我来说似乎不是一个通用的测试代码。

是否有用 C 或 C++ 编写此类测试代码的标准方法。通用我的意思是一个独立于它运行的系统的内存映射的代码。

c testing embedded fault

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

如果可能,将 C++ 指针解引用到类型

class Foo {
public:
    static const int BAR = 2;
};

typedef Foo T1;
typedef Foo* T2;

int value1 = T1::BAR;  // This works.
int value2 = T2::BAR;  // This doesn't work.
Run Code Online (Sandbox Code Playgroud)

可以BAR从中提取的值T2吗?

我正在使用 c++-11。

我想这将是不好的做法,但我很好奇是否可以做到。

c++ typedef class c++11

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

这是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
查看次数