programing

*(긴*)0=0; 이 문장의 기능은 무엇입니까?

newstyles 2023. 10. 31. 20:35

*(긴*)0=0; 이 문장의 기능은 무엇입니까?

다음 코드에서,*(long*)0=0;와 함께 사용됩니다.if조항, 하지만 그것의 목적은 무엇일까요?

if(r.wid*r.ht < tot)
    *(long*)0=0;

0에서 0으로 적습니다. A의 주소로 해석됩니다.long, 예를 들면NULL포인팅합니다.그건 타당한 일이 아닙니다.NULL는 프로그램이 액세스할 수 있는 데이터를 유효하게 가질 수 있는 주소가 아닙니다.이 코드는 정의되지 않은 동작을 트리거하므로 일반적으로 특정 효과를 얻기 위해서는 이 코드를 사용할 수 없습니다.

그러나 종종 이와 같은 코드는 분할 오류 유형 충돌을 강제로 수행하는 데 사용되며, 디버거에 저장하는 것이 편리하기도 합니다.

다시 말하지만, 이는 정의되지 않은 동작입니다. 이러한 오류가 발생한다는 보장은 없지만, 분할 오류가 있는 시스템에서는 위 코드가 오류를 발생시킬 가능성이 높습니다.다른 시스템에서는 완전히 다른 작업을 수행할 수도 있습니다.

segfault가 발생한 경우 디버거에서 중단점을 수동으로 설정하는 것보다 이런 방식으로 segfault를 트리거하는 것이 더 편리할 수 있습니다.예를 들어 IDE를 사용하지 않는 경우 디버거에 (텍스트적인) 명령을 내리는 것보다 원하는 위치의 코드에 이러한 몇 개의 토큰을 입력하는 것이 더 쉬운 경우가 많은데, 이는 정확한 소스 코드 파일과 라인 번호를 수동으로 지정하는 것이 약간 귀찮을 수 있습니다.

C교과서에서는,abort의도적으로 프로그램을 중단시키는 방법입니다.하지만 메탈에 가까운 프로그래밍을 할 때는 다음의 가능성을 걱정해야 할 수도 있습니다.abort의도한 대로 작동하지 않음!표준 POSIXy 구현:abort부름getpid그리고.kill( 경유)raise)을 배달합니다SIGABRT프로세스에 적용할 수 있습니다. 이는 결국 신호 핸들러의 실행을 야기할 수 있고, 이는 원하는 대로 할 수 있습니다.상황이 있습니다. 예를 들어 의 깊은 곳에 있습니다.malloc, 스택을 전혀 건드리지 않고(specif적으로 반환 명령을 실행하지 않고 악성 코드로 점프할 수 있는) 충돌을 강제로 수행해야 하는 치명적인 advers라리 메모리 손상에 대응합니다.*(long *)0 = 0그런 상황에서 시도하는 것은 가장 미친 짓이 아닙니다.신호 처리기를 실행할 위험이 여전히 있지만, 이는 피할 수 없습니다. 트리거할 방법이 없습니다.SIGKILL전화를 하지 않고도 말입니다.좀 더 심각한 것은 IMHO(현대 컴파일러)는 정의되지 않은 동작을 가지고 있음을 관찰하고 삭제한 후 테스트를 삭제할 가능성이 있습니다. 테스트가 결코 사실일 수 없기 때문입니다. 아무도 의도적으로 정의되지 않은 동작을 호출하지 않을 것이기 때문이죠?이런 종류의 논리가 비뚤어져 보인다면, LLVM 그룹의 정의되지 않은 행동과 최적화에 대한 담론을 읽어보기 바랍니다(2부, 3부).

이 목표를 달성하기 위한 더 좋은 방법들이 있습니다.오늘날 많은 컴파일러들은 하드웨어 결함과 전달을 야기할 것이 보장되는 기계 명령을 생성하는 고유한 (예를 들어, gcc, clang: )을 가지고 있습니다.SIGILL; 포인터를 사용하는 정의되지 않은 트릭과는 달리 컴파일러는 이를 최적화하지 않습니다.컴파일러에 해당 명령어가 없지만 어셈블리 삽입어가 있는 경우 수동으로 이러한 명령어를 삽입할 수 있습니다. 이 명령어는 기계 의존성의 추가 비트가 큰 문제가 되지 않을 만큼 충분히 낮은 수준의 코드일 수 있습니다.아니면, 그냥 전화를 해서_exit. 이것은 신호 처리기를 실행할 위험이 없고 내부적으로도 기능 반환을 수반하지 않기 때문에 거의 틀림없이 가장 안전한 재생 방법입니다.하지만 핵심 쓰레기는 없다는 뜻입니다.

프로그램을 '비정상적으로 종료'하려면abort()function (http://pubs.opengroup.org/onlinepubs/9699919799/functions/abort.html) .

"조건 X가 참이 아니면 프로그램을 비정상적으로 종료시킨다"는 C/C++ 관용어가 표준입니다.assert()macro. 위의 코드는 다음과 같이 작성하는 것이 좋습니다.

assert( !(r.wid*r.ht < tot) );

또는(엣지 케이스를 무시하고 싶을 경우) 다음과 같이 더 명확하게 읽힙니다.

assert( r.wid*r.ht >= tot );

r의 너비 곱하기 높이가 합계보다 작으면 프로그램을 충돌시킵니다.

언급URL : https://stackoverflow.com/questions/21376602/what-is-the-function-of-this-statement-long0-0