标签: compiler-bug

数组引用和隐式构造函数:gcc中的错误与否?

下面的代码编译罚款与铛3.5.0,但不进行编译GCC 4.9.0(带-Wall -Wextra -pedantic-errors标志和任何的-std=c++03,-std=c++11-std=c++14标志):

struct S
{
    S(const float(&)[12])
    {
    }
};

float v[12];

S f()
{
    return v;
}

int main()
{
}
Run Code Online (Sandbox Code Playgroud)

MS VC 2013也 编译了这段代码.

哪种编译器是正确的,什么是符合标准的行为?

c++ gcc compiler-bug c++11 c++14

6
推荐指数
0
解决办法
99
查看次数

使用声明和访问修饰符的嵌套类

编译一些代码,我遇到了编译器错误,这对我来说似乎很奇怪,并且与继承,嵌套类,使用声明和访问修饰符有关.

基本上,目的是使派生类型公开基类型的嵌套受保护类.

以下简短示例来说明问题:

class Base
{
protected:

    struct Nested
    {
        enum value_enum
        {
            val = 0,
            val2,
            val3
        };
    };

};

class Derived : public Base
{
public:

    using Base::Nested;
};


int main(int argc, char** argv)
{
    //Base::Nested aa; // error, as (I) expected
    //Base::Nested::value_enum ab; // error, as (I) expected

    Derived::Nested ba; // works, as (I) expected
    Derived::Nested::value_enum bb; // MSVC error, as (I) did not expect


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

看到现场.

MSVC11(v11.00.61030)对此代码进行了阻塞,并出现以下错误:

错误C2248:'Base :: Nested':无法访问类'Base'中声明的受保护结构

GCC和Clang都正确地编译了这个,因此如果没有引用标准中相关部分的能力,我认为这是一个MSVC错误.

有没有办法解决这个与MSVC?

c++ access-modifiers nested-class compiler-bug visual-studio-2012

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

使用参数包的部分专业化的行为与手动扩展的不同

我试图理解为什么我使用两个应该与我等效的模板得到不同的行为

给定

template<template<typename...> class TT, typename T1, typename T2>
class A {};
Run Code Online (Sandbox Code Playgroud)

is_a是通用版本

template<typename T>
struct is_a : std::false_type
{
};

template<template<typename...> class TT, typename... T>
struct is_a<A<TT, T...>> : std::true_type
{
};
Run Code Online (Sandbox Code Playgroud)

is_a2是手动扩展为2种类型而不是参数包的版本

template<typename T>
struct is_a2 : std::false_type
{
};

template<template<typename...> class TT, typename T1, typename T2>
struct is_a2<A<TT, T1, T2>> : std::true_type
{
};
Run Code Online (Sandbox Code Playgroud)

我希望当 A 用 3 个参数实例化时,这 2 个版本的行为相同,但事实并非如此

参见代码编译https://wandbox.org/permlink/MjSwFLvWmH0n1QLk

我希望is_a在任何is_a2可以工作的地方工作。

这是我应该报告的编译器错误吗?

编辑

显然这适用于 clang https://wandbox.org/permlink/9n5pXUGtBa8cAvFw

c++ templates language-lawyer compiler-bug template-meta-programming

6
推荐指数
0
解决办法
111
查看次数

如果使用/ std:c ++ 17在MSVC2017 15.9.3中使用静态本地错误,lambda返回的值是多少?

下面的示例代码从lambda函数打印值,该函数简单地递增并返回静态局部计数器变量的值.

它使用gcc和clang C++ 17进行打印0,12,3预期.但是在Visual Studio Community 2017 15.9.3中没有/std:c++17设置 - 它打印0,02,3不是.

#include <iostream>

int main() {
    auto f = [] {
        static int i = 0;
        return i++;
    };
    const int v1 = f(); // Expect v1 = 0
    const int v2 = f(); // Expect v2 = 1

    // Prints the wrong values (MSVC 15.9.3 with /std:c++17)
    std::cout << v1 << "," << v2 << std::endl; // Expect "0,1", prints …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ compiler-bug c++17 visual-studio-2017

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

使用已删除或非用户提供的私有析构函数构造(但不破坏)类的对象

以下代码片段格式正确吗?

struct A { ~A() = delete; };
A *pa{new A{}};

class B { ~B() = default; };
B *pb{new B{}};
Run Code Online (Sandbox Code Playgroud)

A乍一看,B似乎从未使用过的已删除 dtor和私有显式默认 dtor从未使用过(有意的内存泄漏,如果您愿意的话),这可以说是格式良好的。

Clang 接受各种编译器和 C++ 版本(C++11 到 C++2a)的程序。

另一方面,GCC 拒绝针对各种编译器和 C++ 版本的程序。

struct A { ~A() = delete; };
A *pa{new A{}};  // GCC error: use of deleted function 'A::~A()'

class B { ~B() = default; };
B *pb{new B{}};  // GCC error: 'B::~B()' is private within this context
Run Code Online (Sandbox Code Playgroud)

(如果格式正确;在我提交错误报告之前:是否有针对此极端情况的任何开放的 GCC 错误报告?我自己搜索了 GCC:s bugzilla 无济于事。) …

c++ gcc language-lawyer compiler-bug

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

来自空大括号的模糊复制赋值的编译器差异

我一直在试图理解std::nullopt_t不允许DefaultConstructible在 C++17(引入它的地方)及更高版本中的基本原理,并在此过程中解决了一些编译器差异混淆。

考虑以下违反规范的(它是DefaultConstructible)实现nullopt_t

struct nullopt_t {
    explicit constexpr nullopt_t() = default;
};
Run Code Online (Sandbox Code Playgroud)

它是 C++11 和 C++14(无用户提供的构造函数)中的聚合,但不是 C++17(构造函数explicit)和 C++20(用户声明的构造函数)中的聚合。

现在考虑以下示例:

struct S {
    constexpr S() {}
    S(S const&) {}
    S& operator=(S const&) { return *this; }   // #1
    S& operator=(nullopt_t) { return *this; }  // #2
};

int main() {
    S s{};
    s = {};  // GCC error: ambiguous overload for 'operator=' (#1 and #2)
}
Run Code Online (Sandbox Code Playgroud)

这在 …

c++ gcc clang language-lawyer compiler-bug

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

为什么使用 -O3 的 gcc 会不必要地清除本地 ARM NEON 数组?

考虑以下代码(编译器资源管理器链接),在 gcc 和 clang 下编译并进行-O3优化:

#include <arm_neon.h>

void bug(int8_t *out, const int8_t *in) {
    for (int i = 0; i < 2; i++) {
        int8x16x4_t x;

        x.val[0] = vld1q_s8(&in[16 * i]);
        x.val[1] = x.val[2] = x.val[3] = vshrq_n_s8(x.val[0], 7);

        vst4q_s8(&out[64 * i], x);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:这是一个问题的最小可重现版本,该问题出现在我实际的、更复杂的代码的许多不同函数中,其中充满了执行与上面完全不同的操作的算术/逻辑/排列指令。请不要批评和/或建议执行上述代码的不同方法,除非它对下面讨论的代码生成问题有影响。

clang 生成正常的代码:

bug(signed char*, signed char const*):                            // @bug(signed char*, signed char const*)
        ldr     q0, [x1]
        sshr    v1.16b, v0.16b, #7
        mov     v2.16b, v1.16b
        mov     v3.16b, v1.16b
        st4     { v0.16b, …
Run Code Online (Sandbox Code Playgroud)

c gcc compiler-bug neon arm64

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

函数声明返回一种类型,实际上返回另一种类型

我几乎可以肯定以下是 Visual Studio 编译器的错误,但很难相信我决定在这里仔细检查:

struct A {
    constexpr virtual int f() { return 0; }
};

struct B : A {
    constexpr auto f() { return 1.1; }
};

constexpr int g() {
    B b;
    A & a = b;
    return a.f();
}

static_assert( g() != 1 );
static_assert( g() == 1.1 );
Run Code Online (Sandbox Code Playgroud)

g()声明为返回int类型的函数通过编译时检查g() == 1.1意味着g()实际上返回一个double值。此行为在最新的 MSVC 编译器中可以重现,在线演示: https: //gcc.godbolt.org/z/6sGET7773

由于B::f()声明不能包含auto返回类型,程序是否存在格式错误?

c++ visual-c++ compiler-bug

6
推荐指数
0
解决办法
66
查看次数

using 命名空间指令是否使名称在内联函数中可用?

考虑声明一个不受约束的ns::operator*. using namespace ns在块作用域中并调用函数之后foo<T>,clangns::operator*在读取内部基于范围的循环的迭代器时使用foo。没有其他类型ns涉及其他类型,因此 ADL 应该不会产生任何候选者。

在以下示例中,static_assert失败并显示消息:

错误:由于要求 'std::is_same_v<const int &, const custom_type &>',静态断言失败

汇编代码显示这ns::operator*是由 clang 使用的。gcc 和 msvc 的断言都通过了!

namespace ns {

template <typename T>
constexpr auto operator*(T&& /*value*/) {
    struct custom_type {};
    return custom_type{};
};

}  // namespace ns

template <typename T>
constexpr void foo() {
    std::vector<T> vec{};
    for (const auto& curr : vec) {
        static_assert(std::is_same_v<const T&, decltype(curr)>);
    }
}

int main() { …
Run Code Online (Sandbox Code Playgroud)

c++ templates namespaces using compiler-bug

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

模板内联constexpr变量的地址是否被gcc视为常量表达式?

template <typename T>
inline constexpr int a = 1;

static_assert(&a<void>, "");
Run Code Online (Sandbox Code Playgroud)

不会在gcc 9.2上进行编译,但是会在clang和msvc上进行编译。

Gcc抱怨用于的表达式static_assert不是常量表达式。

The code compiles after removing template, removing inline, or removing address-of operator.

Is this a gcc bug?

c++ gcc compiler-bug constexpr c++17

5
推荐指数
0
解决办法
48
查看次数