相关疑难解决方法(0)

为什么循环总是被编译成"do ... while"样式(尾部跳转)?

当试图理解汇编(启用编译器优化)时,我看到这种行为:

这样一个非常基本的循环

outside_loop;
while (condition) {
     statements;
}
Run Code Online (Sandbox Code Playgroud)

经常被编译成(伪代码)

    ; outside_loop
    jmp loop_condition    ; unconditional
loop_start:
    loop_statements
loop_condition:
    condition_check
    jmp_if_true loop_start
    ; outside_loop
Run Code Online (Sandbox Code Playgroud)

但是,如果未打开优化,则会编译为通常可理解的代码:

loop_condition:
    condition_check
    jmp_if_false loop_end
    loop_statements
    jmp loop_condition  ; unconditional
loop_end:
Run Code Online (Sandbox Code Playgroud)

根据我的理解,编译后的代码更像是这样的:

goto condition;
do {
    statements;
    condition:
}
while (condition_check);
Run Code Online (Sandbox Code Playgroud)

我看不到巨大的性能提升或代码可读性提升,为什么经常出现这种情况呢?是否有此循环样式的名称,例如"尾随条件检查"?

optimization performance assembly loops micro-optimization

26
推荐指数
1
解决办法
1675
查看次数

'if'是否有模板参数或SFINAE是首选?

首选是这样的:

template<typename T>
bool isNotZero(const T &a)
{
    if (std::is_floating_point<T>::value) return abs(a) > std::numeric_limits<T>::epsilon();
    else return a;
}
Run Code Online (Sandbox Code Playgroud)

或这个:?

template<typename T>
std::enable_if<std::is_floating_point<T>::value, bool>::type
isNotZero(const T &a) { return abs(a) > std::numeric_limits<T>::epsilon(); }

template<typename T>
std::enable_if<std::is_integral<T>::value, bool>::type
isNotZero(const T &a) { return a; }
Run Code Online (Sandbox Code Playgroud)

我通常使用第一种类型来避免许多版本的功能.

我相信它完全一样.

第一个版本在操作码阶段优化,第二个版本在模板实例化阶段优化.

c++ templates sfinae c++11

23
推荐指数
1
解决办法
1330
查看次数

禁用GCC中的所有优化选项

使用GCC编译C程序的默认优化级别是-O0.根据GCC文档关闭所有优化.例如:

    gcc -O0 test.c 
Run Code Online (Sandbox Code Playgroud)

但是,要检查-O0是否真的关闭了所有优化.我执行了这个命令:

    gcc -Q -O0 --help=optimizers 
Run Code Online (Sandbox Code Playgroud)

在这里,我有点惊讶.我启用了大约50个选项.然后,我使用以下方法检查了传递给gcc的默认参数:

    gcc -v 
Run Code Online (Sandbox Code Playgroud)

我懂了:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-       
2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --      
enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --
program-suffix=-4.8 --enable-shared --enable-linker-build-id --
libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-
gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-
sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-
time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --
with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-
cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-
java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-
jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-
directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-
gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --
with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release 
--build=x86_64-linux-gnu …
Run Code Online (Sandbox Code Playgroud)

c optimization gcc performance-testing compiler-optimization

14
推荐指数
3
解决办法
6982
查看次数

什么被认为是编译时分支?

什么是技术/ c ++语言工具 - 提供编译时分支的功能?


第一次尝试枚举它们(我期待添加更正):

  1. 重载分辨率:例如,选择"最佳"版本适合所提供的参数

    void F(X& arg);
    void F(X&& arg); 
    
    Run Code Online (Sandbox Code Playgroud)
  2. 模板特化:创建为"特殊参数"运行的代码 - 一种对模板元编程和编译时递归至关重要的技术

    template<int N> struct A    { /* implementation */ };
    template<>      struct A<0> { /* specific  code */ };
    
    Run Code Online (Sandbox Code Playgroud)
  3. SFINAE&expression sfinae:(1)的一个特例,为条件接口提供工具.

    template<class C, class F>
    auto test(C c, F f) -> decltype((c->*f)(), void()); // 'C' is pointer type
    
    Run Code Online (Sandbox Code Playgroud)

c++ templates overload-resolution template-meta-programming c++11

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

C++ 11是否支持模板类反射?

我对C++ 11模板有一点了解.我的目的是拥有一个模板函数,如下所示:

template<class T>
void function(T * a) {
  if (T belongs to class M) {
    a->function_m();
  } else {
    a->function_o();
  }
}
Run Code Online (Sandbox Code Playgroud)

C++ 11是否支持此模板类反射?

c++ c++11

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

为什么编译器在编译时无法理解if branch的值?

我正在编写一个计算多维向量元素的函数

template<class T>
int real_size(const std::vector<T>& vec)
{
    int size=0;
    for(const auto& v : vec)
    {
        if(std::is_integral<T>::value ||
                std::is_floating_point<T>::value){
            size+=1;
        }
        else{
            size +=real_size(v);
        }
    }
    return size;
}

int main()
{
    std::vector<std::vector<int>> a(10);
    a[0]=std::vector<int>(10);
    std::cout<<real_size(a);
}
Run Code Online (Sandbox Code Playgroud)

哪给我这些错误:

 error: no matching function for call to 'real_size(const int&)'
             size +=real_size(v);
                           ^
Run Code Online (Sandbox Code Playgroud)

这段代码看起来很好,错误也无关紧要...... else语句永远不会成为size +=real_size(int);因为我正在检查模板参数的类型std::is_integer.

但似乎编译器在编译时无法理解它!它是编译器错误还是我犯了错误?

*我正在使用gcc 4.8.1.g ++ -std = c ++ 11*

c++ templates c++11

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