【发布时间】:2019-10-24 15:56:10
【问题描述】:
我对内在函数还很陌生,我在使用 GCC-7.4 和 GCC-8.3 时遇到了我的代码的不同行为
我的代码很简单
b.cpp:
#include <iostream>
#include <xmmintrin.h>
void foo(const float num, const float denom)
{
const __v4sf num4 = {
num,
num,
num,
num,
};
const __v4sf denom4 = {
denom,
denom,
denom,
denom,
};
float res_arr[] = {0, 0, 0, 0};
__v4sf *res = (__v4sf*)res_arr;
*res = num4 / denom4;
std::cout << res_arr[0] << std::endl;
std::cout << res_arr[1] << std::endl;
std::cout << res_arr[2] << std::endl;
std::cout << res_arr[3] << std::endl;
}
在 b.cpp 中,我们基本上只是从浮点变量构造两个 __v4sf 并执行除法
b.h:
#ifndef B_H
#define B_H
void foo(const float num, const float denom);
#endif
a.cpp:
#include "b.h"
int main (void)
{
const float denominator = 1.0f;
const float numerator = 12.0f;
foo(numerator, denominator);
return 0;
}
这里我们只是从 b.cpp 调用我们的函数
GCC 7.4 工作正常:
g++-7 -c b.cpp -o b.o && g++-7 a.cpp b.o -o a.out && ./a.out
12
12
12
12
但是 GCC 8.3 出了点问题
g++-8 -c b.cpp -o b.o && g++-8 a.cpp b.o -o a.out && ./a.out
inf
inf
inf
inf
所以我的问题是 - 为什么我使用不同版本的 GCC 会收到不同的结果?它是未定义的行为吗?
【问题讨论】:
-
您正在使用特定于编译器的功能。根据定义,它是未定义的行为。 C++ 标准中“未定义”的含义本质上是“C++ 标准没有对发生的事情指定任何约束”。该标准当然没有指定您可能使用的任何编译器特定的内在函数。如果您想了解发生了什么,请阅读 gcc 文档 - 可能适用于您正在使用的两个版本。
-
@Peter 这不是未定义的,它的implementation defined(因为
__v4sfstarts with__)。主要区别,这基本上意味着标准方面的问题,并说“它被定义为:做任何实现(在本例中为 gcc)想要它做的事情。” -
这看起来像是 gcc 中的一个错误(您可以通过删除一些
const来解决它)。请向 gcc 的 bugzilla 报告,以便修复,谢谢。 -
@MarcGlisse 我创建了错误报告gcc.gnu.org/bugzilla/show_bug.cgi?id=90810(不确定我的格式是否正确)。等待答复
-
请注意,您的代码至少由于对齐原因被破坏:
__v4sf假定 16 字节对齐,而 res_arr 仅保证 4。
标签: c++ gcc undefined-behavior intrinsics