2009-03-04 2 views
6

페이지 하단의 here에서이 견적을 확인하십시오. consts 할 반면, 그들은 최종 출력 개체/라이브러리/실행의 모든 ​​공간 을 소모하지 않는const vs enum in D

열거는 점에서 consts 다르다 (나는 약 constinvariant의도에 적용되는 인용 코멘트를 믿는다). value2가 리터럴로 취급되고, 오브젝트 파일에 나타나지 않는 동안

그래서 분명히 value1는 실행 파일을 부풀게합니다.
const int value1 = 0xBAD; 
enum int value2 = 42; 

돌아 가기 C++에서 나는 항상이 상수를 최적화 할 수없는 레거시 이유, 오래된 컴파일러했다 추측했다. 그러나 이것이 D에서 여전히 사실이라면, 이것의 뒤에 더 깊은 이유가 있어야합니다. 왜 그런지 알아?

답변

4

는 D에서 열거는 "문자 그대로 보존 된 정수"것으로 보인다 (또한 2.0이 아직 완료되지 않은 것을 명심) (편집 : 놀라운, D2도 floats and strings 지원). 열거 자에는 위치가 없습니다. 그들은 정체성이없는 가치로서 중요하지 않습니다.

enum은 D2에 새로 추가되었습니다. 먼저 새 변수를 정의합니다. 그것은 lvalue가 아닙니다 (그래서 당신은 또한 주소를 취할 수 없습니다). 난 내 가난한 D 지식을 신뢰할 수있는 경우

enum int a = 10; // new in D2 

enum : int { a = 10 } 

같다. 따라서 여기에 a은 lvalue가 아닙니다 (위치가없고 주소를 가져올 수 없습니다). 그러나 const는 이고 주소는입니다. 전역 변수 (올바른 D 언어인지 여부는 모르지만) const 변수가있는 경우 컴파일러는 일반적으로 변수를 액세스 할 수있는 모듈이나 해당 주소를 사용할 수 있는지 모르기 때문에이를 최적화 할 수 없습니다. 그래서 스토리지를 할당해야합니다.

당신이 로컬 const를 가지고 있다면 컴파일러는 누군가의 주소에 관심이 있는지 아니면 모두가 가치를 지는지 여부를보고 컴파일러가 그 범위를보고 알기 때문에 C++ 에서처럼 멀리 떨어져서 최적화 할 수 있다고 생각합니다. .

1

enum 값이 표현식에서 "인라인"으로 사용되는 것처럼 들린다. const에서 실제로 저장소를 사용하고 참조하는 표현식이 메모리 저장소에서 값을로드합니다.

이 소리는 C#의 const와 readonly의 차이점과 비슷합니다. 전자는 컴파일 타임 상수이고 나중에는 런타임 상수입니다. 이것은 어셈블리의 버전 관리에 영향을주었습니다 (읽기 전용을 참조하는 어셈블리는 컴파일 할 때 사본을 받고 참조 된 어셈블리가 다른 값으로 다시 작성된 경우 값을 변경하지 못합니다).

3

저는 좋은 컴파일러/링커가 상수를 제거해야한다고 생각합니다. 열거 형을 사용하면 실제로 스펙에서 보장됩니다. 차이점은 주로 의미론의 문제입니다.

그냥 C++에서 같은
+1

그러나 컴파일러는 항상 모든 관련 소스를 가지고 있다고 가정합니다. – larsivi

+0

타사 라이브러리에 해당 const 변수에 대한 액세스 권한을 부여하려면 어떻게합니까? 그것이 const로 만들어진 전체 클래스 인스턴스라면? – Marenz

+0

참고 "컴파일러/* 링커 *". 게다가 D는 어쨌든 컴파일 타임에 변수의 값을 볼 수 있어야합니다 (상수 폴딩과 다른 것들을 위해서), 어딘가에 물리적으로 저장하는 것이 더 적습니다. - 소스가 필요한 상황 어쨌든 가능합니다. (나는 이전에 객체 코드를 내부적으로 분해하는 컴파일러에 대해서는 잘 모르고있다.) – FeepingCreature

4

실제 질문; 왜 enum/const는 C++ 에서처럼 D에서 동일합니다; 대답이없는 것처럼 보입니다. 슬프게도이 선택에 대한 정당한 이유가 전혀 없습니다. 저는 이것이 C++의 의도하지 않은 부작용이었고 사실상의 패턴이되었다고 생각합니다.D에서 동일한 패턴이 필요했고 Walter Bright는 C++에서와 같이 수행해야한다는 결론을 내 렸습니다. 그 장소에서 들어오는 사람들이 무엇을 해야할지 인식 할 수있었습니다 ... 사실,이 IMHO 바보 같이 결정하기 전에 키워드 매니페스트가 사용되었습니다 이 유즈 케이스에 대한 enum 대신.

+2

'enum'은 manifest 상수를 의미하는 불행한 일이다. 그러나 D는 명시 적으로 손상된 부분을 변경하는 것만을 강조하며 나머지는 모두 algol 언어의 확립 된 규범을 따릅니다. 만약 당신이 정말로 모두 나가면 확실하게 할 수있는 이상한 키워드와 구문을 발견 할 수 있습니다. 예를 들어 할당/동등성, 함수 이름 앞에 나열된 반환 값, 구조/집계 등 –

2

012MP의 실제 목적은 단일 매니페스트 상수를 지원하기 위해 구문 상으로 확장되었는데, 내가 이해하는 바로는 D 템플릿 전문가 인 Don Clugston이 템플릿으로 미친 짓을하고 있다는 것입니다. 컴파일러가 const 변수에 대한 내부 데이터 구조 생성을 계속했기 때문에 그는 오랜 빌드 시간, 어리석은 컴파일러 메모리 사용 등으로 계속 실행되었습니다. 열거 형에 비해 const/immutable 변수에 대한 핵심 사항 중 하나는 const/immutable 변수가 lvalues이며 해당 주소를 사용할 수 있다는 것입니다. 이는 컴파일러에 약간의 오버 헤드가 있음을 의미합니다. 이것은 대개 중요하지 않지만, 컴파일 타임 메타 프로 그램을 매우 복잡하게 실행하면 const 변수가 최적화 되어도 컴파일 타임에 상당한 오버 헤드가 발생합니다.