*(긴*)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
'programing' 카테고리의 다른 글
C 또는 C++에서 A 플러그인 시스템 구현 (0) | 2023.10.31 |
---|---|
Get-ChildItem 결과에서 항목 목록을 제외하는 방법은 무엇입니까? (0) | 2023.10.31 |
신뢰할 수 없는(자체 서명된) HTTPS에 대한 AJAX 호출이 자동으로 실패함 (0) | 2023.10.31 |
MySQL: OR 없이 colIN(null, "")이 가능한 테이블에서 *를 선택합니다. (0) | 2023.10.31 |
멀티 테넌트 장고 애플리케이션: 요청당 데이터베이스 연결 변경? (0) | 2023.10.31 |