我实现了一个带有指向某个手动管理内存的指针的结构。这一切都适用于DMD,但是当我使用GDC测试时,它在opEquals
运算符重载失败。我把它缩小到了memcmp。在opEquals
中,我将指向内存与memcmp进行比较,后者的行为与我在DMD中的预期相同,但在GDC中失败。
如果我通过在内置类型上使用opEquals
一次比较存储在手动管理的内存1中的每个值来返回并编写==
方法,则它在两个编译器中都有效。我更喜欢memcmp路由,因为它写得更短,看起来应该更快(更少的间接,迭代等)。
为什么呢?这是一个错误吗?
(我对C的经验是10年前,因为我一直在使用python / java,我在C中从未遇到过这种问题,但我没有那么多使用它。)
编辑:
我比较的记忆代表了一个真实的2-D阵列。值,我只是希望它被分配在一个块中,所以我没有必要处理锯齿状数组。我将在紧密的循环中使用结构。基本上我是在滚动我自己的矩阵结构,它将(最终)缓存一些常用的值(跟踪,行列式),并为不需要复制它的转置提供备用只读视图。我计划使用大约10x10到大约1000x1000的矩阵(虽然不总是正方形)。
我还计划实现一个版本,通过ubyte[]
为GC分配内存并分析这两个实现。
编辑2:
好的,我尝试过几件事。我也有一些parallel
循环,我有一个可能是问题的预感。所以我添加了一些版本语句来制作并行和非并行版本。为了使其与GDC一起使用,我必须使用非并行版本并将real
更改为double
。
所有案例均在GDC下编制。但是单元测试失败了,并不总是在同一条线上,但是当我使用opEquals
或real
时,始终在parallel
调用。在DMD中,所有案例都编译并运行没有问题。
谢谢,
答案 0 :(得分:2)
real
有一个奇怪的大小:它是80位数据,但如果你检查real.sizeof,你会发现它比那个大(至少在Linux上,我认为它在Windows上是10个字节,我打赌你不会在那里看到这个错误)。原因是要确保它在字边界上对齐 - 四个字节的倍数 - 以便处理器在数组中加载更高效。
每个数据元素之间的字节称为填充,并且不总是定义它们的内容。我自己也没有证实这一点,但@jpf对这个问题的评论说我的直觉也是如此,所以我现在把它作为答案发布。
D中的is
运算符与memcmp(&data1, &data2, data.sizeof)
的运算符相同,因此@ jpf的注释和memcmp
将是相同的。它检查数据和填充,而==只检查数据(并且对浮动类型btw有点特殊,因为它也比较NaN,所以确切的位模式对那些检查很重要;实际上,我的第一个肠道当我看到问题的标题是它与NaN有关!但不是这样的情况)
无论如何,显然dmd也会初始化填充字节,而gdc则不会,它会把它留作垃圾而不会总是匹配。