2010-04-06 4 views
0

다음 코드를 실행 한 후 SIGILL이 표시됩니다. 나는 그것이 무엇이 잘못되었는지를 정말로 알 수 없다.float에서 고정 전환으로 SIGILL 받기

대상 플랫폼은 ARM, 그리고 나는 포트 (이 코드가 포함되어있는) 알려진 라이브러리

void convertFloatToFixed(float nX, float nY, unsigned int &nFixed) { 
    short sx = (short) (nX * 32); 
    short sy = (short) (nY * 32); 

    unsigned short *ux = (unsigned short*) &sx; 
    unsigned short *uy = (unsigned short*) &sy; 

    nFixed = (*ux << 16) | *uy; 
} 

이 거기에 어떤 도움을 크게 감상 할 수 노력하고있어. 사전에

덕분에

+0

첫 번째 캐스트의 경우 'static_cast'와 같은 이름의 캐스트를 선호하고 'short sx = static_cast (nX * 32)'및 'unsigned short ux = reinterpret_cast < 서명되지 않은 짧은 &>(sx);' – GManNickG

+0

나는 마지막 줄까지 SIGILL의 원인을 찾아 냈지만 이유를 이해할 수는 없다. 거기에 문제가 있습니까? – foliveira

+2

스택에 반송 주소를 불어 넣는 나쁜 코드 생성을 추측합니다. 코드는 컴파일러가 스스로 멈출 수있게 해주는 많은 로프를 제공합니다. 포인터 캐스트를 없애기 시작하면 간단한 캐스트가 수행합니다. –

답변

1

일부 ARM 프로세서는 하드웨어 부동 소수점을 가지고 있고, 일부는하지 않습니다, 그래서이 기능은 하드웨어 부동 소수점에 대한 컴파일되는 것이 가능하지만 플랫폼은 부동 소수점 유닛이 부족 따라서 부동 소수점 명령어는 프로세서로 하여금 잘못된 명령어를보고하게합니다. 이것이 테스트 프로그램의 첫 번째 부동 소수점 계산 인 경우 문제가 될 가능성이 매우 높습니다. gcc에 전달해야하는 -march 옵션을 찾거나 이미 작동하는 일부 프로그램에서 사용하는 컴파일 옵션을 살펴 보려면 플랫폼의 설명서를 확인하십시오.

이 함수는 동작을 정의하지 않았으므로 원하는 동작이 무엇인지 나타내지 않고 개선을 제안하기 어렵습니다. 시작이 뭔가를 시도 : - 나는 포인터를 제거있어 (다른 사람들이 지적으로) 엄격한 앨리어싱 규칙을 파괴하는 캐스트 한

void convertFloatToFixed(float nX, float nY, unsigned int &nFixed) { 
    assert(nX * 32 < INT_MAX); 
    assert(nY * 32 < INT_MAX); 

    int sx = nX * 32; 
    int sy = nY * 32; 

    unsigned int ux = sx; 
    unsigned int uy = sy; 

    nFixed = (ux << 16) | uy; 
} 

. 또한 short 대신 int을 사용했습니다. 어쨌든 계산 전에 int으로 넓혀 지므로 일반적으로 short 개의 자동 변수가있는 지점이 없습니다. (short을 16 비트 씩 이동하는 것은별로 유용하지 않을 것입니다.) 몇 가지 검사를 추가 했으므로 디버그 빌드에서 float-to-integer 변환이 오버플로되어 정의되지 않은 동작이 발생하는지 확인할 수 있습니다 .

+0

제가 그 당시 (거의 2 년 전) 테스트했던 시스템에서 부동 소수점 유닛의 부족과 관련된 문제는 그 답을 받아 들일 것입니다. – foliveira

관련 문제