相关疑难解决方法(0)

在 C++ 中进行类型双关的现代正确方法是什么?

似乎有两种类型的 C++。实用C++和语言律师C++。在某些情况下,能够将一种类型的位模式解释为一种不同的类型会很有用。浮点技巧就是一个显着的例子。让我们取著名的快速平方根反比(取自Wikipedia,又取自此处):

float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;                       // evil floating point bit level hacking
    i  = 0x5f3759df - ( i >> 1 );               // what the
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) ); …
Run Code Online (Sandbox Code Playgroud)

c++ performance casting language-lawyer type-punning

35
推荐指数
2
解决办法
1315
查看次数

Pimpl成语不使用动态内存分配

我们想在项目的某些部分使用pimpl习语.项目的这些部分也恰好是禁止动态内存分配的部分,这个决定不在我们的控制范围内.

所以我要问的是,在没有动态内存分配的情况下,有没有一种干净又好的方法来实现pimpl习语?

编辑
以下是一些其他限制:嵌入式平台,标准C++ 98,没有外部库,没有模板.

c++ embedded pimpl-idiom dynamic-memory-allocation

28
推荐指数
2
解决办法
5554
查看次数

reinterpret_cast类型是否实际上是未定义的行为?

似乎广泛认为类型惩罚通过reinterpret_cast某种方式被禁止(正确地说:"未定义的行为",即" 本国际标准没有要求的行为 ",并明确指出实现可以在C++中定义行为).使用以下推理不同意我是不正确的,如果是这样,为什么


[expr.reinterpret.cast]/11州:

如果类型"指向" 的表达式可以使用a 显式转换为"指向" 的类型,则T1可以将类型的glvalue表达式强制转换为"引用T2"类型.结果引用与源glvalue相同的对象,但具有指定的类型.[注意:也就是说,对于左值,参考演员与使用内置和运算符的转换具有相同的效果(同样适用于). - 结束注释]不创建临时,不进行复制,也不调用构造函数或转换函数.T1T2reinterpret_­castreinterpret_­cast<T&>(x)*reinterpret_­cast<T*>(&x)&*reinterpret_­cast<T&&>(x)

用脚注:

75)这有时被称为类型双关语.

/ 11隐含地,通过示例,带有/ 6到/ 10的限制,但也许最常见的用法(双关语对象)在[expr.reinterpret.cast]/7中解决:

可以将对象指针显式转换为不同类型的对象指针.当v对象指针类型的prvalue 转换为对象指针类型"指向cv T"时,结果为static_­cast<cv T*>(static_­cast<cv void*>(v)).[注意:将"指向T1"的类型的prvalue转换为"指向"的类型T2(T1 and T2对象类型和对齐要求的T2位置不比那些更严格T1)并返回其原始类型会产生原始指针值. - 结束说明]

显然,目的不能转换为/从指针或引用void,如:

  1. / 7中的例子清楚地表明,static_cast在指针的情况下应该足够了,[expr.static.cast]/13[conv.ptr]/2 ; 和
  2. [转换为]引用void …

c++ casting language-lawyer reinterpret-cast type-punning

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

reinterpret_cast从对象到第一个成员

我正在看这个答案,我想知道是否使用reinterpret_cast将对象转换为第一个成员并使用结果在C++中是安全的.

假设我们有一个A类,一个B类和一个B的实例b:

class A{
public:
    int i;
    void foo(){}
};

class B{
public:
    A a;
};

B b;
Run Code Online (Sandbox Code Playgroud)

问题1:使用这样的ba是否安全:reinterpret_cast<A*>(&b)->foo()

注意:在一般情况下,我们假设类及其成员都是标准布局.

我关于reinterpret_cast的可用引用的讲座告诉我这样的用法应该被授权,因为没有别名违规,但是它与许多答案冲突,比如这个.

问题2:使用这样的ba是否安全:static_cast<A*>(static_cast<void*>(&b))->foo()

c++ type-conversion undefined-behavior reinterpret-cast c++11

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

“reinterpret_cast”真的有什么好处吗?

最近 了解到,通过 ing 其地址将 POD 重新解释为不同的 POD 是未定义行为reinterpret_castreinterpret_cast所以我只是想知道,如果它不能用于其名称所暗示的用途,那么它的潜在用例可能是什么?

c++ casting reinterpret-cast type-punning c++17

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

为什么这种类型的惩罚不是未定义的行为?

这是一个玩具示例,我认为会调用未定义的行为:

#include <cstdint>
#include <iostream>
#include <vector>

int
main()
{
    std::vector<uint16_t> foo = {0, 0x42F6};
    std::cout << *reinterpret_cast<float*>(foo.data()) << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我很确定取消引用它的结果reinterpret_cast会违反严格的别名规则.然而:

$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
$ g++ -fstrict-aliasing -Wstrict-aliasing -fsanitize=undefined -std=c++14 -o a a.cpp
$ ./a
123
Run Code Online (Sandbox Code Playgroud)

没有来自编译器或UB消毒剂的警告.为什么不?

c++ undefined-behavior type-punning

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