이 소스 코드는 C의 문자열을 켜고 있습니다.어떻게 그럴 수 있죠?
에뮬레이터 코드를 읽다가 정말 이상한 걸 맞췄어요
switch (reg){
case 'eax':
/* and so on*/
}
이것이 어떻게 가능한 걸까요?할 수 있을 줄 알았는데switch필수 유형으로.무슨 거시적인 속임수라도 있는 거야?
(더 많은 코드를 붙여넣지 않는 한 "매크로 속임수" 부분에 응답할 수 있습니다.그러나 여기에는 매크로가 작업해야 할 것이 많지 않습니다.정식적으로는 키워드를 재정의할 수 없습니다.그 동작은 정의되어 있지 않습니다.)
프로그램의 가독성을 달성하기 위해서, 위트 있는 개발자는 실장 정의의 동작을 이용하고 있습니다. 'eax'는 문자열이 아니라 다중 문자 상수입니다.주위에 작은 따옴표가 있는 것에 주의해 주세요.eax가장 가능성이 높은 것은 아마도int당신의 경우, 그것은 그 조합의 캐릭터들만의 독특한 것입니다.(각 문자가 32비트로 8비트를 차지하는 경우가 많습니다).int그리고 모두가 알고 있습니다.switch을 타고int!
마지막으로 표준 참조:
C99 표준은 다음과 같습니다.
6.4.4p10: "여러 문자(예: 'ab')를 포함하는 정수 문자 상수 값 또는 단일 바이트 실행 문자에 매핑되지 않는 문자 또는 이스케이프 시퀀스를 포함하는 값은 구현 정의됩니다."
C 표준 (6.8.4.2 스위치 문)에 의거하여
3 각 케이스 라벨의 표현은 정수 상수 표현이어야 한다.
(6.6 상수 표현)
6 정수식은 정수형이어야 하며 정수형, 열거상수, 문자상수, 정수상수인 식 크기 및 주조물의 직접 피연산자인 부동상수만을 가져야 한다.정수 상수식의 주조 연산자는 연산자 크기에 대한 피연산자의 일부를 제외하고 연산자 유형을 정수 형식으로만 변환해야 합니다.
자, 이제 무엇이냐?'eax'?
C 표준(6.4.4.4 문자 상수)
2 정수 문자 상수는 'x'와 같이 단일 따옴표로 둘러싸인 하나 이상의 다중 바이트 문자 시퀀스입니다.
그렇게'eax'같은 섹션의 10항에 따른 정수 문자 상수입니다.
- ...여러 개의 문자(예: 'ab')를 포함하거나 단일 바이트 실행 문자에 매핑되지 않는 문자 또는 이스케이프 시퀀스를 포함하는 정수 문자 상수 값은 구현 정의됩니다.
따라서 첫 번째 인용문에 따르면 대/소문자 레이블로 사용할 수 있는 정수 상수식의 피연산자일 수 있습니다.
문자 상수(작은 따옴표로 묶음)에는 유형이 있습니다.int는, 문자 배열의 타입을 가지는 문자열 리터럴(큰따옴표로 둘러싸인 일련의 문자)과는 다릅니다.
코드 프래그먼트에서는, 멀티 문자 상수라고 불리는 이력 홀수(멀티 문자라고도 불립니다)가 사용됩니다.
'eax'는 구현이 정의되어 있는 정수 상수입니다.
다음은 멀티캐릭터에 관한 흥미로운 페이지와 멀티캐릭터의 사용방법 및 사용방법에 대한 설명입니다.
http://www.zipcon.net/~swhite/swhite/computers/swhite/c_multi-char_const.html
백미러를 더 자세히 들여다보면 옛날 Dennis Ritchie의 오리지널 C 매뉴얼(https://www.bell-labs.com/usr/dmr/www/cman.pdf)에서 문자 상수를 지정하는 방법을 소개합니다.
2.3.2 문자 상수
문자 상수는 작은 따옴표 '로 둘러싸인 1 또는 2자입니다.
''.' 문자 상수 내에서 단일 따옴표 앞에 백슬래시 '가 와야 합니다.\'.' 특정 그래픽이 아닌 문자 및 '\" 자체는 다음 표에 따라 이스케이프할 수 있습니다.BS \b NL \n CR \r HT \t ddd \ddd \ \\탈옥 '
\ddd"는 백슬래시 뒤에 1, 2, 또는3의 8진수로 구성됩니다.이 숫자는 원하는 문자의 값을 지정하기 위해 사용됩니다.이 구조의 특별한 사례는 다음과 같습니다.\0(숫자 뒤에 숫자가 붙지 않음)은 늘 문자를 나타냅니다.문자 상수는 정수와 똑같이 동작합니다(특히 문자 유형의 개체와는 다릅니다).PDP-11의 어드레싱 구조에 따라 길이 1의 문자 상수는 하위 바이트에 소정의 문자를 위한 코드를, 상위 바이트에 0을 가지며, 길이 2의 문자 상수는 하위 바이트에 제1 문자를 위한 코드를 가진다.여러 문자를 가진 문자 상수는 본질적으로 기계에 의존하므로 피해야 합니다.
마지막 문구는 이 신기한 구조에 대해 기억해야 할 것입니다.여러 문자를 가진 문자 상수는 본질적으로 기계에 의존하므로 피해야 합니다.
다른 사람들이 말했듯이, 이것은int상수와 그 실제 가치는 구현에 정의됩니다.
나머지 코드들은 마치...
if (SOMETHING)
reg='eax';
...
switch (reg){
case 'eax':
/* and so on*/
}
앞부분의 'eax'와 뒷부분의 'eax'의 값이 같다는 것을 알 수 있기 때문에 모든 것이 잘 풀리지 않습니까? ...틀렸습니다.
주석 @Davislor에서 'eax'에 대해 가능한 몇 가지 값을 나열합니다.
...
0x65,0x656178,0x65617800,0x786165,0x6165또는 다른 것
첫 번째 잠재적 값을 알아채셨나요?그건 그냥'e'나머지 두 문자는 무시합니다.문제는 이 프로그램이 아마도'eax','ebx'기타 등등.이 모든 상수가 다음과 같은 값을 갖는 경우'e'결국 에 이르게 된다.
switch (reg){
case 'e':
...
case 'e':
...
...
}
별로 좋아 보이지 않죠?
「실장 정의」의 장점은, 프로그래머가 컴파일러의 문서를 체크해, 이러한 상수에 대해서 합리적인 것을 실행할 수 있는지를 확인할 수 있는 것입니다.만약 그렇다면, 집에는 공짜입니다.
단점은 다른 불쌍한 사람이 다른 컴파일러를 사용하여 코드를 컴파일하려고 할 수 있다는 것입니다.인스턴트 컴파일 오류입니다.프로그램은 노트북이 아니다.
@zwoon이 댓글로 지적한 것처럼, 생각했던 것만큼 나쁜 경우는 코드가 컴파일 되지 않습니다.이것에 의해, 적어도 문제의 정확한 파일명과 행 번호를 알 수 있습니다.그러나, 당신은 작업 프로그램을 가지고 있지 않을 것입니다.
언급URL : https://stackoverflow.com/questions/45550674/this-source-code-is-switching-on-a-string-in-c-how-does-it-do-that
'source' 카테고리의 다른 글
| Vue 앱에서 v-show를 사용한 입력에 대한 사용자 지정 지시 v-focus (0) | 2022.07.31 |
|---|---|
| org.hibernate.최대 절전 모드예외:DialectResolution에 접근때 'hibernate.dialect'설정하지 않정보가 null이 될 수 없다. (0) | 2022.07.31 |
| CMake 아래에 있는 여러 디렉토리 (0) | 2022.07.30 |
| Java에서 주석의 사용방법과 사용처 (0) | 2022.07.30 |
| Java를 사용한 DOM 구문 분석의 정규화 - 어떻게 작동합니까? (0) | 2022.07.30 |