대부분의 C 개발자가 const 대신 define을 사용하는 이유는 무엇입니까? [복제]
이 질문에 이미 답변이 있습니다.
많은 프로그램에서 a #define
는 상수와 동일한 목적으로 사용됩니다. 예를 들면.
#define FIELD_WIDTH 10
const int fieldWidth = 10;
나는 일반적으로 기본적으로 응용 프로그램 결정을 처리하기 위해 전처리기에 의존하는 다른 것보다 선호되는 첫 번째 형식을 봅니다. 이 전통에 대한 이유가 있습니까?
이에 대한 매우 확실한 이유가 있습니다. const
C에서 무언가가 일정하다는 것을 의미하지는 않습니다. 변수가 읽기 전용임을 의미합니다.
컴파일러가 실제 상수 (예 : 비 VLA 배열의 배열 크기)를 필요로하는 곳에서 const
변수를 사용하는 fieldWidth
것은 불가능합니다.
그들은 다릅니다.
const
런타임에 변수를 변경할 수 없음을 나타내는 한정자 일뿐입니다. 그러나 변수의 다른 모든 기능은 유지됩니다. 할당 된 스토리지가 있으며이 스토리지가 처리 될 수 있습니다. 따라서 코드는이를 리터럴로 취급하는 것이 아니라 지정된 메모리 위치에 액세스하고 (인 경우 static const
최적화 할 수있는 경우 제외 ) 런타임에 해당 값을로드하여 변수를 참조합니다. 그리고 const
변수가 스토리지를 할당했기 때문에 헤더에 추가하고이를 여러 C 소스에 포함하면으로 표시하지 않는 한 "다중 심볼 정의"연결 오류가 발생합니다 extern
. 이 경우 컴파일러는 실제 값에 대해 코드를 최적화 할 수 없습니다 (글로벌 최적화가 켜져 있지 않은 경우).
#define
단순히 이름을 값으로 대체합니다. 또한 #define
'd 상수는 전 처리기에서 사용될 수 있습니다. #ifdef
값을 기준으로 조건부 컴파일을 수행하기 위해 함께 사용하거나 문자열 화 연산자 #
를 사용하여 값 이있는 문자열을 가져올 수 있습니다. 컴파일러는 컴파일 시간에 그 값을 알고 있으므로 해당 값을 기반으로 코드를 최적화 할 수 있습니다.
예를 들면 :
#define SCALE 1
...
scaled_x = x * SCALE;
를 컴파일러 SCALE
로 정의 1
하면 곱셈을 제거 할 수 x * 1 == x
있지만 SCALE
( extern
) const
이면 연결 단계까지 값을 알 수 없기 때문에 값을 가져와 곱셈을 수행하는 코드를 생성해야합니다. ( extern
여러 소스 파일의 상수를 사용하려면 필요합니다.)
using에 더 가까운 #define
것은 열거 를 사용하는 것 입니다.
enum dummy_enum {
constant_value = 10010
};
그러나 이것은 정수 값으로 제한되고의 장점 #define
이 없으므로 널리 사용되지 않습니다.
const
컴파일 된 라이브러리에서 상수 값을 가져와야 할 때 유용합니다. 또는 포인터와 함께 사용되는 경우. 또는 변수 인덱스 값을 통해 액세스되는 상수 값의 배열 인 경우. 그렇지 않으면, const
어떤 장점이 이상이 없습니다 #define
.
그 이유는 대부분의 경우 const
정규화 된 변수가 아닌 상수를 원하기 때문 입니다. 둘은 C 언어에서 원격으로 동일하지 않습니다. 예를 들어 변수는 static
vla가 아닌 배열 차원 (예 : 구조의 배열 크기 또는 C99 이전의 모든 배열)과 같이 -storage-duration 객체에 대한 이니셜 라이저의 일부로 유효하지 않습니다 .
R의 대답을 조금 확장 fieldWidth
하면 상수 표현 이 아닙니다 . 그것은이다 const
restrict로 변수입니다. 이 값 은 런타임까지 설정되지 않으므로 컴파일 타임 상수식이 필요한 경우 (예 : 배열 선언 또는 switch
명령문 의 케이스 레이블 등)에 사용할 수 없습니다.
매크로와 비교하면 FIELD_WIDTH
, 전처리 후 상수 표현식으로 확장됩니다 10
. 이 값 은 컴파일 타임에 알려 지므로 배열 차원, 케이스 레이블 등에 사용할 수 있습니다.
R.와 Bart의 대답에 추가하려면 C에서 심볼릭 컴파일 시간 상수를 정의하는 유일한 방법이 있습니다 : 열거 형 상수. 표준은 이것들이 유형임을 강요합니다 int
. 나는 개인적으로 당신의 예를 다음과 같이 쓸 것입니다
enum { fieldWidth = 10 };
그러나 나는 그것에 대해 C 프로그래머들 사이에서 맛이 많이 다르다고 생각합니다.
const int가 항상 적절한 것은 아니지만, 어떤 것을 정수 값으로 정의하는 경우 열거 형은 일반적으로 #define 대신 사용할 수 있습니다. 이것은 실제로 그러한 경우에 내가 선호하는 것입니다.
enum { FIELD_WIDTH = 16384 };
char buf[FIELD_WIDTH];
C ++에서는 클래스 또는 네임 스페이스에서 열거 형의 범위를 지정할 수 있지만 #define의 범위를 지정할 수 없기 때문에 이것은 큰 이점입니다.
In C you don't have namespaces and cannot scope an enum inside a struct, and am not even sure you get the type-safety, so I cannot actually see any major advantage, although maybe some C programmer there will point it out to me.
According to K&R (2nd edition, page 211) the "const and volatile properties are new with the ANSI standard". This may imply that really old ANSI code did not have these keywords at all and it really is just a matter of tradition. Moreover, it says that a compiler should detect attempts to change const variables but other than that it may ignore these qualifiers. I think it means that some compilers may not optimize code containing const variable to be represented as intermediate value in machine code (like #define does) and this might cost in additional time for accessing far memory and affect performance.
Some C compilers will store all const
variables in the binary, which if preparing a large list of coefficients can use up a tremendous amount of space in the embedded world.
Conversely: using const
allows flashing over an existing program to alter specific parameters.
The best way to define numeric constants in C is using enum. Read the corresponding chapter of K&R's The C Programming Language, page 39.
참고URL : https://stackoverflow.com/questions/4024318/why-do-most-c-developers-use-define-instead-of-const
'Programing' 카테고리의 다른 글
Windows 컴퓨터에서 my.cnf를 찾을 수 없습니다. (0) | 2020.09.05 |
---|---|
base64의 문자열을 이미지로 변환하고 Python의 파일 시스템에 저장 (0) | 2020.09.05 |
POST Content-Length가 제한을 초과했습니다. (0) | 2020.09.05 |
Android 4.0 이상용 외부 SD 카드 경로는 어떻게 얻을 수 있습니까? (0) | 2020.09.05 |
정수 해시 키를 허용하는 정수 해시 함수는 무엇입니까? (0) | 2020.09.05 |