小编cur*_*guy的帖子

gcc:如何正确使用__attribute((__ may_alias__))以避免"derefencing type-punned pointer"警告

我有一些使用类型惩罚的代码,以避免必须调用成员"对象"的构造函数和析构函数,除非/直到实际需要使用该对象.

它工作正常,但在g ++ 4.4.3下,我得到了这个可怕的编译器警告:

jaf@jeremy-desktop:~$ g++ -O3 -Wall puns.cpp 
puns.cpp: In instantiation of ‘Lightweight<Heavyweight>’:
puns.cpp:68:   instantiated from here 
puns.cpp:12: warning: ignoring attributes applied to ‘Heavyweight’ after definition
puns.cpp: In destructor ‘Lightweight<T>::~Lightweight() [with T = Heavyweight]’:
puns.cpp:68:   instantiated from here
puns.cpp:20: warning: dereferencing type-punned pointer will break strict-aliasing rules
puns.cpp: In member function ‘void Lightweight<T>::MethodThatGetsCalledRarely() [with T = Heavyweight]’:
puns.cpp:70:   instantiated from here
puns.cpp:36: warning: dereferencing type-punned pointer will break strict-aliasing rules
Run Code Online (Sandbox Code Playgroud)

我的代码尝试使用gcc的__attribute((__ may_alias__))让gcc知道潜在的别名,但是gcc似乎并不理解我想告诉它的内容.我做错了什么,或者gcc 4.4.3只是在__may_alias__属性上遇到了一些问题?

重现编译器警告的玩具代码如下:

#include <stdio.h>
#include <memory>    // …
Run Code Online (Sandbox Code Playgroud)

c++ gcc strict-aliasing compiler-warnings type-punning

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

将指向函数的指针转换为指向函数类型的不同指针的结果

(5.2.10/6)C++ 03指向函数的指针可以显式转换为指向不同类型函数的指针.通过指向函数类型(8.3.5)的函数调用函数的效果是未定义的,该函数类型与函数定义中使用的类型不同.除了将"指向T1的指针"的rvalue转换为"指向T2的指针"类型(其中T1和T2是函数类型)并返回其原始类型产生原始指针值之外,这种指针转换的结果未指定.[注意:有关指针转换的更多详细信息,另请参见4.10.]

以下是我正在尝试做的事情,虽然很明显转换fp1为的结果fp2将产生一个原始指针,但在同一点上标准中的措辞是"The result of such a pointer conversion is unspecified"什么意思呢?

int f() { return 42; }

int main()
{
    void(*fp1)() = reinterpret_cast<void(*)()>(f);

    int(*fp2)() = reinterpret_cast<int(*)()>(fp1);

    // Safe to call the function ?
    fp2();
}
Run Code Online (Sandbox Code Playgroud)

c++ function-pointers reinterpret-cast

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

使用不确定的值初始化对象

以下是否调用未定义的行为?

int x;
int i = x;
Run Code Online (Sandbox Code Playgroud)

参考C++ 03

(4.1/1)如果左值引用的对象不是类型T的对象,并且不是从T派生的类型的对象,或者如果对象未初始化,则需要此转换的程序具有未定义的行为.

编辑: 但是,从(3.3.1/1)开始,对象可能会使用自己的不确定值进行初始化,为什么会这样?即

int x = x; //not an undefined behaviour
Run Code Online (Sandbox Code Playgroud)

c++ initialization undefined-behavior

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

C++多重继承+虚函数( - 模糊)=奇怪的行为(也是函数指针)

我正在创建一些旨在提供对回调功能的访问的接口.也就是说,继承自接口A允许类使用类型1的回调; 接口B允许类型2.继承A和B允许两种类型的回调.最终目的是A类和B类通过继承它们来处理所有脏工作.

第一个问题

这是一个小例子,应该说明我遇到的一些麻烦:

class A
{
public:
    static void AFoo( void* inst )
    {
        ((A*)inst)->ABar( );
    }
    virtual void ABar( void ) = 0;
};

class B
{
public:
    static void BFoo( void* inst )
    {
        ((B*)inst)->BBar( );
    }
    virtual void BBar( void ) = 0;
};

class C : public A, public B
{
public:
    void ABar( void ){ cout << "A"; };
    void BBar( void ){ cout << "B"; };
};
Run Code Online (Sandbox Code Playgroud)

通过拨打电话

C* c_inst …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance pointers casting static-cast

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

为什么boost :: shared_ptr使用gcc内联汇编来增加use_count而不是使用operator ++?

我正在阅读boost::shared_ptr源代码并发现它使用此函数来增加shared_ptr的使用计数(引用计数):

inline void atomic_increment( int * pw )
{
    //atomic_exchange_and_add( pw, 1 );

    __asm__
    (
        "lock\n\t"
        "incl %0":
        "=m"( *pw ): // output (%0)
        "m"( *pw ): // input (%1)
        "cc" // clobbers
    );
}
Run Code Online (Sandbox Code Playgroud)

为什么不简单地使用operator++这样做呢?这会带来更好的表现吗?

c++ boost thread-safety shared-ptr atomicity

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

为什么std :: cout不能从union打印值,但是printf有吗?

在下面的代码std::cout中不打印值,但printf确实如此.为什么是这样?

#include <iostream>
#include <cstdio>

struct bits
{
    union
    {
        unsigned char b;
        struct
        {
            unsigned char b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
        };
    };
};

const union
{
    bits b[3];
    char c[3];
} CU = { .c = { -1, 0, 1 }};


int main()
{
    std::cout << "----- chars:\n";

    std::cout << "\tstd::cout (c): " << CU.c[0]
                 << ", " << CU.c[1]
                 << ", " << CU.c[2] 
                             << "\n";

    printf("\tprintf (c): %d, %d, …
Run Code Online (Sandbox Code Playgroud)

c++ printf cout

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

公共/受保护/私有继承的麻烦

我正在尝试一个简单的C++继承示例.但我无法理解.当我尝试B从类继承的类的受保护成员时,A它表示A::baz受保护.

#include <iostream>

class A {
    public:
        int foo;
        int bar;
    protected:
        int baz;
        int buzz;
    private:
        int privfoo;
        int privbar;
};

class B : protected A {}; // protected members go to class B, right?

int main() {
    B b;

    b.baz; // here is the error [A::baz is protected]
}
Run Code Online (Sandbox Code Playgroud)

我似乎无法找到我做错的事.我试图改变class B : protected A: public A,但它仍然无法正常工作.

c++ inheritance protected private-members

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

放宽原子规则的(轻微)区别是什么?

在看到 Herb Sutters关于“原子武器”的精彩演讲后,我对放松原子的例子感到有些困惑。

我认为C++ 内存模型(SC-DRF = Sequentially Consistent for Data Race Free)中的原子在加载/读取时执行“获取”。

我知道对于负载 [和存储] 是默认值std::memory_order_seq_cst,因此两者是相同的:

myatomic.load();                          // (1)
myatomic.load(std::memory_order_seq_cst); // (2)
Run Code Online (Sandbox Code Playgroud)

到目前为止一切都很好,没有涉及放松的原子(在听完演讲后,我永远不会使用放松的原子。永远。承诺。但当有人问我时,我可能不得不解释......)。

但是为什么我使用时它是“宽松”的语义

myatomic.load(std::memory_order_acquire);   // (3)
Run Code Online (Sandbox Code Playgroud)

既然负载获取不是释放,为什么这与(1)和不同(2)究竟在这里放松?

我唯一能想到的就是我误解了load意味着acquire。如果这是真的,并且默认值seq_cst意味着两者,那不就意味着一个完整的围栏 - 没有任何东西可以传递该指令,也不能传递?我一定误解了那部分。

[并且对称地用于存储释放]。

c++ memory-model memory-barriers stdatomic relaxed-atomics

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

shared_from_this可以在没有enable_shared_from_this的情况下实现吗?

使用enabled_shared_from_this时似乎有一些边缘情况.例如:

提升shared_from_this和多重继承

可以在不需要enable_shared_from_this的情况下实现shared_from_this吗?如果是这样,它可以快速制作吗?

c++ multiple-inheritance shared-ptr weak-ptr enable-shared-from-this

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

是否可以覆盖特定父级的虚函数?

假设您有以下类层次结构:

class A
{
   public:
   virtual void foo() {}
}

class B
{
   public:
   virtual void foo() {}
}

class C: public A, public B
{
    public:
    virtual void foo() override {  } // This overrides both
}

class D: public A, public B
{
    public:
    // Is there syntax so that there is a separate override for each?
    // Maybe something like:
    // virtual void A::foo() override {}
    // virtual void B::foo() override {}
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在D类上有两个foo函数,这样如果D作为对A的引用传递,则调用D中的一个函数,如果D作为对B的引用传递,则D中的不同函数是叫什么名字?

用例是如果你从两个外部库继承,它们碰巧有重叠的函数说明符?

c++ overriding virtual-functions multiple-inheritance

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