Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用-O3优化和奇数间距填充16bpp图像时崩溃_C++_Optimization_G++ - Fatal编程技术网

C++ 用-O3优化和奇数间距填充16bpp图像时崩溃

C++ 用-O3优化和奇数间距填充16bpp图像时崩溃,c++,optimization,g++,C++,Optimization,G++,我编写了一个非常简单的代码,用一个常量值(1024)填充一个32x32 16bpp的图像。图像缓冲区由std::vector托管。我的图像的基音/步幅(即两个连续行之间的字节数)大到足以容纳整行,但设置为奇数。这是我的密码: #包括 #包括 int main() { 整数宽度=32; 整数高度=32; 内螺距=宽度*2+1; 标准::矢量图像(高度*间距); uint8_t*缓冲区=&image[0]; 对于(int y=0;y

我编写了一个非常简单的代码,用一个常量值(1024)填充一个32x32 16bpp的图像。图像缓冲区由
std::vector
托管。我的图像的基音/步幅(即两个连续行之间的字节数)大到足以容纳整行,但设置为奇数。这是我的密码:

#包括
#包括
int main()
{
整数宽度=32;
整数高度=32;
内螺距=宽度*2+1;
标准::矢量图像(高度*间距);
uint8_t*缓冲区=&image[0];
对于(int y=0;y
我使用的是带有GCC4.6.1(Ubuntu 11.10)的Linux x86_64。代码在
-O0
-O1
-O2
优化级别下运行良好。Valgrind未报告任何访问冲突。但是,只要我切换到
-O3
或使用
-ftree vectorize
选项进行自动矢量化
,程序就会崩溃:

#g++-g-O3./test.cpp-Wall-pedantic&./a.out
分段故障
#g++-g-O2-ftree矢量化./test.cpp-Wall-pedantic&&./a.out
分段故障
gdb和valgrind均未提供任何有用信息:

#valgrind./a.out
==3840==Memcheck,内存错误检测器
==3840==2002-2010年版权(C)和GNU GPL'd,朱利安·苏厄德等人。
==3840==使用Valgrind-3.6.1-Debian和LibVEX;使用-h重新运行以获取版权信息
==3840==命令:./a.out
==3840== 
==3840== 
==3840==进程以信号11(SIGSEGV)的默认动作终止
==3840==一般保护故障
==3840==0x4005B3:main处(test.cpp:18)
==3840== 
==3840==堆摘要:
==3840==在出口处使用:1个块中的2080字节
==3840==总堆使用率:1个allocs,0个frees,分配2080字节
==3840== 
==3840==泄漏汇总:
==3840==肯定丢失:1个块中有2080字节
==3840==间接丢失:0个块中有0个字节
==3840==可能丢失:0个块中有0个字节
==3840==仍然可访问:0个块中有0个字节
==3840==抑制:0个块中有0个字节
==3840==使用--leak check=full重新运行以查看泄漏内存的详细信息
==3840== 
==3840==对于检测到的和抑制的错误计数,请使用:-v重新运行
==3840==错误摘要:0个上下文中的0个错误(已抑制:4个上下文中的4个)
分段故障
当我切换到带有
-m32
gcc标志的32位二进制文件时,不会发生崩溃。如果使用偶数音高(例如,
pitch=width*2+2
),也不会出现这种情况。有谁能帮我找出我在代码中犯的(当然是愚蠢的)错误吗?非常感谢


更新:根据Jonathan的建议,我刚刚向GCC开发人员报告了这个问题:
我的问题已由Richard Blener在以下网站上回答:

您正在取消引用一个指向uint16_t的指针,该指针没有针对该类型进行充分对齐。C标准禁止这样做,从而导致未定义的行为


在我看来,应该对这种未定义的行为发出警告。还请注意,@jmetcalfe在本文的评论中也给出了这一解释。

比较生成的汇编代码。此外,您可能希望使用单个选项进行测试
-O3
打开以查看哪一个是罪魁祸首(请参阅选项列表)。@JoachimPileborg罪魁祸首是
-ftree向量化
选项。不幸的是,我对汇编不够熟悉,无法理解崩溃的原因。@Jonathan代码访问未对齐的uint16\t。这不是UB吗?@jmetcalfe,我认为向量器应该在支持它们的平台上处理未对齐的访问,我认为包括x86_64。它可能仍然是一个别名冲突,但是
-fno strict aliasing
不会改变任何东西。我可能是错的,但是在gcc帮助列表中询问或报告(可能无效)错误似乎适合我,并得到了快速响应,正如@jmetcalfe所说,
reinterpret_cast
是告诉编译器闭嘴并处理指针的方式。有太多几乎无法检测到的场景涉及到重新解释,试图为它们编写警告是徒劳的。@Tisys,不要混淆未定义和未指定,它们非常不同