标签: compiler-specific

为什么GHC元组限制为62?

来自Haskell 98的报告:

元组的大小没有上限,但是一些Haskell实现可能会限制元组的大小,并限制与较大元组相关联的实例.但是,每个Haskell实现必须支持最大为15的元组,以及Eq,Ord,Bounded,Read和Show的实例.(......)

然而,众所周知,GHC不支持大于62的元组.这是当我尝试在GHCi中创建大小为63的元组时发生的情况:

<interactive>:1:1: error:
    A 63-tuple is too large for GHC
      (max size is 62)
      Workaround: use nested tuples or define a data type
Run Code Online (Sandbox Code Playgroud)

我承认,这是按照哈斯克尔98规范,同时又有大小比62更大的元组很可能是高度不必要的,但我不明白到底为什么,这是因为它是在GHC.


总结一下:

  • 为什么会出现元组大小限制?
  • 为什么尺寸限制在62?

此外:

  • 为什么仅从GHC 6.12.2开始就是这种情况?
  • 其他突出的Haskell实现是否这样做?他们的理由是什么?

size haskell tuples compiler-errors compiler-specific

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

为什么这段代码会为不同的编译器生成不同的输出?

我有以下代码:

#include <iostream>
#include <vector>

struct C {
  int a;

  C() : a(0) {}
  C(int a) : a(a) {}
};

std::ostream &operator<<(std::ostream &os, const C &c) {
  os << c.a;
  return os;
}

using T = std::vector<C>;

int main() {
  auto v = T({5});

  for (const auto &a : v) {
    std::cout << a << ", ";
  }
  std::cout << std::endl;

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

如果我使用 g++,它会打印:

#include <iostream>
#include <vector>

struct C {
  int a;

  C() : a(0) {}
  C(int …
Run Code Online (Sandbox Code Playgroud)

c++ vector initializer-list compiler-specific direct-initialization

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


在C++中,为什么有些编译器拒绝将只包含double的对象放入寄存器?

在Scott Meyer的Effective C++第20节中,他指出:

一些编译器拒绝将仅包含double的对象放入寄存器中

当按值传递内置类型时,编译器会很乐意将数据放入寄存器并快速发送ints/ doubles/ floats/等.沿.但是,并非所有编译器都会以相同的宽限度处理小对象.我可以很容易地理解为什么编译器会以不同的方式处理对象 - 按值传递Object比在vtable和所有构造函数之间复制数据成员要多得多.

但仍然.对于现代编译器来说,这似乎是一个容易解决的问题:"这个类很小,也许我可以区别对待".Meyer的声明似乎暗示编译器将对仅由int(或charshort)组成的对象进行优化.

有人可以进一步了解为什么有时这种优化不会发生?

c++ compiler-specific

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

在抽象基类上使用__declspec(novtable)会以任何方式影响RTTI吗?

或者,使用__declspec(novtable)是否还有其他已知的负面影响?我似乎无法找到任何问题的参考.

c++ rtti visual-studio visual-c++ compiler-specific

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

GCC 编译器产生错误:成员函数的无效使用,而 CLang 编译器则不会

我正在使用以下程序:

\n

在main函数中,我想打印poll_timer函数的地址。

\n

该程序使用 clang 可以成功编译并运行,但使用 GCC 则不能。

\n

我在使用 GCC 时收到以下错误

\n
"709568706/source.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\n709568706/source.cpp:28:32: error: invalid use of member function \xe2\x80\x98static void MessagePoller::poll_timer()\xe2\x80\x99 (did you forget the \xe2\x80\x98()\xe2\x80\x99 ?)\n     std::cout << (void*)m_sut->poll_timer << std::endl;\n                         ~~~~~~~^~~~~~~~~~"\n
Run Code Online (Sandbox Code Playgroud)\n
#include <iostream>\n#include <memory>\n\nclass MessagePoller\n{\n  protected:\n    static void poll_timer()\n    {\n        std::cout << "Poll timer Base called\\n";\n    }\n};\n\nclass TestMessagePoller : public MessagePoller\n{\npublic:\n    using MessagePoller::poll_timer;\n\n};\ntypedef std::shared_ptr<TestMessagePoller> TestMessagePollerPtr;\n\nint main()\n{   \n    TestMessagePollerPtr m_sut;\n    m_sut = TestMessagePollerPtr(new TestMessagePoller());\n\n    std::cout << "HERE1\\n";\n    m_sut->poll_timer();\n    std::cout << (void*)m_sut->poll_timer …
Run Code Online (Sandbox Code Playgroud)

c++ gcc compiler-specific clang++

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

在此类的方法的 require 子句中使用类

这是一个简单的例子:

#include <type_traits>
#include <ranges>
#include <vector>

struct MyClass
{
    void f( int ) {}
    void f( char ) {}

    template <std::ranges::input_range Rng>
        requires requires ( MyClass cls, const std::ranges::range_value_t<Rng>& val )
        {
            { cls.f( val ) };
        }
    void f( Rng&& rng ) {}
};

int main()
{
    MyClass cls;
    cls.f( 10 );
    cls.f( 'a' );
    cls.f( std::vector<int>{ 10, 15 } );
}
Run Code Online (Sandbox Code Playgroud)

根据Godbolt 的说法,这个示例在 MSVC 和 GCC 上编译成功,但在 Clang 上编译失败。标准对此类要求表达式有何规定?

更新:我们可以简化示例,以便方法调用中不存在循环(Godbolt):

#include <type_traits> …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer compiler-specific c++-concepts c++20

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

C++ 编译器实际上符合零大小数组 SFINAE 规则吗?

大约一两年前,我读到了 C++ 中的 SFINAE 规则。他们特别指出,

以下类型错误是 SFINAE 错误:

...

尝试创建 void 数组、引用数组、函数数组、负大小数组、非整数大小数组或大小为零的数组

我决定在我的作业中使用这个规则,但是它不起作用。逐渐减少它,我得到了这个我不理解的小代码示例:

#include <iostream>

template<int I>
struct Char {};

template<int I>
using Failer = Char<I>[0];

template<int I>
void y(Failer<I> = 0) {
    std::cout << "y<" << I << ">, Failer version\n";
}

template<int I>
void y(int = 0) {
    std::cout << "y<" << I << ">, int version\n";
}

int main() {
    y<0>();
    y<1>();
    y<2>();
    y<3>();
}
Run Code Online (Sandbox Code Playgroud)

而且,一些C++编译器似乎也不理解它。我创建了一个Godbolt 示例,您可以在其中找到三种不同的编译器以不同的方式解决y歧义:

  • gcc报编译错误;
  • clang 选择int版本(这是我认为符合 …

c++ sfinae language-lawyer compiler-specific

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

自动检测C++ 14"return应该使用std :: move"的情况

我的理解是,在C++ 17中,以下片段旨在做正确的事:

struct Instrument;  // instrumented (non-trivial) move and copy operations

struct Base {
    Instrument i;
};

struct Derived : public Base {};

struct Unrelated {
    Instrument i;
    Unrelated(const Derived& d): i(d.i) {}
    Unrelated(Derived&& d): i(std::move(d.i)) {}
};

Unrelated test1() {
    Derived d1;
    return d1;
}

Base test2() {
    Derived d2;
    return d2;  // yes, this is slicing!
}
Run Code Online (Sandbox Code Playgroud)

也就是说,在C++ 17中,为了在这两个return语句中重载解析的目的,编译器应该将两者d1d2rvalues视为rvalues.但是,在C++ 14及更早版本中,情况并非如此; return操作数中的左值到右值变换应该仅在操作数完全正确的返回类型时应用.

此外,GCC和Clang似乎都在这个领域有混乱和可能的错误行为.在Wandbox上尝试上面的代码,我看到这些输出:

GCC 4.9.3 and earlier: copy/copy (regardless of …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer compiler-specific move-semantics c++17

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

什么是双变量参数?~打字稿

TypeScript 的文档随附Compiler Options,其中--strictFunctionTypes定义了其描述。不幸的是,无法获得什么是bivariant parameter。我也试图了解https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-function-parameters-bivariant

compiler-specific typescript

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