2017-10-10 9 views
1

나는 다음과 같은 C 코드가 있다고 가정 : 이제C : "게터"기능과 중단 정적 휘발성를 사용

/* clock.c */ 

#include "clock.h" 

static volatile uint32_t clock_ticks; 

uint32_t get_clock_ticks(void) 
{ 
    return clock_ticks; 
} 

void clock_tick(void) 
{ 
    clock_ticks++; 
} 

내가 clock_tick를 호출 오전 :에서 get_clock_ticks()를 호출하는 동안, 중단 내에서 (즉 clock_ticks 변수를 증가) main() 기능 (예 : 중단 외부).

나의 이해는 clock_ticks는 달리 컴파일러가 액세스를 최적화 할 수 volatile로 선언하고 (실제로 중단 변경하면서) main()이 값이 변경되지 않은 생각하게해야한다는 것입니다. 실제로는 volatile로 선언되지 않은 경우에도 메모리에서 변수를로드하도록 컴파일러에 강제로 직접 main() (즉 : static로 선언하지)를 형성하는 대신 변수를 액세스, 거기 get_clock_ticks(void) 기능을 사용하는 경우

이 궁금하다.

누군가가이 일이 일어날 수 있다고 말하면서 나는 이것을 궁금해합니다. 사실입니까? 어떤 조건 하에서? 어쨌든 "getter"기능을 사용하면 항상 volatile을 사용해야합니까?

+0

귀하의 경우에는 '휘발성'이 필수적입니다. 변수가 인터럽트에서 액세스 될 때 차이를 만들고 있습니다. 이 방법은 컴파일러가 알지 못하는 변수를 액세스하고 수정하는 것이 있다는 것을 알고 있습니다. 그렇지 않으면 "getter"가 변수의 상수 초기 값을 반환합니다. –

+0

https://stackoverflow.com/questions/5822386/the-volatile-keyword-in-c-language –

+0

getter 함수가 인라인 될 수 있습니다. 비 일관성 동작으로 나타날 수있는 캐시 일관성 문제가있을 수 있습니다. – jxh

답변

2

게터 기능은 어떤 식 으로든 volatile을 사용하는 데 도움이되지 않습니다.

  • 컴파일러가 방금 두 줄 이상의 값을 가져 왔고 그 이후로 변경되지 않았다고 가정합니다.
  • 좋은 최적화 컴파일러라면 함수 호출이 단순히 함수 호출을 최적화하는 부작용이 없다는 것을 기대합니다. get_clock_ticks()external 될 경우

은 (즉, 별도의 모듈), 문제는 (어쩌면 당신이 기억 기능) 다릅니다.

일반적인 프로그램 흐름 (예 : ISR)에서 값이 변경 될 수있는 항목은 이어야하며volatile이어야합니다.

+0

답해 주셔서 감사합니다. 누군가가 여기에 뭔가를 추가하려고 할 때를 대비하여 내일까지 기다릴 것입니다. ^^ – Peque

+0

표시된 코드는'clock.c' 파일에 있으며'clock.h' 헤더를 포함합니다. 클럭 기능 (예 :'main()'이 들어있는 파일)을 사용하는 코드는 헤더 만 포함하므로 둘 중 하나의 함수를 인라인 할 기회가 없습니다. 물론, OP가'clock.c' 파일을 포함하는 것을 막을 수있는 방법은 없지만, 그것이 예상되는 것은 아닙니다. (이 코드는 인터럽트가 어떻게 설정되는지 보여주지 않습니다.) –

+0

@JonathanLeffler "clock.c"를 모두 본 것으로 가정합니다. 나는 반드시 그렇게하지 않는다. 'get_clock_ticks()'가 "clock.c"의 바깥 쪽에서 또는 내부에서 호출 될 때 옵션을 최적화하는 데 차이가 있습니다 ("작동하지 않는다"는 이유로 "때때로 작동하지 않습니다"). – tofro

1

get_clock_ticks를 선언하는 코드와 별도의 모듈로 사용하는 코드를 컴파일하더라도 언젠가는 링크 시간 또는 모듈 간 최적화를 사용할 것입니다. getter 함수를 사용하는 경우에도 "휘발성"을 유지하십시오.이 경우 코드 생성에 아무런 해가 없으며 코드가 정확합니다.

언급하지 않은 한 가지는 프로세서의 비트 크기입니다. 단일 연산에서 32 비트 값을 읽을 수없는 경우, 읽기가 원 자성이 아니므로 get_clock_ticks()가 실패하는 경우가 있습니다.

+0

감사합니다. 예, 32 비트 ARM입니다. – Peque