小编cur*_*guy的帖子

C和C++标准对位级整数表示和操作有何看法?

我知道C和C++标准没有规定数字的特定表示(可以是二进制补码,符号和数量等).但我不清楚这些标准(并且无法确定是否已经说明)知道在使用位时是否存在任何特定的限制/保证/保留表示.尤其:

  1. 如果整数类型中的所有位都为零,那么整数整数是否代表零?
  2. 如果整数类型中的任何位是1,那么整数整数是否表示非零?(如果这是"是",那么一些表示如符号和幅度将受到额外限制)
  3. 是否有保证的方法来检查是否有任何位未设置?
  4. 是否有保证的方法来检查是否设置了任何位?(#3和#4类型取决于#1和#2,因为我知道如何设置,例如某个变量中的第5位(参见#5)x,我想检查变量y以查看它是否是第5位是1,我想知道是否if (x & y)可行(因为据我所知,这取决于表示的值而不是该位是否实际上是1或0))
  5. 是否有保证的方法来设置最左边和/或最右边的位?(至少比将char c所有位置为真(设置为c = c | ~c)并c = c << (CHAR_BIT - 1)设置高位和c = c ^ (c << 1)低位更简单的方法,假设我没有做任何假设,我不应该这样,给出这些问题)
  6. 如果#1的答案是"否",那么如何迭代整数类型的位并检查每个位是1还是0?

我想我的整体问题是:C和C++标准是否有关于位和整数的限制/保证/保留表示,尽管事实上没有强制表示整数的表示(如果C和C++标准在这方面有所不同) ,他们的区别是什么?)

我在完成作业时提出了这些问题,这需要我做一些操作(注意这些不是我作业的问题,这些都是"抽象的").

编辑:至于我称之为"位",我的意思是"值形成"位而不包括"填充"位.

c c++ integer data-representation language-lawyer

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

原子衰减比增量更贵吗?

在他的Blog Herb Sutter写道

[...]因为增加智能指针引用计数 通常可以优化为与优化shared_ptr实现中的普通增量相同- 在生成的代码中只是普通的增量指令,而不是围栏.

然而,减量必须是原子减量或等效物,它产生特殊的处理器存储器指令,这些指令本身更昂贵,并且最重要的是在优化周围代码时引起存储器栅栏限制.

该文是关于执行的shared_ptr,我不确定他的评论是否只适用于此或通常是这样.从他的表述我收集它一般.

但是当我想到它时,我只能想到"更加昂贵的减量",当if(counter==0)紧接着 - 这可能就是这种情况shared_ptr.

因此,我想知道原子操作++counter是否(通常)总是快--counter,或者只是因为if(--counter==0)...shared_ptr?一起使用?

c++ performance atomic reference-counting memory-fences

18
推荐指数
3
解决办法
907
查看次数

为什么?1> sizeof(int)?

请考虑以下代码:

template<bool> class StaticAssert;
template<> class StaticAssert<true> {};
StaticAssert< (-1 < sizeof(int)) > xyz1; // Compile error
StaticAssert< (-1 > sizeof(int)) > xyz2; // OK
Run Code Online (Sandbox Code Playgroud)

为什么是-1 > sizeof(int)真的?

  1. -1提升到unsigned(-1)那时是真的吗unsigned(-1) > sizeof(int)
  2. 这是真的,-1 > sizeof(int)相当于-1 > size_t(4)如果的sizeof(int)的是4,如果是这样的话,为什么-1 > size_t(4)是假的?

这个C++标准是否合适?

c++ unsigned sizeof type-conversion modular

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

在多重继承中理解vptr?

我试图理解书中有效的c ++语句.以下是多继承的继承图.

在此输入图像描述

在此输入图像描述

现在这本书说vptr需要每个类中的单独内存.它也做了以下声明

上图中的一个奇怪之处在于,即使涉及四个类,也只有三个vptrs.如果愿意,实现可以自由地生成四个vpt,但是三个就足够了(事实证明B和D可以共享一个vptr),并且大多数实现利用这个机会来减少编译器生成的开销.

我看不出有什么理由为什么每个类都要求为vptr提供单独的内存.我理解vptr是从基类继承的,可能是继承类型.如果我们假设它显示了带有继承的vptr的结果内存结构,那么它们如何才能生成该语句

B和D可以共享vptr

有人可以在多重继承中澄清一下vptr吗?

  • 我们每个班级都需要单独的vptr吗?
  • 如果以上是真的,为什么B和D可以共享vptr?

c++ multiple-inheritance virtual-inheritance vtable vptr

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

什么时候初始化器暂时销毁?

在回答了一些问题之后,我今天构建了这个实验

struct A { 
  bool &b; 
  A(bool &b):b(b) { } 
  ~A() { std::cout << b; }  
  bool yield() { return true; } 
}; 

bool b = A(b).yield();

int main() { }
Run Code Online (Sandbox Code Playgroud)

bfalsetrue通过动态初始化将其设置为有值之前(由初始化为零).如果临时在b完成初始化之前被销毁,我们将打印false,否则true.

该规范说明临时在完整表达结束时被销毁.这似乎没有与初始化一起订购b.所以我想知道

  • 规范是否允许实现同时打印falsetrue不同的运行?

false用于上述的Clang打印,而GCC打印true.这让我很困惑.我是否错过了定义订单的规范文本?

c++ initialization language-lawyer temporary-objects order-of-execution

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

C++ 11内存模型并在不同的线程中访问同一结构的不同成员

假设您有以下定义:

struct X
{
  char a, b;
};

X x;
Run Code Online (Sandbox Code Playgroud)

现在假设您有两个线程,其中一个读取和写入x.a但从不访问,x.b而另一个读取和写入x.b但从不访问x.a.两个线程都不使用任何锁或其他同步原语.这可以保证在C++ 11中有效吗?或者它是否算作访问同一个对象,因此需要锁定?

c++ multithreading memory-model thread-safety c++11

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

原子参考计数

我试图准确理解线程安全的原子引用计数是如何工作的,例如std::shared_ptr.我的意思是,基本概念很简单,但我真的很担心减法加上如何delete避免竞争条件.

Boost的这个教程演示了如何使用Boost原子库(或C++ 11原子库)实现原子线程安全的引用计数系统.

#include <boost/intrusive_ptr.hpp>
#include <boost/atomic.hpp>

class X {
public:
  typedef boost::intrusive_ptr<X> pointer;
  X() : refcount_(0) {}

private:
  mutable boost::atomic<int> refcount_;
  friend void intrusive_ptr_add_ref(const X * x)
  {
    x->refcount_.fetch_add(1, boost::memory_order_relaxed);
  }
  friend void intrusive_ptr_release(const X * x)
  {
    if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
      boost::atomic_thread_fence(boost::memory_order_acquire);
      delete x;
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

好的,所以我得到了一般的想法.但我不明白为什么以下情况不可能:

说refcount是当前的1.

  1. 线程A:原子地将refcount递减为0.
  2. 线程B:原子地将refcount递增到1.
  3. 线程A:调用delete托管对象指针.
  4. 线程B:将refcount视为1,访问托管对象指针... …

c++ multithreading atomic reference-counting c++11

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

为什么 C++ 标准会按照它的方式处理文件?

C++ 使用该streamoff类型来表示(文件)流中的偏移量,并在 [stream.types] 中定义如下:

using streamoff = implementation-defined ;

类型 streamoff 是有符号基本整数类型之一的同义词,其大小足以表示操作系统的最大可能文件大小。287)

287) 通常很长很长。

这是有道理的,因为它允许在大文件中查找(而不是使用long可能只有 32 位宽的 )。

[filebuf.virtuals] 定义了basic_filebuf在文件中查找的函数,如下所示:

pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;

off_type等价于streamoff,参见 [iostreams.limits.pos]。然而,标准接着解释了函数的效果。我被最后一句话激怒了,它需要调用fseek

效果:让width表示a_codecvt.encoding()。如果is_open() == false, 或off != 0 && width <= 0,则定位操作失败。否则,如果way != basic_ios::curoff != 0,并且如果最后一个操作是输出,则更新输出序列并写入任何非移位序列。接下来,寻找新的位置:如果width > 0,调用fseek(file, width * off, …

c++ file seek language-lawyer c++20

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

Is this a bug in std::gcd?

I've come across this behavior of std::gcd that I found unexpected:

#include <iostream>
#include <numeric>

int main()
{
    int      a = -120;
    unsigned b =  10;

    //both a and b are representable in type C
    using C = std::common_type<decltype(a), decltype(b)>::type;
    C ca = std::abs(a);
    C cb = b;
    std::cout << a << ' ' << ca << '\n';
    std::cout << b << ' ' << cb << '\n';

    //first one should equal second one, but doesn't
    std::cout << std::gcd(a, b) …
Run Code Online (Sandbox Code Playgroud)

c++ unsigned libstdc++ language-lawyer c++17

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

跳过变量初始化格式错误还是会导致未定义的行为?

考虑这个代码:

void foo()
{
    goto bar;
    int x = 0;
    bar: ;
}
Run Code Online (Sandbox Code Playgroud)

GCC 和 Clang拒绝它,因为跳转到bar:绕过变量初始化。MSVC 根本不抱怨(除非使用xafterbar:导致警告)。

我们可以用 a 做类似的事情switch

void foo()
{
    switch (0)
    {
        int x = 0;
        case 0: ;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在所有三个编译器都发出错误

这些片段格式不正确吗?或者他们会导致UB?

我曾经认为两者都是格式错误的,但我找不到标准的相关部分。[stmt.goto]不说这事,而且也不[stmt.select]

c++ goto initializer variable-declaration language-lawyer

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