小编uh *_*per的帖子

为什么GCC不能优化`std :: sqrt`?

我有简单的程序:

#include <cmath>

int main()
{
    for (int i = 0; i < 50; ++i)
        std::sqrt(i);
}
Run Code Online (Sandbox Code Playgroud)

Clang 3.8优化了它-O3,但gcc 6.1没有.它产生以下组件:

## Annotations in comments added after the question was answered,
## for the benefit of future readers.
main:
    pushq   %rbx
    xorl    %ebx, %ebx
    jmp     .L2
.L4:
    pxor    %xmm0, %xmm0         # break cvtsi2sd's false dep on the old value of xmm0
    pxor    %xmm1, %xmm1         # xmm1 = 0.0
    cvtsi2sd        %ebx, %xmm0  # xmm0 = (double)i
    ucomisd …
Run Code Online (Sandbox Code Playgroud)

c++ optimization gcc

12
推荐指数
1
解决办法
608
查看次数

Python 3.4中的切片速度是否真的慢?

这个问题和我的回答让我想到了Python 2.7和Python 3.4之间的这种特殊区别.以简单的示例代码为例:

import timeit
import dis

c = 1000000
r = range(c)
def slow():
    for pos in range(c):
        r[pos:pos+3]

dis.dis(slow)

time = timeit.Timer(lambda: slow()).timeit(number=1)
print('%3.3f' % time)
Run Code Online (Sandbox Code Playgroud)

在Python 2.7中,我始终如一地获得0.165~Python 3.4 0.554~.反汇编之间唯一重要的区别是Python 2.7发出SLICE+3字节代码,而Python 3.4 BUILD_SLICE随后发出BINARY_SUBSCR.请注意,我已经从其他问题中消除了潜在减速的候选者,即字符串和xrangePython 3.4中不存在的事实(range无论如何,它应该与后者的类相似).

使用itertools' islice两者之间几乎完全相同的时间,所以我高度怀疑这是切片,这是造成差异的原因.

为什么会发生这种情况,是否存在指向行为变化的权威来源的链接?

编辑:为了回答答案,我已经将range对象包裹起来list,这确实给出了明显的加速.然而,当我增加迭代次数时,timeit我注意到时序差异变得越来越大.作为一个完整性检查,我替换切片与None看看会发生什么.

500次迭代timeit.

c = 1000000
r = list(range(c))
def slow():
    for pos in …
Run Code Online (Sandbox Code Playgroud)

python performance python-2.7 python-3.4

11
推荐指数
1
解决办法
350
查看次数

完全限定的静态成员变量中的歧义

在此示例代码中,有两个句子显示相同的静态变量.第一个没有歧义,但第二个没有,为什么?

#include <iostream>

using namespace std;

struct A { static const char a = 'a'; };
struct B : public A { };
struct C : public A { };
struct G : public B, public C { };

int main()
{
    G v;

    cout << G::B::A::a << endl;
    cout << v.B::A::a << endl;
}
Run Code Online (Sandbox Code Playgroud)

GCC错误(根据一些评论,clang中没有歧义):

main.cpp:15:18: error: 'A' is an ambiguous base of 'G'
  cout << v.B::A::a << endl;
Run Code Online (Sandbox Code Playgroud)

关于coliru的代码

c++ multiple-inheritance fully-qualified-naming

11
推荐指数
1
解决办法
157
查看次数

依赖范围内的功能之友

这段代码无效:

template <class T> struct A;

class C {
    template <class T> friend void A<T>::foo();
};
Run Code Online (Sandbox Code Playgroud)

在GCC 6.1.0中它说:

error: member 'void A<T>::foo()' declared as friend before type 'A<T>' defined

     template <class T> friend void A<T>::foo();
Run Code Online (Sandbox Code Playgroud)

Clang 3.8.0:

warning: dependent nested name specifier 'A<T>::' for friend class declaration 
is not supported; turning off access control for 'C' [-Wunsupported-friend]
Run Code Online (Sandbox Code Playgroud)

Visual Studio 2015崩溃:

fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'f:\dd\vctools\compiler\cxxfe\sl\p1\c\template.cpp', line 8952)
        template <class T> friend …
Run Code Online (Sandbox Code Playgroud)

c++

8
推荐指数
1
解决办法
526
查看次数

这个大小是如何计算的?

5.1.1/2表明:

关键字this指定一个指向调用非静态成员函数(9.3.2)的对象的指针,或者计算非静态数据成员的初始值设定项(9.2).

和:

与其他上下文中的对象表达式不同*this,为了成员函数体外的类成员访问(5.2.5),不需要它是完整类型.

以下代码打印8:

#include <cstddef>
#include <iostream>

struct Test
{
    std::size_t sz = sizeof(this->sz);
};

int main()
{
    std::cout << Test{}.sz;
}
Run Code Online (Sandbox Code Playgroud)

5.3.3说:

操作数是一个表达式,它是一个未评估的操作数(第5章),或带括号的type-id.的sizeof操作者不得应用于具有功能或不完整的类型的表达式...

sizeof this->sz 有相同的结果.

this->在这种情况下被视为无操作,它基本上相当于sizeof(sz)

c++

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

在std :: move(x)上执行一些操作

让我们一起办理手续.

17.3.28有效但未指明的状态[defns.valid]

除了满足对象的不变量并且对象上的操作按其类型指定的操作之外,未指定的对象状态

[ 示例:如果x类型的对象std::vector<int>处于有效但未指定的状态,x.empty()则可以无条件地调用,并且x.front()只有在x.empty()返回false时才能调用.- 结束例子 ]

一些用户认为这std::move(x).something()是荒谬的.但我无法理解之间的差异std::move(x).something()y = std::move(x); y.something().注意:

// -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
std::vector<int> v;
v.pop_back();
// Error: attempt to access an element in an empty container.
Run Code Online (Sandbox Code Playgroud)

现在我们想尝试我们荒谬的案例:

std::vector<int> v(10);
std::move(v).pop_back();
Run Code Online (Sandbox Code Playgroud)

没错.这必须是每个人都在谈论的"有效但未指明",但让我们继续前进.

std::vector<int> v(10);
std::cout << std::move(v).size();
auto v2 = std::move(v);
std::cout << v.size();
Run Code Online (Sandbox Code Playgroud)

这打印100.这并不太令人惊讶.std::move它只是一个演员,它实际上并不执行移动构造函数的工作.

我错过了什么或者std::move(x).something()仍然是非感性的(除非是无操作)?


有关参考,请参阅有关成员函数.begin()和std :: begin()的注释以及upvoted答案.

以下示例表明v不会移动:

template< class …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics

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

如何调用未在派生类中定义的基类函数?

我一直认为基类的公共方法确实被派生类继承,甚至认为派生类没有定义该特定方法.例如

#include <iostream>

using namespace std;


    class A {
    public:
        int f() { cout << 3; return 0;}
        int f(int x) {cout << x; return 0;}
    }; 

    class B: public A {
    public:
        int f() {std::cout << 5; return 0;}

    };


    int main(){
       B ob;
       ob.f(7); 

       return 0;
    }
Run Code Online (Sandbox Code Playgroud)

我期待结果是:7,但我得到编译错误说

" 错误:函数调用的参数太多,预期为0,有1;你的意思是'A :: f'吗? "

我知道错误试图说的是什么,但我很困惑,没有调用Base类的功能.

c++

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

为什么定义sizeof实现的结果?

在C99中,§6.5.3.4:

2 sizeof运算符产生其操作数的大小(以字节为单位),该操作数可以是表达式或类型的带括号的名称....

4结果的值是实现定义的,其类型(无符号整数类型)size_t<stddef.h>(和其他头文件)中定义.

在C++ 14中,§5.3.3:

1 sizeof运算符产生其操作数的对象表示中的字节数....应用于任何其他基本类型(3.9.1)的sizeof的结果是实现定义的.

唯一保证的值是sizeof(char),sizeof(unsigned char)而且sizeof(signed char)是一个.

但是,"对象表示中的字节数"对我来说似乎很不错.例如,在C99§6.2.6.1中:

4存储在任何其他对象类型的非位字段对象中的值由n × CHAR_BIT位组成,其中n是该类型对象的大小(以字节为单位)....

那么为什么它是实现定义的,如果看起来很明确?


你们当中许多人似乎误解了我的问题.我从未声称:

A)类型的大小在所有系统上定义或相同,

B)实现定义意味着它可以返回"随机值"

我在这里得到的n * CHAR_BITS是一个固定的公式.公式本身不能在实现之间改变.是的,一个int可能是4个字节或8个字节.我明白了.但是在所有实现之间,值必须n * CHAR_BITS.

c c++ sizeof

-6
推荐指数
2
解决办法
547
查看次数