- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我们刚刚从 VS2010 迁移到 VS2013,我发现了一个奇怪的错误,我想这可能是由于编译器造成的。
使用命令行 cl ConsoleApplication1.cpp/EHa/fp:strict/O2
编译以下程序:0xC0000005:访问冲突读取位置 0xFFFFFFFF。
这仅在编译为 32 位(而非 64 位)时发生
#include <iostream>
#include <cmath>
class Vector2D
{
public:
double x;
double y;
Vector2D() : x(0), y(0) {}
Vector2D(double _x, double _y) : x(_x), y(_y) {}
double Width() { return x; }
double Height() { return y; }
};
bool IsEqual(const double & a, const double & b)
{
if (a == b)
return true;
double tolerance = pow(10., -5);
if (::fabs(a) < tolerance / 2.)
{
return ::fabs(b) < tolerance / 2.;
}
double diff = ::fabs((b - a) / a);
return (diff < tolerance);
}
bool IsEqual(Vector2D & a, Vector2D & b)
{
return IsEqual(a.Width(), b.Width()) && IsEqual(a.Height(), b.Height());
}
std::string GetMsg()
{
return std::string("");
}
int main(int argc, char* argv[])
{
Vector2D v1;
Vector2D v2;
v1 = Vector2D(1, 0);
// This innocent call will cause an access violation
// the access violation occurs *only* if fp:strict and /EHa switches are used
GetMsg(), IsEqual(v1, v2);
return 0;
}
我是在指责编译器太快了吗?
最佳答案
这是一个自动矢量化错误,它死于访问本地 Vector2D 变量的 UNPCKLPS 指令,它没有正确对齐。基本错误在函数的序言中:
int main(int argc, char* argv[]) {
013A16B0 push ebp
013A16B1 mov ebp,esp
013A16B3 and esp,0FFFFFFF8h
AND 指令错误,它将堆栈对齐到 8 而不是 16。不足以提供 SSE2 代码所需的对齐保证。此错误的最强候选者是/EHa,它阻止 IsEqual() 被优化掉。可能是因为优化器无法假定抛出 SEH 异常不会产生副作用。现在强加对齐要求。
您可以通过显式声明要对齐的变量来解决这个问题:
__declspec(align(16)) Vector2D v1;
__declspec(align(16)) Vector2D v2;
代码优化器现在可以:
001E16B3 and esp,0FFFFFFF0h
到目前为止,最令人惊叹的解决方法是:
__declspec(noinline)
bool IsEqual(Vector2D & a, Vector2D & b) {
// etc..
}
并且优化器现在决定删除不必要的 IsEqual() 调用,从而删除对齐要求。呵呵。优化器 bug 有很强的行为习惯,就像这样。
此错误不会出现在 VS2015 中,很难判断它是否真正得到解决,因为它生成了一个非常不同的序言,似乎假设 main() 函数已经进入对齐堆栈。如果你想从马口中听到它,你可以在 connect.microsoft.com 上提交错误。
关于c++ - VS2013 : compiler bug with float and/EHa +/fp:strict?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33526606/
什么时候使用 fp:strict 而不是 fp:precise?如果我想要“更精确”的计算并避免舍入误差,使用前者是否更好?使用这两者背后的启发是什么? 最佳答案 标准 IEEE 754 指定了一种用
我检测到发布版本和调试版本之间的程序结果存在一些差异。经过一些研究,我意识到一些浮点优化导致了这些差异。我已经通过使用 fenv_access pragma 禁用一些关键方法的优化来解决了这个问题。
我在 Built-in Functions — Python 3.7.0 documentation 中阅读了内置函数 iter 的示例 with open('mydata.txt') as fp:
我在 Built-in Functions — Python 3.7.0 documentation 中阅读了内置函数 iter 的示例 with open('mydata.txt') as fp:
我一直在查找一些用 C 语言读取文件的例子,我看到了这两个例子 fgets(buff,255,(FILE*)fp); 和 fgets(buff,255,fp); 假设 fp 是前面定义的文件指针 "F
我是 FP-TS 的新手,但仍然不太明白如何使用 TaskEither .我正在尝试异步读取文件,然后使用 yaml-parse-promise 解析结果字符串。 ==编辑== 我用文件的完整内容更新
我需要在我的 Mac 上编译一个 C 文件,该文件是在仅假设 Linux 和 GCC 环境下编写的。该文件包含一行 if(fp->_IO_write_base == fp->_IO_write_end
for line in fp 和 for line in fp.readlines() 有什么区别? with open(filename, 'r') as fp : for line in
这可能非常无聊,但谷歌搜索确实没有帮助。 在python官方文档中,它经常将文件称为fp: with open(filename, "w") as fp: fp.write() “p”代表什么? 最佳
我想知道如果我设置/fp:fast 而不是 fp:precise 会遇到什么样的错误?我在 MSV10 下工作 我对最大位数为 8 的 double 执行/,*,+,- 运算,例如 1.4379294
我正在使用 Groovy 进行一个项目,我想采用一个员工数组,这样在数组中没有经理跟随他们的下属。原因是我需要将人员添加到数据库中,我不希望分两次完成。 所以,我基本上有: 12
背景: 许多年前,我继承了一个代码库,该代码库使用 Visual Studio (VC++) 标志“/fp:fast”在特定的计算量大的库中生成更快的代码。不幸的是,'/fp:fast' 产生的结果与
我正在尝试从PostgreSQL数据库检索数据,将其转换为视图模型数组,并将数据返回给客户端,在本例中最好是作为单个对象,而不是数组。对于我在错误消息下面列出的代码,我收到以下错误。我是函数式编程领域
所以我尝试将此类 Matlab 代码转换为 C++: ss = 'file.mask' fp = fopen(ss, 'rb'); sx = fread(fp, 1, 'int32') sy = f
我是fp-ts的新手,请帮助我解决问题: 我需要使用异步功能在不同级别上多次记录同一错误。这是我的示例代码: const myProgram = pipe( tryCatch(() => so
我正在尝试在为浏览器编写的库中使用 lodash/fp。我正在使用 Webpack 来打包我的库。 在我的代码中,我当前加载 lodash/fp 如下(ES2015 样式。我使用 Babel 对其进行
我的问题是引用 this post ,具体来说: data Actions a = Actions { actEval :: a, actMap :: (a -> a) -> Act
我正在阅读 FP,我有两个基本问题: FP 表示函数应该接受一个输入并给出单个输出。那么我该怎么办void方法?它不返回任何东西吗? FP 说函数应该是单一的 责任,那我们怎么处理log方法内的语句?
我是 c 初学者,所以我在让用户输入姓氏、逗号和名字时遇到问题。但是它将传递给函数调用 int get_name(FILE *fp) 在我的主要功能中。如果我必须使用参数参数,我就会遇到问题。 示例,
我有一些这样的序列 (100) - (102) - (103) - (104,106) - (108) (101) - (103) (102) - (106) 在 C++ 中有一些有效的实现前缀树或
我是一名优秀的程序员,十分优秀!