2012-12-07 8 views
1

임베디드 SW 프로젝트의 경우 const volatile TYPE * 포인터를 사용해야합니다. 이제 다음과 같은 몇 가지 계산 함수가 있습니다.const volatile 포인터 함수 인수

uint8 calc(const volatile uint8 *array, uint8 value) { ... } 

두 변수의 데이터는 함수 실행 중에 변경되지 않습니다.

호출하는 코드처럼 보이는 다음

const volatile uint8 *array = (const volatile uint8 *)0x00010111; 
uint8 value = 8; 

uint8 result = calc(array, value); 

을 질문 지금, 우리는 휘발성 인수없이 calucation 기능을 설계 할 경우 차이가있을 것입니다 :

uint8 calc(const uint8 *array, uint8 value) { ... } 

를 호출 우리의 경우 휘발성을 버리십시오.

uint8 result = calc((const uint8 *)array, value); 

두 번째 솔루션에 대한 장점은 더 유연합니다. y : 비 휘발성 변수에도이 함수를 사용할 수 있습니다. 그러나 우리가 변동성을 제거하고 컴파일러가 강력한 최적화를 수행한다면 이것이 효과가 있습니까?

+0

아마도 아무런 차이가 없습니다. –

+1

아마도 차이는 없겠지만 컴파일러는 많은 작업을 수행 할 수 있으며 생성 된 기계 코드를 확인하는 유일한 방법은 알 수 있습니다. 캐스트에 대해 생각하는 한 가지 방법은 컴파일러에게 "나는 당신보다 더 잘 압니다"라고 말하고 있다는 것입니다. 이 경우에는 그렇지 않습니다. – msw

답변

0

실제로는 volatile-ness로 인해 발생할 수있는 것에 따라 다릅니다.

함수 실행 중에이 배열의 값이 변경되고 이러한 변경 사항이 발견되면이를 volatile으로 지정하십시오.

중요하지 않거나 "이전"값이 더 중요한 경우 volatile을 생략하십시오.

3

비 휘발성 인수가있는 함수를 항상 사용할 수 있습니다. 함수의 코드가 주어진 객체를 휘발성처럼 처리하는 것입니다 (그럴 경우 성능이 저하 될 가능성이 큽니다). 휘발성 논증 ("예고없이 변경 될 수 있기 때문에")이 무엇을 의미 하는지를 상상하기는 힘듭니다. 당신이 작성하는 것처럼, 당신의 경우에는 데이터가 변하지 않으므로 가장 유연한 솔루션은 매개 변수를 const로 선언하고 휘발성을 잊어 버리는 것입니다.

그리고 "uint8_t"를 사용하고 uint8과 같은 자체 제작 된 형식 이름을 사용하지 마십시오. 1996 년부터 표준에 포함되었습니다!

+0

물론, 필자는 그것을 작성하기 만했습니다.) - 제 동료는 컴파일러 (tricore 용)가 이상한 최적화를 수행하고 있다는 것에 대해 걱정하고 있습니다. – Ben

+0

여기서 정의되지 않은 작업을 수행하지 않으므로 컴파일러는 너무 이상한 일을 할 수 없습니다. 코를 날아 다니는 모든 악마는 자신의 코드가됩니다.). – slartibartfast

+1

이 대답은 함수 매개 변수는 휘발성이지만 함수는 비 휘발성 인수와 함께 호출되는 것처럼 표시됩니다. 그러나이 질문은 함수 매개 변수를 비 휘발성으로 수정하지만 휘발성이지만 비 휘발성으로 캐스팅 된 인수로 호출하는 방법에 대해 묻습니다. –

1

두 가지 경우가 있습니다. 기능이 하드웨어 레지스터 등을 직접 조작하는 것입니다. 그런 다음 이 매개 변수에 휘발성이 있어야합니다. 또는이 함수는 하드웨어 레지스터와 전혀 관련이 없습니다. 그런 다음 이 휘발성이어서는 안됩니다. 이 두 가지 경우에는 중간 지점이 없습니다. 함수 인자의 계산 순서가없는 동작이므로

또한 calc((const uint8_t*)array, value);

const uint8_t* ptr = array; 
calc(ptr, value); 

전 형태 나쁜 단지 불량 가능성 버 버전이다. 컴파일러는 왼쪽 피연산자 또는 오른쪽 피연산자를 먼저 평가하기로 선택했을 수 있습니다. 따라서이 명령을 알거나 추측 할 수 없습니다. 휘발성 액세스는 부작용이므로 원래 코드는 프로그램이 빌드 될 때마다 다른 결과를 줄 수 있습니다. 이것은 실시간 임베디드 시스템에서 특히 문제가되며 위험 할 수도 있습니다.

따라서 표현식 내에서 휘발성 변수에 절대 액세스하지 않는 것이 좋습니다 (MISRA-C : 2004 12.2 참조).

+0

여기에 동의하지 않습니다. "array"표현식의 평가는 휘발성 객체에 대한 액세스 권한을 부여하지 않습니다. 상호 액세스 순서 (예 : 인터럽트 플래그 및 승인 플래그)에 민감한 객체 (하드웨어 레지스터)가있는 경우 휘발성 메모리가 사용자의 햄을 저장하지 않습니다. - 현대 명령 - 딥 파이프 라인을 재정렬하면 프로그램 흐름을 강제로 시도하지 않습니다. 표준이 정의한 "가상의 이상적인 C 기계". 임베디드 PowerPC에서 문제의 이러한 속성과 정확히 일치하는 코드 검토를 진행했습니다. – slartibartfast

+0

@slartibartfast 올바르지 않습니다. 휘발성 객체는 비 휘발성 함수 매개 변수에 복사 될 때 액세스됩니다. 또한, 내 말은 다중 처리 또는 스레드 안전과 관련이 전혀 없으며 어디에서 가져 왔는지도 모른다. 그것들은 실시간 퍼포먼스와 관련이 있기 때문에 내 포스트의 "실시간"텍스트입니다. – Lundin

+0

휘발성 개체 ("배열"이 가리키는)가 호출에서 액세스되는 곳을 볼 수 없습니다. 또한 멀티 스레딩이나 멀티 프로세싱 중 하나도 언급하지 않았습니다. 이것은 프로그래머 (및 표준)가 "휘발성 (volatile)"을 사용하기 위해 의도 한 것을 끊는 재정렬 파이프 라인 내부의 단일 실행 스레드입니다. 그리고 그러한 문제가 어떻게 실시간 프로그래밍에만 관련되는지는 저 밖에 있습니다. 올바른 코드를 얻었거나 그렇지 않은 경우? – slartibartfast

관련 문제