标签: compiler-bug

?编译器错误?变量假设不变

Visual Studio 版本:17.7.1 (MSVC 19.37.32822)
使用默认设置和编译器标志新创建的项目。

最小可重现示例:

#include <cstdio>

__declspec(noinline) void test2(char** data)
{
    // After moving the pointer:
    // data_1 now points to data[1] = 1
    // data_0 now points to data[0] = 2
    *data += 1;
}

__declspec(noinline) void test(char* data_1)
{
    char* data_0 = data_1;
    test2(&data_1);
    int len = (int)(data_1 - data_0);

    if (*data_1 & 1)
    {
        if (*data_0 & 2)
            printf("good\n");
     }
}

int main()
{
    char data[2];
    data[0] = 2;
    data[1] = 1;
    test(data); …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ compiler-bug

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

接受 const char(&amp;)[N] 的函数模板是否比接受 const T&amp; 的函数模板更专业?

我定义了两个版本的函数模板,名为compare

\n
#include <cstring>\n\nusing namespace std;\n\n// fist version\ntemplate <size_t N, size_t M>\nint compare(const char (&a)[N], const char (&b)[M]) {\n    return strcmp(a, b);\n}\n\n// second version\ntemplate <typename T>\nint compare(const T &a, const T &b) {\n    if (a < b) return -1;\n    if (b < a) return 1;\n    return 0;\n}\n\nint main() {\n    const char *p1 = "dog", *p2 = "cat";\n    compare(p1, p2); // call second version\n    compare("dog", "cat"); // call second version?\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在使用c++11std的CPP Primer(第5版)一书中,作者说compare(p1, p2)将调用第二版模板,因为没有办法将指针转换为对数组的引用。将 …

c++ function-templates overload-resolution compiler-bug

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

64位指针减法,有符号整数下溢和可能的编译器错误?

我最近撕掉了我的头发调试这段代码(稍为修改以简化演示):

char *packedData;
unsigned char* indexBegin, *indexEnd;
int block, row;

// +------ bad! 
// v
  int cRow = std::upper_bound( indexBegin, indexEnd, row&255 ) - indexBegin - 1;

char value = *(packedData + (block + cRow) * bytesPerRow);
Run Code Online (Sandbox Code Playgroud)

当然,std::upper_bound在64位环境中将两个指针的差异(减去搜索到的数组的开头的结果)分配给int而不是ptrdiff_t是错误的,但是产生的特殊不良行为是非常意外的.当[indexBegin,indexEnd]的数组大小超过2GB时,我希望这会失败,所以差异溢出了一个int; 但实际发生的事情是当indexBegin和indexEnd在2 ^ 31的两侧有值时(即indexBegin = 0x7fffffe0,indexEnd = 0x80000010)崩溃.进一步的调查揭示了以下x86-64汇编代码(由MSVC++ 2005生成,带有优化):

; (inlined code of std::upper_bound, which leaves indexBegin in rbx,
; the result of upper_bound in r9, block at *(r12+0x28), and data at
; *(r12+0x40), immediately precedes this point)
movsxd    rcx, r9d …
Run Code Online (Sandbox Code Playgroud)

64-bit visual-c++ compiler-bug

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

为什么SFINAE在更改类模板专门化的位置时会搞砸?这是一个C++错误吗?

以下代码给出了预期的编译器错误(Demo):

  1 template<bool> struct Range;
  2 
  3 template<int value, typename = Range<true> > struct Unique;
  4 template<int value> struct Unique<value, Range<(value > 1)> > { typedef char type[1]; };
  5 template<int value> struct Unique<value, Range<(value > 2)> > { typedef char type[2]; };
  6 
  7 Unique<3>::type o1;
  8 Unique<3>::type o2;
Run Code Online (Sandbox Code Playgroud)

现在,如果我换掉第5行和第7行.然后没有编译器错误 !! 演示.

  5 Unique<3>::type o1;

  7 template<int value> struct Unique<value, Range<(value > 2)> > { typedef char type[2]; };
Run Code Online (Sandbox Code Playgroud)

因为o1,没有错误(value > 2) …

c++ sfinae template-specialization language-lawyer compiler-bug

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

POD零初始化

struct Line
{
    Bounds          bounds_;
    Vector          origin_;
    uint32_t        begin_; 
    uint32_t        end_;   
    dist            ascent_;
    dist            descent_;
};
Run Code Online (Sandbox Code Playgroud)

使用如下:

Line line = {};
while (!parser.done()) {
    line = Line(); // zero-initialize
    ...
}
Run Code Online (Sandbox Code Playgroud)

Bounds并且Vector是非POD类,dist是一个typedef int64_t.

但是,VC++ 11的优化32位版本构建似乎line在while循环中至少留下了未初始化的部分内容.为什么?根据Do,括号后的类型名称与new有所区别?,它应该零初始化它,对吧?

我将struct成员的值记录到文件中:

  • after Line line = {};:非POD类型默认初始化,其他类型为0.
  • 之后line = Line();:POD类型仍默认初始化,其他包含随机值.

c++ initialization pod visual-c++ compiler-bug

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

引用"自动"功能作为模板参数

这是重现问题的最小(C++ 14)代码:

template <void (&a)()>
struct Foo {
    static auto value() {}
};

void bar() {}

template struct Foo<Foo<bar>::value>;
Run Code Online (Sandbox Code Playgroud)

GNU C++ "g ++(Ubuntu 5.1.0-0ubuntu11~14.04.1)5.1.0"编译器发出:

error: could not convert template argument ‘Foo<a>::value<bar>’ to ‘void (&)()’
 template struct Foo<Foo<bar>::value>;
                                    ^
Run Code Online (Sandbox Code Playgroud)

我注意到的第一个奇怪的事情是Foo<a>::value<bar>- a没有被替换,并且value以某种方式成为模板?

以下无意义的修复增强了我的印象,这是一个编译器错误:

  • 声明value()返回void而不是推断它
  • "解除引用" value:template struct Foo<*Foo<bar>::value>;
  • 括号内容value:template struct Foo<(Foo<bar>::value)>;
  • 制作a指针:template <void (*a)()> struct Foo ...

最后,Clang编译我的片段很好.

那么,某个禁止第一个片段的地方是否有一个模糊的标准条款,或者GCC刚刚死在我身上?

c++ templates compiler-bug auto

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

Delphi XE字节数组索引

我像这样使用简单的循环缓冲区

var
  Values: array [byte] of single;
  ptr: byte;
Run Code Online (Sandbox Code Playgroud)

在这个测试例子中

for ptr:=0 to 10 do Values[Byte(ptr-5)]:=1;
Run Code Online (Sandbox Code Playgroud)

我希望设置为1前5个值和最后5个值,但XE4 compiller产生不正确的代码,它使用32位指针数学来计算数组索引:

for ptr:=0 to 10 do Values[Byte(ptr-5)]:=1;
005B94BB C645FB00         mov byte ptr [ebp-$05],$00
005B94BF 33C0             xor eax,eax
005B94C1 8A45FB           mov al,[ebp-$05]
005B94C4 C78485E0FBFFFF0000803F mov [ebp+eax*4-$0420],$3f800000
005B94CF FE45FB           inc byte ptr [ebp-$05]
005B94D2 807DFB0B         cmp byte ptr [ebp-$05],$0b
005B94D6 75E7             jnz $005b94bf
Run Code Online (Sandbox Code Playgroud)

这是我的错误代码和操作字节索引的正确方法吗?

arrays delphi indexing bytebuffer compiler-bug

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

VC++使用fp:fast导致错误(不仅仅是不准确)结果 - 这是编译器错误吗?

我安装了最新的VS2017更新(15.4.4),在编译项目时,单元测试开始失败.在使用优化(/ O2)和浮点快速模型(/ fp:fast)时,似乎在某些情况下会出现问题.以前的编译器(VS2017更新15.2)没有发生此问题.

这是一个示例程序:

#include <iostream>

const float FACTOR = 0.01745329251994329576923690768489f;

unsigned long long hoursToMicrosecs(int hours)
{
    return hours * 3600 * 1000000LL;
}

float degToRad(float deg)
{
    return deg * FACTOR;
}

float f(int u1, int u2)
{
    float percent = ((u1 - u2) / 1000.0f) / (hoursToMicrosecs(24) / 1000000.0f);
    return degToRad(percent * 360);
}

int main()
{   
    auto result = f(3600000, 35063681);
    std::cout << result << '\n';
    return (result > -3.0f) ? 0 : -1;
}
Run Code Online (Sandbox Code Playgroud)

result 应该是-2.2881,但输出实际上是-394.868,这不仅是不准确的. …

c++ floating-point visual-c++ compiler-bug visual-studio-2017

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

Clang无法从基类中找到const模板成员函数

以下C++文件:

struct Base {
    template <typename T, int = 42>
    void f(T &&) const {}
};

struct Derived: Base {
    template <typename T, typename X = typename T::asdf>
    void f(T &&) const {}

    using Base::f;
};

int main() {
    Derived const cd;
    cd.f('x');
}
Run Code Online (Sandbox Code Playgroud)

与GCC编译良好但不与Clang编译:

$ g++-7.3.0 -std=c++11 test.cpp -o test -Wall -Wextra
$ g++-7.2.0 -std=c++11 test.cpp -o test -Wall -Wextra
$ g++-6.4.0 -std=c++11 test.cpp -o test -Wall -Wextra
$ g++-5.4.0 -std=c++11 test.cpp -o test -Wall -Wextra
$ g++-4.9.4 -std=c++11 …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang compiler-bug c++11

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

有状态lambda的问题 - Microsoft编译器版本19.16.27024.1

嗨我有状态lambda表达式的问题.

这是一个虚拟的例子,但在我看来,ms编译器做错了什么,或者我有一些未定义的行为?

码:

int main() {

    auto start = [x = 1, z = 1]() mutable {
        goto resume;
        for (; ; ++z) {
            for (x = 1; x < z; ++x) {
            resume:
                std::cout << z;
                if (z > 3)
                    return 1;
            }
        }
    };

    start();
}
Run Code Online (Sandbox Code Playgroud)

Microsoft编译器版本19.16.27024.1

cl -O2/std:c ++ 17(或-O1,-Ox)----->打印'1'然后打印无限数'2'(错误我认为)

cl -Od/std:c ++ 17 ----->打印12334

g ++(Ubuntu 7.3.0-27ubuntu1~18.04)7.3.0

g ++ -03 ----->打印12334

clang version 8.0.0(trunk)clang ++ -O3 ----->打印12334

https://godbolt.org/z/wsHYA-(代码但没有std :: cout)

删除for循环后(这个带有x变量)问题不再可见; 如果somone想知道我为什么编写这样的代码 - 我想模仿协同程序等的行为(没有什么严重的,例如序列生成器)

c++ lambda compiler-bug

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