相关疑难解决方法(0)

C中空指针的指针算法

当一个指针到特定类型的(比如int,char,float,..)被递增,其值增加该数据类型的大小.如果void指向大小数据的指针x递增,它如何获得指向x前面的字节?编译器如何知道添加x指针的值?

c pointers void-pointers pointer-arithmetic

162
推荐指数
7
解决办法
11万
查看次数

是否增加了一个明确定义的空指针?

在执行指针算术时有很多未定义/未指定行为的示例 - 指针必须指向同一个数组(或者一个超过结尾),或者在同一个对象内,限制何时可以根据上述进行比较/操作等

以下操作定义明确吗?

int* p = 0;
p++;
Run Code Online (Sandbox Code Playgroud)

c++ pointers language-lawyer

47
推荐指数
3
解决办法
3770
查看次数

由UB递增NULL指针引起的错误示例

这段代码:

int *p = nullptr;
p++;
Run Code Online (Sandbox Code Playgroud)

导致未定义的行为,如在增加一个明确定义的空指针中讨论的那样

但在解释研究员为什么要避免UB的时候,除了说它很糟糕,因为UB意味着任何事情都可能发生,我想举一些例子证明它.我有很多他们可以访问超出限制的数组,但我找不到一个.

我甚至试过了

int testptr(int *p) {
    intptr_t ip;
    int *p2 = p + 1;
    ip = (intptr_t) p2;
    if (p == nullptr) {
        ip *= 2;
    }
    else {
        ip *= -2;
    } return (int) ip;
}
Run Code Online (Sandbox Code Playgroud)

在一个单独的编译单元中希望优化编译器会跳过测试,因为当p为null时,line int *p2 = p + 1;是UB,并且允许编译器假定代码不包含UB.

但是gcc 4.8.2(我没有可用的gcc 4.9)和clang 3.4.1都回答了正值!

有人会建议一些更聪明的代码或其他优化编译器在增加空指针时出现问题吗?

c++ undefined-behavior

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

union for uint32_t和uint8_t [4]未定义的行为?

这个答案的评论中,据说使用如下的联合将整数分割成它们的字节将是未定义的行为.在那个地方给出的代码是相似的,虽然与此不相同,请注意我是否更改了代码的未定义行为相关方面.

union addr {
 uint8_t addr8[4];
 uint32_t addr32;
};
Run Code Online (Sandbox Code Playgroud)

到目前为止,我认为这将是一个很好的做法,addr = {127, 0, 0, 1};并得到相应 uint32_t的回报.(我承认根据我的系统的字节顺序,这可能产生不同的结果.但问题仍然存在.)

这是未定义的行为吗?如果是这样,为什么?(我不知道C++中的UB是什么意思是访问非活动的联盟成员.)


C99

  • 在这一点上,C99非常接近C++ 03.

C++ 03

  • 在联合中,最多一个数据成员可以在任何时间处于活动状态,也就是说,最多一个数据成员的值可以随时存储在并集中.C++ 03,第9.5(1)节,第162页

然而

  • 如果POD-union包含几个共享一个共同初始序列的POD结构,则允许检查任何POD结构成员的公共初始序列同上.
  • 如果两个POD-struct类型具有相同数量的非静态数据成员,则它们是布局兼容的,并且相应的非静态数据成员(按顺序)具有布局兼容类型 C++ 03,第9.2(14)节,第157页
  • 如果两种类型T1和T2是相同类型,则T1和T2是布局兼容类型.C++ 03,第3.9(11)节,第53页

结论

  • as uint8_t[4]uint32_t不是同一类型(我猜,一个严格的混叠的东西)(加上两个都不是POD结构/联合)上面确实是UB?

C++ 11

  • 请注意,聚合类型不包含联合类型,因为具有联合类型的对象一次只能包含一个成员.C++ 11,脚注46,第42页

c c++ strict-aliasing unions type-punning

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