使用g++(GCC)4.8.3 20140911(Red Hat 4.8.3-7)使用编译命令"g++-g-fno省略帧指针-msse2-mssse3-O3 Memory.cpp"编译以下代码时,可执行文件在执行时引发"非法指令(核心转储)"。
它使用旧版g++使用完全相同的编译器标志进行编译和运行,没有问题。当编译器标志"-mssse3-O3"被删除或替换为较低的优化级别(如"-O2")时,它也可以编译和运行而不会出现问题。
如果同时使用旧的和新的g++编译器,具有编译器标志"-msse2-mssse3-O3",并具有可移植的对齐内存分配器是一项要求,那么存在哪些选项?下面的代码中是否有一个简单的错误可以很容易地修复?最后,为什么会出现这种错误?
使用gdb时,触发此错误的行是:"memory[i]=(unsigned char)i;"。
提前非常感谢。
#include <iostream>
using std::cerr;
using std::cout;
using std::endl;
using std::flush;
#include <stdlib.h>
void *aligned_alloc(int alignment, int size){
const int pointer_size = sizeof(unsigned char *);
const int requested_size = size + alignment - 1 + pointer_size;
unsigned char *base = (unsigned char *)malloc(requested_size);
if (base == NULL) return NULL;
unsigned char *start = base + pointer_size;
const int trim_offset = (int)(((unsigned long long)(start+alignment-1)) & (alignment-1));
unsigned char *aligned = start + alignment - 1 - trim_offset;
*(unsigned char **)(aligned-pointer_size) = base;
return aligned;
}
void aligned_free(void **aligned){
if (*aligned == NULL) return;
unsigned char *base = *(unsigned char **)((unsigned char *)(*aligned) - sizeof(unsigned char *));
free(base);
*aligned = NULL;
}
int main(){
unsigned char *memory = (unsigned char *)aligned_alloc(16, 120);
if (memory == NULL){
cout<<"ERROR: Unable to allocate memory."<<endl;
exit(1);
}
for (int i=0; i<120; i++){
memory[i] = (unsigned char)i;
}
aligned_free((void **)&memory);
return 0;
}
这是由于CPU不支持SSSE3(补充数据流单指令多数据扩展指令集3)指令子集(特别是某种风格的3GHZ P4),试图运行为支持该指令子集的CPU编译的代码;简单地从GCC命令行中删除-mssse3
标志就足以使有问题的指令消失。