小编thb*_*thb的帖子

为什么new []表达式曾经调用析构函数?

根据C ++ 17标准(此处为草案),[expr.new]:

如果new表达式创建一个对象或一个类类型的对象数组,则将对分配函数,释放函数和构造函数进行访问和歧义控制。如果new表达式创建了一个类类型的对象数组,则可能会调用析构函数。

为什么要new[]调用析构函数?毕竟是新的。它不是删除。

c++ new-operator c++17

39
推荐指数
3
解决办法
1412
查看次数

原子能遭受虚假商店吗?

在C++中,原子能遭受虚假存储吗?

例如,假设mn是原子能和m = 5最初.在主题1中,

    m += 2;
Run Code Online (Sandbox Code Playgroud)

在线程2中,

    n = m;
Run Code Online (Sandbox Code Playgroud)

结果:最终值n应为5或7,对吧?但它可能是虚假的6吗?它是虚假的4或8,甚至是其他什么?

换句话说,C++内存模型是否禁止线程1表现得好像这样做?

    ++m;
    ++m;
Run Code Online (Sandbox Code Playgroud)

或者,更奇怪的是,好像它做到了这一点?

    tmp  = m;
    m    = 4;
    tmp += 2;
    m    = tmp;
Run Code Online (Sandbox Code Playgroud)

参考文献:H.-J.Boehm&SV Adve,2008,图1.(如果您点击链接,那么,在论文的第1部分中,查看第一个项目符号项:"......提供的非正式规范")

替代形式的问题

一个答案(赞赏)表明,上述问题可能会被误解.如果有帮助,那么这是另一种形式的问题.

假设程序员试图告诉线程1 跳过操作:

    bool a = false;
    if (a) m += 2;
Run Code Online (Sandbox Code Playgroud)

C++内存模型是否禁止线程1在运行时表现,就好像它这样做?

    m += 2; // speculatively alter m
    m -= 2; // oops, should not have altered! reverse the alteration
Run Code Online (Sandbox Code Playgroud)

我问,因为之前联系过的Boehm和Adve似乎解释说多线程执行可以

  • 推测性地改变变量,但随后
  • 稍后,当推测性更改变得不必要时,将变量更改回其原始值.

可编译的示例代码

如果您愿意,这里有一些您可以实际编译的代码.

#include …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading atomic memory-barriers

31
推荐指数
3
解决办法
1960
查看次数

$*和$ @之间的区别

可能重复:
bash中"$ @"和"$*"之间的区别是什么?

多年来,我曾多次在shell脚本的使用$*和犹豫之间犹豫不决$@.已经读了bash的手册页的适用部分,一遍又一遍,已经尝试都$*$@我或多或少完全无法理解两个变量之间的应用程序的实际差别.你能告诉我吗?

$*最近一直在使用,但不要问我为什么.我不知道为什么,因为我不知道为什么$@甚至存在,除了作为一个几乎完全的同义词$*.

有什么实际区别吗?

(我个人倾向于使用Bash,但对shell的选择保持不可知.就我所知,我的问题并不是Bash特有的.)

bash shell

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

现代x86硬件可以不将单个字节存储到内存中吗?

说到C++的并发内存模型,Stroustrup的C++编程语言,第4版,第1节.41.2.1,说:

...(像大多数现代硬件一样)机器无法加载或存储任何小于单词的东西.

但是,我的x86处理器,几年前,可以存储小于一个字的对象.例如:

#include <iostream>
int main()
{
    char a =  5;
    char b = 25;
    a = b;
    std::cout << int(a) << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果没有优化,GCC将其编译为:

        [...]
        movb    $5, -1(%rbp)   # a =  5, one byte
        movb    $25, -2(%rbp)  # b = 25, one byte
        movzbl  -2(%rbp), %eax # load b, one byte, not extending the sign
        movb    %al, -1(%rbp)  # a =  b, one byte
        [...]
Run Code Online (Sandbox Code Playgroud)

评论是由我提出的,但是汇编是由GCC提出的.当然,它运行良好.

显然,我不明白Stroustrup在谈到硬件可以加载和存储任何小于一个单词的内容时所说的内容.据我所知,我的计划什么也不做,但加载和存储对象小于一个字的.

C++对零成本,硬件友好的抽象的彻底关注使C++与其他易于掌握的编程语言区别开来.因此,如果Stroustrup在公交车上有一个有趣的信号心理模型,或者有其他类似的东西,那么我想了解Stroustrup的模型.

什么 Stroustrup谈论,拜托?

更长时间的背景声明 …

c++ concurrency x86 assembly memory-model

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

"原子对象"的定义

在C和C++的标准术语,短语" 原子对象 "是指" 物体原子类型, "不是吗?

没有标准会明确定义每个双字短语,因此没有错误的C和C++标准,因为省​​略了这个短语的明确定义.然而,当我读到C++ 17标准(这里的草案)时,教派.4.7.1(4),即"所有的修改以使特定原子对象中号发生在一些特定的总次序,被称为修饰顺序中号 " -和当标准反复采用类似的语言来分隔以往更精确逻辑并发-I我想确保我不会无意中误解.

我是否正确地假设短语"原子对象"的意思

  • 对象原子类型

我能想象的唯一合理的选择是这个短语的意思

  • 正确对齐的对象足够小,硬件可以原子地处理它.

请问是哪一个?

(注意:我在C和C++上都标记了这个问题,因为当涉及原子时,这两个标准使用几乎相同的语言.因此,就我所知,任何一种语言的专家都可以回答.如果由于某种原因,我是错了,那么请删除C标签并保留C++.)

参考:另见这个问题,我的问题是初步的.

c c++ atomic definition language-lawyer

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

C++ 11标准和免费提供的N3337草案之间的章节编号是否有所不同?

C++ 11标准ISO/IEC 14882:2011后来的免费下载草案 N3337之间条款,章节,小节,段落等的编号是否不同

需要明确的是:我的问题不在于是否建议使用N3337代替官方标准,因为Stackoverflow已经很好地回答了这个问题; 但只是编号不同.

作为参考,这里是我发现的最接近相关的非Stackoverflow答案(如果你按照链接,具体参考日期为"Sun Mar 18,12:06:41 PM"的项目).另外作为参考,@ Nemo将注意力集中在相关的Stackoverflow问题上.

c++ standards c++11

15
推荐指数
1
解决办法
743
查看次数

英特尔内存模型是否使SFENCE和LFENCE冗余?

英特尔内存模型保证:

  • 商店不会与其他商店重新订购
  • 载荷不会与其他载荷重新订购

http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/

我已经看到声称由于Intel内存模型,SFENCE在x86-64上是多余的,但从来没有LFENCE.上述内存模型规则是否使指令冗余?

optimization x86 assembly atomic memory-barriers

15
推荐指数
1
解决办法
1355
查看次数

在表达式left()= right()中,为什么right()首先被排序?

在C ++中,表达式left() = right()求值

  1. right()
  2. left()

按此顺序。该right()先行,如已经讨论这里。

我想不出right()先走的理由。你是否可以?我认为这是有原因的。否则,该标准几乎不会说出它的意思,而是要考虑:right()将返回一些结果。在机器代码级别上,CPU是否不需要在将结果right()返回之前就知道将结果放回何处right()

如果您碰巧知道标准委员会在想什么(因为您在房间里或已经阅读备忘录),那就太好了:我想阅读您的答案。但是,我的实际问题较为温和。我只想知道是否存在合理的原因,以及该原因可能是什么。

c++ assignment-operator c++17

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

操作员删除功能的放置形式

在他的新书TC++ PL4中, Stroustrup 对用户控制的内存分配和放置 - 或者更具体地说,关于神秘的"放置"的惯常做法 略有不同.在书的教派.11.2.4,Stroustrup写道:newdelete

delete除了可能通知垃圾收集器已删除的指针不再安全地派生之外,"placement "运算符不执行任何操作.

这意味着声音编程实践将通过调用放置delete来显式调用析构函数.

很公平.但是,没有更好的语法来调用放置而delete不是模糊

::operator delete(p);
Run Code Online (Sandbox Code Playgroud)

我问的原因是Stroustrup的教派.11.2.4没有提到这种奇怪的语法.事实上,Stroustrup没有详述此事; 他根本没有提到任何语法.我隐约不喜欢这样的外观::operator,它将命名空间解析的问题插入到与名称空间无关的内容中.不存在更优雅的语法吗?

作为参考,这里是Stroustrup在更全面的上下文中的引用:

默认情况下,operator new在免费商店中创建其对象.如果我们想要在其他地方分配对象怎么办?...我们可以通过提供带有额外参数的allocator函数将对象放在任何地方,然后在使用时提供这样的额外参数new:

void* operator new(size_t, void* p) { return p; }

void buf = reinterpret_cast<void*>(0xF00F);
X* p2 = new(buf) X;
Run Code Online (Sandbox Code Playgroud)

由于这种用法,new(buf) X提供额外参数的语法operator new()称为放置语法. 请注意,每个都operator new()将大小作为其第一个参数,并且隐式提供分配的对象的大小.在operator new()由所使用的new操作者是由通常的说法,匹配规则选择; 每个operator new()都有一个size_t作为它的第一个参数.

"放置" operator new()是最简单的这种分配器.它在标准标题中定义<new>: …

c++ placement-new

9
推荐指数
1
解决办法
848
查看次数

块作用域的 thread_local

thread_local在块范围内使用变量有什么用?

如果一个可编译的示例有助于说明问题,这里是:

#include <thread>
#include <iostream>

namespace My {
    void f(int *const p) {++*p;}
}

int main()
{
    thread_local int n {42};
    std::thread t(My::f, &n);
    t.join();
    std::cout << n << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出: 43

在示例中,新线程有自己的,n但(据我所知)不能用它做任何有趣的事情,所以为什么要麻烦呢?新线程自己的n有什么用吗?如果它没有用,那又有什么意义呢?

当然,我认为有一个点。我只是不知道这有什么意义。这就是我问的原因。

如果新线程自己n想要(如我所想)在运行时由 CPU 进行特殊处理——也许是因为,在机器代码级别,人们无法n通过从新线程的基指针的预先计算的偏移量以正常方式访问自己的线程堆栈——那我们岂不是白白浪费机器周期和电力?然而即使不需要特殊处理,仍然没有收获!不是我能看到的。

那么为什么thread_local在块范围内?

参考

c++ multithreading thread-local-storage

6
推荐指数
1
解决办法
988
查看次数