我知道C和C++标准没有规定数字的特定表示(可以是二进制补码,符号和数量等).但我不清楚这些标准(并且无法确定是否已经说明)知道在使用位时是否存在任何特定的限制/保证/保留表示.尤其:
x,我想检查变量y以查看它是否是第5位是1,我想知道是否if (x & y)可行(因为据我所知,这取决于表示的值而不是该位是否实际上是1或0))char c所有位置为真(设置为c = c | ~c)并c = c << (CHAR_BIT - 1)设置高位和c = c ^ (c << 1)低位更简单的方法,假设我没有做任何假设,我不应该这样,给出这些问题)我想我的整体问题是:C和C++标准是否有关于位和整数的限制/保证/保留表示,尽管事实上没有强制表示整数的表示(如果C和C++标准在这方面有所不同) ,他们的区别是什么?)
我在完成作业时提出了这些问题,这需要我做一些操作(注意这些不是我作业的问题,这些都是"抽象的").
编辑:至于我称之为"位",我的意思是"值形成"位而不包括"填充"位.
在他的Blog Herb Sutter写道
[...]因为增加智能指针引用计数 通常可以优化为与优化
shared_ptr实现中的普通增量相同- 在生成的代码中只是普通的增量指令,而不是围栏.然而,减量必须是原子减量或等效物,它产生特殊的处理器存储器指令,这些指令本身更昂贵,并且最重要的是在优化周围代码时引起存储器栅栏限制.
该文是关于执行的shared_ptr,我不确定他的评论是否只适用于此或通常是这样.从他的表述我收集它一般.
但是当我想到它时,我只能想到"更加昂贵的减量",当if(counter==0)紧接着 - 这可能就是这种情况shared_ptr.
因此,我想知道原子操作++counter是否(通常)总是快于--counter,或者只是因为它if(--counter==0)...与shared_ptr?一起使用?
请考虑以下代码:
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提升到unsigned(-1)那时是真的吗unsigned(-1) > sizeof(int)?-1 > sizeof(int)相当于-1 > size_t(4)如果的sizeof(int)的是4,如果是这样的话,为什么-1 > size_t(4)是假的?这个C++标准是否合适?
我试图理解书中有效的c ++语句.以下是多继承的继承图.


现在这本书说vptr需要每个类中的单独内存.它也做了以下声明
上图中的一个奇怪之处在于,即使涉及四个类,也只有三个vptrs.如果愿意,实现可以自由地生成四个vpt,但是三个就足够了(事实证明B和D可以共享一个vptr),并且大多数实现利用这个机会来减少编译器生成的开销.
我看不出有什么理由为什么每个类都要求为vptr提供单独的内存.我理解vptr是从基类继承的,可能是继承类型.如果我们假设它显示了带有继承的vptr的结果内存结构,那么它们如何才能生成该语句
B和D可以共享vptr
有人可以在多重继承中澄清一下vptr吗?
在回答了一些问题之后,我今天构建了这个实验
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)
bfalse在true通过动态初始化将其设置为有值之前(由初始化为零).如果临时在b完成初始化之前被销毁,我们将打印false,否则true.
该规范说明临时在完整表达结束时被销毁.这似乎没有与初始化一起订购b.所以我想知道
false和true不同的运行?false用于上述的Clang打印,而GCC打印true.这让我很困惑.我是否错过了定义订单的规范文本?
c++ initialization language-lawyer temporary-objects order-of-execution
假设您有以下定义:
struct X
{
char a, b;
};
X x;
Run Code Online (Sandbox Code Playgroud)
现在假设您有两个线程,其中一个读取和写入x.a但从不访问,x.b而另一个读取和写入x.b但从不访问x.a.两个线程都不使用任何锁或其他同步原语.这可以保证在C++ 11中有效吗?或者它是否算作访问同一个对象,因此需要锁定?
我试图准确理解线程安全的原子引用计数是如何工作的,例如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.
0.1.delete托管对象指针.1,访问托管对象指针... …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::cur或off != 0,并且如果最后一个操作是输出,则更新输出序列并写入任何非移位序列。接下来,寻找新的位置:如果width > 0,调用fseek(file, width * off, …
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) 考虑这个代码:
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] 。