programing

char가 서명된 경우 "char foo = 255"가 정의되지 않은 동작입니까?

closeapi 2023. 8. 9. 20:45
반응형

char가 서명된 경우 "char foo = 255"가 정의되지 않은 동작입니까?

Linux가 설치된 x86 시스템에서 gcc 4.5.2로 컴파일할 때 다음과 같은 경고가 표시되지 않습니다.

char foo = 255;

하지만 사용할 때-pedanticgcc는 다음을 말합니다.

경고: 암시적 상수 변환의 오버플로

gcc가 하는 행동이 좀 이상하고 이 과제에서 무슨 일이 일어나고 있는지 정말 이해하는지 의심스럽습니다.내 생각에 만약에charPOSIX의 길이는 8비트이며 기본적으로 서명되어 있으므로 유지할 수 없습니다.255.

C 표준에서는 부호 없는 정수 오버플로로 인해 오버플로가 발생한다고 하지만 부호 있는 정수 오버플로는 정의되어 있지 않습니다.그럼 이 과제는 정의되지 않은 행동인가요?그리고 gcc는 왜 이런 식으로 행동합니까?

요약:.결과적으로 구현이 정의되고 가능성이 매우 높습니다.-1하지만 적어도 원칙적으로는 복잡합니다.

오버플로 관련 규칙은 연산자 대 변환, 서명된 유형 대 서명되지 않은 유형에 따라 다르며 변환 규칙은 C90과 C99 사이에서 변경되었습니다.

C90을 기준으로, 부호 있는 정수 피연산자를 가진 연산자의 오버플로("overflow"는 수학적 결과를 표현할 수 없음을 의미함)는 정의되지 않은 동작을 가집니다.부호 없는 정수 피연산자의 경우 동작이 일반적인 랩어라운드로 잘 정의됩니다(엄밀하게 말하면 표준에서는 이를 "오버플로"라고 부르지 않습니다).하지만 당신의 선언은:

char foo = 255;

연산자를 사용하지 않습니다.=이 경우에는 할당이 아닌 이니셜라이저입니다.

If 유형char값을 나타낼 수 있습니다.255(일반적으로 사실인 것은 사실입니다.char서명되지 않았거나 다음과 같은 경우CHAR_BIT >= 9), 그러면 당연히 행동은 잘 정의됩니다.int표현255은(는) 은(는) 으로 변환됩니다.char(이후CHAR_BIT >= 8이 경우 서명되지 않은 랩어라운드를 호출할 수 없습니다.)

그렇지 않으면 변환을 통해 다음에 저장할 수 없는 결과가 생성됩니다.char.

C90 기준으로 변환 결과는 구현 정의입니다. 즉, 설정이 보장됩니다.foo활자의 범위 내에서 어느 정도의 으로.char변환 방법을 알려주는 데 필요한 구현의 설명서를 읽어보면 이 값이 무엇인지 확인할 수 있습니다. (저장된 값이 다른 값인 구현은 본 적이 없습니다.)-1그러나 원칙적으로 어떤 결과도 가능합니다.)

C99는 정의를 변경하여 서명된 유형으로 과도하게 변환하면 구현 정의 결과가 산출되거나 구현 정의 신호가 발생합니다.

컴파일러가 후자를 선택하면 어떤 신호가 발생하는지 문서화해야 합니다.

그러면 구현 정의 신호가 발생하면 어떻게 될까요?이 표준의 섹션 7.14는 다음과 같습니다.

신호의 전체 집합, 신호의 의미 및 기본 처리는 구현 정의됩니다.

신호의 "기본 처리"에 대한 가능한 동작 범위가 (나에게) 완전히 명확하지는 않습니다.최악의 경우, 저는 그러한 신호가 프로그램을 종료시킬 수 있다고 생각합니다.신호를 포착하는 신호 핸들러를 정의할 수도 있고 정의할 수도 없습니다.

7.14는 또한 다음과 같이 말합니다.

함수가 반환되는 경우, 시그의 값이 SIGFPE, SIGILL, SIGSEGV 또는 계산 예외에 해당하는 다른 구현 정의 값이면 동작이 정의되지 않습니다. 그렇지 않으면 프로그램은 중단된 지점에서 실행을 다시 시작합니다.

그러나 오버플로우 변환은 여기서 사용되는 용어처럼 "계산 예외"가 아니기 때문에 적용되지 않는다고 생각합니다. (실행 정의 신호가 발생하지 않는 한)SIGFPE,SIGILL또는SIGSEGV하지만 그것은 어리석을 것입니다).

따라서 궁극적으로, 구현이 과도한 변환에 대응하여 신호를 발생시키기로 선택하는 경우, (결과뿐만 아니라) 동작은 적어도 구현이 정의되며, 정의되지 않을 수 있는 상황이 있을 수 있습니다.어쨌든, 그러한 신호를 다룰 수 있는 휴대용 방법은 없는 것 같습니다.

실제로, 저는 C99의 새로운 표현을 활용하는 구현에 대해 들어본 적이 없습니다.제가 들어본 모든 컴파일러들에게, 변환의 결과는 구현이 정의되어 있습니다. 그리고 아마도 여러분이 2의 보완적인 절단에서 기대할 수 있는 것을 산출할 것입니다. (그리고 저는 C99의 이 변화가 좋은 아이디어라고 전혀 확신하지 못합니다.)다른 것이 없다면, 그것은 필요했던 것보다 약 3배 더 오래 이 대답을 했습니다.)

부호 있는 정수 오버플로는 이진 변이, 단항 감소 등과 같이 산술 표현식의 중간 결과를 평가할 때만 정의되지 않은 동작을 발생시킵니다.또한 부동 소수점 값을 정수 유형으로 변환하면 값이 범위를 벗어나는 경우 정의되지 않은 동작이 발생합니다.

서명된 형식으로 오버플로 정수 변환해도 정의되지 않은 동작이 발생하지 않습니다.대신 구현 정의 결과를 생성합니다(구현 정의 신호가 발생할 가능성이 있음).

C11, 6.3.1.3에 따라:

정수 유형의 값이 다음과 같은 다른 정수 유형으로 변환되는 경우_Bool[...] 새 유형이 서명되었지만 값을 표시할 수 없는 경우, 결과가 구현 정의 신호이거나 구현 정의 신호가 발생합니다.

언급URL : https://stackoverflow.com/questions/18922601/is-char-foo-255-undefined-behavior-if-char-is-signed

반응형