코드를 검토 할 때 다음 규칙을 적용합니다.
const
함수가 가리키는 데이터를 수정하거나 해제하지 않는 경우 참조로 전달 된 함수 매개 변수에 항상 사용 하십시오.
int find(const int *data, size_t size, int value);
항상 const
#define 또는 열거 형을 사용하여 정의 할 수있는 상수에 사용하십시오. 컴파일러는 결과적으로 ROM (읽기 전용 메모리)에 데이터를 배치 할 수 있습니다 (링커는 종종 임베디드 시스템에서이 목적을 위해 더 나은 도구 임).
const double PI = 3.14;
value로 전달 된 매개 변수
에 대해 함수 프로토 타입 에서 const를 사용하지 마십시오 . 그것은 의미가 없으며 따라서 단지 '잡음'입니다.
// don't add const to 'value' or 'size'
int find(const int *data, size_t size, const int value);
적절한 const volatile
경우 프로그램에서 변경할 수 없지만 여전히 변경 될 수있는 위치 에서 사용 하십시오. 하드웨어 레지스터는 일반적인 유스 케이스입니다 (예 : 장치 상태를 반영하는 상태 레지스터).
const volatile int32_t *DEVICE_STATUS = (int32_t*) 0x100;
다른 용도는 선택 사항입니다. 예를 들어, 함수 구현 내의 함수에 대한 매개 변수 는 const로 표시 될 수 있습니다.
// 'value' and 'size can be marked as const here
int find(const int *data, const size_t size, const int value)
{
... etc
또는 함수 반환 값 또는 얻은 다음 절대로 변경하지 않는 계산 :
char *repeat_str(const char *str, size_t n)
{
const size_t len = strlen(str);
const size_t buf_size = 1 + (len * n);
char *buf = malloc(buf_size);
...
이러한 용도 const
는 변수를 변경하지 않음을 나타냅니다. 변수가 저장되는 방법이나 위치를 변경하지 않습니다. 컴파일러는 변수가 변경되지 않았 음을 추가로 해결할 수 있지만 추가 const
하면 변수 를 적용 할 수 있습니다. 이것은 독자를 돕고 안전성을 높이는 데 도움이 될 수 있습니다 (함수가 큰 차이를 만들 정도로 충분히 크거나 복잡하더라도 다른 문제가있을 수 있습니다). 편집-예. 중첩 된 루프와 길거나 유사한 변수 이름이 많은 200 줄의 밀도가 높은 코드화 된 함수는 특정 변수가 절대로 변경되지 않는다는 것을 알기 때문에 크게 이해하기 어려울 수 있습니다. 이러한 기능은 잘못 설계되거나 유지 관리되었습니다.
문제 const
. 아마도 "const poisoning"이라는 용어를들을 것입니다. const
함수 매개 변수에 추가 하면 'constness'가 전파 될 때 발생합니다 .
편집-const poisoning : 예를 들어 함수에서 :
int function_a(char * str, int n)
{
...
function_b(str);
...
}
우리가 변경 한 경우 str
에 const
, 우리는 그가 확인해야합니다 fuction_b
도합니다 const
. 등등 경우는 function_b
를 전달 str
에게 function_c
이 많은 별도의 파일 / 모듈로 전달하면이 고통이 될 수 상상할 수 있듯이 등. 변경할 수없는 함수 (예 : 시스템 라이브러리)로 전파되면 캐스트가 필요합니다. 따라서
const
기존 코드를 뿌리면 문제가 발생할 수 있습니다. 새 코드 const
에서는 적절한 곳에서 일관되게 자격 을 얻는 것이 가장 좋습니다 .
더 교활한 문제 const
는 원래 언어가 아니었다는 것입니다. 애드온 으로서는 적합하지 않습니다. 처음에는 두 가지 의미가 있습니다 (위의 규칙에서와 같이 "이것은 변경하지 않을 것입니다"와 "이것은 수정할 수 없습니다"를 의미합니다). 그러나 그 이상으로 위험 할 수 있습니다. 예를 들어,이 코드를 컴파일하고 실행하면 (컴파일러 / 옵션에 따라) 실행될 때 충돌이 발생할 수 있습니다.
const char str[] = "hello world\n";
char *s = strchr(str, '\n');
*s = '\0';
strchr
는 char*
아닌을 반환합니다 const char*
. 호출 매개 변수는
호출 매개 변수를로 캐스팅const
해야합니다 . 그리고이 경우 실제 읽기 전용 저장소 속성을 제거합니다. 편집 :-이것은 일반적으로 읽기 전용 메모리의 var에 적용됩니다. 'ROM'은 일반적인 ROM에서 실행되는 프로그램의 코드 섹션에서와 같이 물리적 ROM뿐만 아니라 쓰기 방지 된 메모리를 의미합니다.char*
많은 표준 라이브러리 함수는 같은 방식으로 작동하므로주의하십시오. 실제 상수 가있을 때 (즉, ROM에 저장 됨) 그 일관성을 잃지 않도록주의해야합니다.
Specific issues with software development
. 나는 매우 구체적입니다.