相关疑难解决方法(0)

究竟什么是"假设"规则?

正如标题所说,

究竟什么是"假设"规则?

一个典型的答案是:

允许任何和所有代码转换不会改变程序的可观察行为的规则

我们会不时地从某些实现中获取行为,这些行为归因于此规则.好多次错了.那么,这个规则究竟是什么呢.标准没有明确地将此规则作为一个部分或段落提及,那么究竟什么属于这条规则的范围?对我来说,这似乎是一个灰色区域,标准没有详细定义.有人可以根据标准的参考资料详细说明细节.

注意:将其标记为C和C++,因为它与两种语言都相关.

c c++ optimization c++-faq as-if

83
推荐指数
2
解决办法
7359
查看次数

编译器优化未使用字符串的行为不一致

我很好奇为什么下面的代码:

#include <string>
int main()
{
    std::string a = "ABCDEFGHIJKLMNO";
}
Run Code Online (Sandbox Code Playgroud)

当使用编译时,将-O3产生以下代码:

main:                                   # @main
    xor     eax, eax
    ret
Run Code Online (Sandbox Code Playgroud)

(我完全理解不需要多余的,a因此编译器可以从生成的代码中完全忽略它)

但是以下程序:

#include <string>
int main()
{
    std::string a = "ABCDEFGHIJKLMNOP"; // <-- !!! One Extra P 
}
Run Code Online (Sandbox Code Playgroud)

产量:

main:                                   # @main
        push    rbx
        sub     rsp, 48
        lea     rbx, [rsp + 32]
        mov     qword ptr [rsp + 16], rbx
        mov     qword ptr [rsp + 8], 16
        lea     rdi, [rsp + 16]
        lea     rsi, [rsp + 8]
        xor …
Run Code Online (Sandbox Code Playgroud)

c++ gcc compilation clang compiler-optimization

69
推荐指数
2
解决办法
2894
查看次数

是否允许编译器优化堆内存分配?

考虑以下使用的简单代码new(我知道没有delete[],但它与此问题无关):

int main()
{
    int* mem = new int[100];

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

是否允许编译器优化new呼叫?

在我的研究中,g ++(5.2.0)和Visual Studio 2015不会优化new呼叫,而clang(3.0+)则可以.所有测试都是在启用完全优化的情况下进行的(-O3用于g ++和clang,用于Visual Studio的发布模式).

是不是new在引擎盖下进行系统调用,使编译器无法(并且非法)优化它?

编辑:我现在已经从程序中排除了未定义的行为:

#include <new>  

int main()
{
    int* mem = new (std::nothrow) int[100];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

clang 3.0不再优化它,但后来的版本确实如此.

编辑2:

#include <new>  

int main()
{
    int* mem = new (std::nothrow) int[1000];

    if (mem != 0)
      return 1;

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

clang总是返回1.

c++ optimization gcc clang language-lawyer

66
推荐指数
4
解决办法
4867
查看次数

与编译时未解析的字符串文字进行比较

我最近发现了类似于以下几行的内容:

#include <string>

// test if the extension is either .bar or .foo
bool test_extension(const std::string& ext) {
    return ext == ".bar" || ".foo";
    // it obviously should be
    // return ext == ".bar" || ext == ".foo";
}
Run Code Online (Sandbox Code Playgroud)

该功能显然没有按照评论的建议去做。但这不是重点。请注意,这不是Can you use 2 or more OR conditions in an if statement? 因为我完全知道您将如何正确编写函数!


我开始想知道编译器会如何处理这个片段。我的第一个直觉是这将被编译为return true;基本上。将示例插入到Godbolt 中,表明 GCC 9.2 和 clang 9 都没有通过优化进行这种优化-O2

但是,将代码更改为1

#include <string>

using namespace std::string_literals;

bool test_extension(const std::string& ext) { …
Run Code Online (Sandbox Code Playgroud)

c++ string compiler-optimization c++14

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