2009-11-07 2 views
0

저는 상속받은 객체의 정렬을 지시하는 기본 클래스를 갖고 싶습니다. 할당 된 방법과 배열을 사용자 지정 배열 템플릿에 할당하는 방법을 제어 할 수 있기 때문에 힙에 문제가 없습니다. 그러나 C++와 관련하여 클래스의 실제 크기는 전혀 변경되지 않습니다. 즉, 파생 클래스의 포인터에 대해 포인터 연산을 수행하면 잘못된 위치로 건너 뜁니다. 그것은 하나의 문제입니다.상속받은 클래스에 클래스 정렬? 모든 스택 정렬을 강제 하시겠습니까? 크기를 변경 하시겠습니까?

문제 2는 스택 정렬입니다. 직접 전체 스택을 16 바이트 정렬 포인터로 강제하는 방법은없는 것 같습니다.

이러한 모든 영향을 볼 수있는 유일한 것은 vC++ 및 g ++ 컴파일러 특정 설정이지만 문제는 여기에 항상 정렬을 수동으로 수정하지 않아도된다는 것입니다. 그것은 통증은 말할 것도없고 오류가 발생하기 쉽습니다.

나는 또한 일종의 스마트 포인터를 만들 수도 있지만 그게 더 많은 문제를 제기 할 수도 있습니다.

기본 클래스 만 정렬하면 하위 클래스도 정렬됩니까? 그렇다면 대부분의 문제점을 해결할 수는 있지만 문제가 될 수 있습니다.

답변

1

기본 클래스에 특정 정렬 요구 사항이있는 경우 파생 클래스는 최소한 해당 맞춤을 갖습니다 (자체 멤버로 인해 더 엄격한 정렬 요구 사항을 얻을 수 있음). 그렇지 않으면 컴파일러는 기본 멤버에 액세스하는 것이 기본 요구 사항을 충족시킬 것이라고 보장 할 수 없습니다.

그러나 실제로 스택 정렬을 위해 이식 할 수있는 것은 없습니다. 이는 컴파일러와 컴파일러의 플랫폼 ABI 요구 사항에 의해 전적으로 처리됩니다. 컴파일러 옵션 또는 pragma를 사용하면 제어 할 수 있지만 휴대용은 할 수 없습니다.

+0

감사합니다. 거기에 '정렬되지 않은'포인터를 할당하려고하면 컴파일러 오류를 피할 수있는 방법이 있습니까? 나는 그것이 나 자신을 얻은 이후로 항상 정렬되어 있다는 것을 안다. 나는 가능한 한 전체 프로그램을 통해 이러한 선언을하는 것을 피하고 싶습니다. 이것이 쉬운 일이 아닌 것 같지만 그렇지 않습니다. –

+0

신경 쓰지 마 마침내 문제가 발생합니다. 이전에이 팝업이 있었지만 해결할 수 있다고 생각하지 않았지만 참조를 전달하는 것으로 변경하면 문제가 해결되었습니다. 나는 매우 혼란 스러웠지만 혼란스러운 주제라고 생각합니다. –

+1

일부 코드를 게시하고 싶을 수도 있습니다. 컴파일러가 '정렬되지 않은 포인터'에 대해 불평할지 모릅니다. 바이트 배열에 대한 포인터를 클래스에 캐스팅하는 경우 정렬 요구 사항을 위반했을 수 있습니다. 참조로 무엇을하고 있더라도 문제를 숨길 수 있습니다. –

0

이식성과 관련하여 Michael의 대답을 지키고 있습니다. SSE 벡터화를 목표로하고 있으며 그 고통을 느끼기 시작하고 있으며 명시적인 힌트와 저수준으로이를 수행하는 표준 방법이되어야한다고 생각합니다. 제어. 언급 한 두 컴파일러는 기본적으로 스택에서 16 바이트 정렬을 위해 노력합니다.

컴파일러 지원은 다양하지만 변경이 가능하거나 도전을받는 등 그 중 하나에서 크게 활용 될 수는 없습니다. 그것은 당신이 포함하고있는 옵티 마이저와 타입에 달려 있으며, 자연스럽게 vectorizer의 선택에 달려 있습니다. 그리고 다시, 당신이하고있는 일과 용도가 명확하지 않습니다. 예를 들어없이 문제 정의 스케치이기 때문에

는, 아마도 당신이 declspec에 주사를 할 수 있습니다 (정렬 (16)) (LTCG와) 캘리포니아 및 __attribute에 대한 ((정렬 (16))) GCC합니다. 도움이된다면 우리에게 알려주는 것이 좋을 것입니다. 예를 들어 어떤 컴파일러의 경고 나 오류가 발생했는지 알 수 있습니다. 나는 또한 여러 가지 이유로 스마트 포인터 사용을 피할 것이다.

귀하의 질문에 당신은 또한 변수 배열과 포인터 유형과 관련하여 문제가 있음을 나타냅니다.이 경우 전자는 문제가 될 수 있습니다. 그리고 복사 생성자와 할당 기능을 잃어 버릴 수는 있지만 기계 코드를 검사해도 아무런 해가 없습니다. 즉, 복잡한 경우에는 출력을보고 Windows에서 VC++ 스위치를 사용하여 Windows에서 더 나은 힌트를 얻고 컴파일러 및 런타임 어설 션/트랩 오류를 일찍 테스트하거나 다른 테스트에서 테스트합니다 모든 무료 객체 파일 분석 도구. 그런 다음 문제가되는 명확한 구조를 가능한 한 가장 안전한 방법으로 해결하면 항상 가능합니다.

+0

나는 왜 그것을하고 있는지 보았다. 나는 그것이 16 바이트를 얼마나 잘 유지하는지 확신하지 못하지만, 심지어 가능성으로 인해 값으로 전달할 때 컴파일러 오류가 발생한다. 왜 그런지 모르겠지만 그 패스는 어쨌든 실수 일뿐입니다. 좋은 답변을 주셔서 감사합니다, 얘들 아, 나는 대부분 과장되어 있었지만 이제는 매력처럼 작동한다. 놀랄만 한 속도 개선. –

0

PARISC HPUX에서 유일한 원자 구조가 16 바이트 정렬을 필요로하는 4 바이트 원자어로 된 비슷한 문제가있었습니다.

우리는과 같이 우리의 4 바이트 양을 선언하여 꾸며 낼 수있다 :

 
struct Stupid_HPUX 
{ 
    int 4byteLockWordInHere[4] ; 
} ; 

오른쪽 하나를 따기 런타임에 사용할 수 있습니다. 귀하의 문제에 대해 비슷한 것을 할 수 있습니다.

 
union rawMemory 
{ 
    int blah[(sizeof(yourtype) + 16)/4] ; 
    char c[1] ; 
} u ; 

그런 다음 런타임에서 결정된 주소로 새로운 위치를 사용하여 필요한 위치를 수정하십시오.