[c] 이 소스 코드는 C에서 문자열을 켜고 있습니다. 어떻게 그렇게합니까?

나는 일부 에뮬레이터 코드를 읽고 있으며 정말 이상한 것을 반박했습니다.

switch (reg){
    case 'eax':
    /* and so on*/
}

이것이 어떻게 가능한지? 나는 당신이 switch정수형 에서만 할 수 있다고 생각했습니다 . 매크로 속임수가 진행되고 있습니까?



답변

(더 많은 코드를 붙여 넣지 않는 한 “매크로 속임수”부분에 대해서만 답할 수 있습니다.하지만 여기에는 매크로가 작동 할 것이 많지 않습니다. 공식적으로는 키워드 를 재정의 할 수 없습니다. . 그 동작은 정의되지 않았습니다.)

프로그램 가독성을 얻기 위해 재치있는 개발자는 구현 정의 동작을 이용 합니다. 'eax'입니다 하지 문자열하지만, 멀티 문자 상수 . 주위의 작은 따옴표 문자를 매우주의하여주의하십시오 eax. 대부분 int의 경우 해당 문자 조합에 고유 한 케이스를 제공합니다 . (매우 자주 각 문자는 32 비트에서 8 비트를 차지합니다 int.) 그리고 모두는 당신 switchint !

마지막으로 표준 참조 :

C99 표준은 다음과 같이 말합니다.

6.4.4.4p10 : “두 개 이상의 문자 (예 : ‘ab’)를 포함하거나 단일 바이트 실행 문자에 매핑되지 않는 문자 또는 이스케이프 시퀀스를 포함하는 정수 문자 상수의 값은 구현에서 정의됩니다. “


답변

C 표준 (6.8.4.2 스위치 문)에 따름

3 각 케이스 라벨의 표현은 정수 상수 표현이어야합니다 .

및 (6.6 상수 표현식)

6 정수 상수 표현식 은 정수 유형을 가져야하며 정수 상수 인 피연산자, 열거 상수,
문자 상수 , 결과가 정수 상수 인 표현식의 크기 및 캐스트의 직접적인 피연산자 인 부동 상수 만 있어야합니다. 정수 상수 표현식의 캐스트 연산자는 sizeof 연산자에 대한 피연산자의 일부를 제외하고 산술 유형을 정수 유형으로 만 변환해야합니다.

이제 무엇입니까 'eax' 입니까?

C 표준 (6.4.4.4 문자 상수)

2 정수 문자 상수는 ‘x’에서와 같이 작은 따옴표로 묶인 하나 이상의 멀티 바이트 문자 시퀀스입니다 .

따라서 'eax'같은 섹션의 단락 10에 따른 정수 문자 상수입니다.

  1. … 두 개 이상의 문자 (예 : ‘ab’)를 포함하거나 단일 바이트 실행 문자에 매핑되지 않는 문자 또는 이스케이프 시퀀스를 포함하는 정수 문자 상수의 값은 구현에서 정의됩니다.

따라서 처음 언급 한 인용문에 따르면 케이스 레이블로 사용할 수있는 정수 상수 표현식의 피연산자가 될 수 있습니다.

문자 상수 (작은 따옴표로 묶인)에는 int유형이 있고 문자 배열 유형을 갖는 문자열 리터럴 (큰 따옴표로 묶인 일련의 문자)과 동일하지 않습니다.


답변

다른 사람들이 말했듯이 이것은 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':
       ...
    ...
}

이건 너무 좋아 보이지 않습니까?

“구현 정의”의 좋은 점은 프로그래머가 컴파일러의 문서를 확인하고 이러한 상수로 적절한 작업을 수행하는지 확인할 수 있다는 것입니다. 그렇다면 집은 무료입니다.

나쁜 부분은 다른 가난한 사람이 코드를 가져와 다른 컴파일러를 사용하여 컴파일하려고 할 수 있다는 것입니다. 인스턴트 컴파일 오류. 이 프로그램은 이식성이 없습니다.

@zwol이 주석에서 지적했듯이 상황은 생각만큼 나쁘지 않으며 나쁜 경우 코드가 컴파일되지 않습니다. 이것은 적어도 문제에 대한 정확한 파일 이름과 줄 번호를 제공합니다. 그래도 작동하는 프로그램이 없습니다.


답변

코드 조각은 multi-chars 라고도하는 다중 문자 문자 상수 라는 역사적 특이성을 사용합니다 .

'eax' 값이 구현 정의 된 정수 상수입니다.

다음은 다중 문자에 대한 흥미로운 페이지이며 사용 방법은 있지만 사용해서는 안됩니다.

http://www.zipcon.net/~swhite/docs/computers/languages/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 인 문자 상수는 하위 바이트의 첫 번째 문자에 대한 코드와 상위 바이트의 두 번째 문자에 대한 코드를 갖습니다. 둘 이상의 문자가있는 문자 상수는 본질적으로 기계에 따라 다르므로 피해야합니다.

마지막 문구는이 흥미로운 구성에 대해 기억해야 할 모든 것 입니다. 둘 이상의 문자가있는 문자 상수는 본질적으로 기계에 따라 다르므로 피해야합니다.


답변