런타임 코드 수정의 현명한 사례가 있습니까?


119

런타임 코드 수정 (런타임에 자체 코드를 수정하는 프로그램)에 대한 합법적 인 (스마트 한) 사용을 생각할 수 있습니까?

최신 운영 체제는 바이러스가 탐지를 피하기 위해이 기술을 사용했기 때문에이를 수행하는 프로그램을 눈살을 찌푸리는 것처럼 보입니다.

내가 생각할 수있는 것은 컴파일 타임에 알 수없는 무언가를 런타임에 알고 일부 코드를 제거하거나 추가하는 일종의 런타임 최적화입니다.


8
현대 아키텍처에서는 캐싱 및 명령어 파이프 라인을 심하게 방해합니다. 자체 수정 코드는 결국 캐시를 수정하지 않으므로 장벽이 필요하며 이로 인해 코드가 느려질 수 있습니다. 그리고 이미 명령 파이프 라인에있는 코드는 수정할 수 없습니다. 따라서 자체 수정 코드를 기반으로하는 모든 최적화는 코드가 실행되기 전에 실행되어야 성능에 미치는 영향이 런타임 검사보다 우수합니다.
Alexandre C.

7
@Alexandre :자가 수정 코드가 임의의 횟수로 실행 되었음에도 불구하고 거의 (예 : 한 번, 두 번) 수정하는 것이 일반적이므로 일회성 비용이 미미할 수 있습니다.
Tony Delroy 2011

7
이것에 대한 메커니즘이 없기 때문에 왜 이것이 C 또는 C ++ 태그인지 확실하지 않습니다.
MSalters 2011

4
@Alexandre : 마이크로 소프트 오피스는 정확히 그렇게하는 것으로 알려져 있습니다. 결과적으로 (?) 모든 x86 프로세서는 자체 수정 코드를 훌륭하게 지원합니다. 다른 프로세서에서는 비용이 많이 드는 동기화가 필요하므로 전체가 덜 매력적입니다.
Mackie Messer 2011

3
@Cawas : 일반적으로 자동 업데이트 소프트웨어는 새 어셈블리 및 / 또는 실행 파일을 다운로드하고 기존 어셈블리를 덮어 씁니다. 그런 다음 소프트웨어를 다시 시작합니다. 이것이 파이어 폭스, 어도비 등이하는 일입니다. 자체 수정은 일반적으로 런타임 중에 일부 매개 변수로 인해 애플리케이션이 메모리에 코드를 다시 작성하고 반드시 디스크에 다시 유지되지 않음을 의미합니다. 예를 들어, 실행 속도를 높이기 위해 특정 실행 중에 실행되지 않는 경로를 지능적으로 감지 할 수있는 경우 전체 코드 경로를 최적화 할 수 있습니다.
NotMe

답변:


117

코드 수정에 대한 유효한 경우가 많이 있습니다. 런타임에 코드를 생성하면 다음과 같은 경우에 유용 할 수 있습니다.

  • 일부 가상 머신은 JIT 컴파일 을 사용하여 성능을 향상시킵니다.
  • 컴퓨터 그래픽에서는 오랫동안 특수 기능 을 즉시 생성 하는 것이 일반적이었습니다. 예를 들어 Rob Pike와 Bart Locanthi, John Reiser Hardware Software Tradeoffs for Bitmap Graphics on the Blit (1984) 또는 Chris Lattner 의이 게시물 (2006) 에서 OpenGL 스택의 런타임 코드 전문화를 위해 LLVM을 사용하는 Apple을 참조하십시오.
  • 경우에 따라 소프트웨어 는 스택 (또는 다른 위치)에서 코드를 동적으로 생성하는 트램폴린으로 알려진 기술 에 의존합니다. 예는 GCC의 중첩 함수 와 일부 Unices 의 신호 메커니즘 입니다.

때때로 코드는 런타임에 코드로 변환됩니다 (이를 동적 이진 변환 이라고 함 ).

  • Apple의 Rosetta 와 같은 에뮬레이터 는 이 기술을 사용하여 에뮬레이션 속도를 높입니다. 또 다른 예는 Transmeta의 코드 모핑 소프트웨어 입니다.
  • Valgrind 또는 Pin 과 같은 정교한 디버거 및 프로파일 러 는 코드가 실행되는 동안이를 사용하여 코드를 계측합니다.
  • x86 명령어 세트가 확장되기 전에 VMWare와 같은 가상화 소프트웨어 는 가상 머신 내에서 권한있는 x86 코드를 직접 실행할 수 없었습니다. 대신 문제가있는 모든 명령을 즉석 에서보다 적절한 사용자 지정 코드로 변환해야 했습니다 .

코드 수정을 사용하여 명령어 세트의 제한을 해결할 수 있습니다.

  • 컴퓨터가 서브 루틴에서 복귀하거나 간접적으로 메모리 주소를 지정하라는 지시가 없었던 때가있었습니다. 자체 수정 코드는 서브 루틴, 포인터 및 배열구현 하는 유일한 방법이었습니다 .

더 많은 코드 수정 사례 :

  • 많은 디버거가 명령어를 대체하여 중단 점구현합니다 .
  • 일부 동적 링커 는 런타임에 코드를 수정합니다. 이 기사 에서는 사실상 코드 수정의 한 형태 인 Windows DLL의 런타임 재배치에 대한 배경 지식을 제공합니다.

10
이 목록은 자신을 수정하는 코드의 예와 링커와 같은 다른 코드를 수정하는 코드를 혼합 한 것으로 보입니다.
AShelly 2011

6
@AShelly : 글쎄요, 동적 링커 / 로더를 코드의 일부로 생각하면 스스로 수정합니다. 그들은 같은 주소 공간에 살고 있기 때문에 이것이 유효한 관점이라고 생각합니다.
Mackie Messer 2011

1
이제 목록에서 프로그램과 시스템 소프트웨어를 구분합니다. 이해가 되길 바랍니다. 결국 모든 분류는 논란의 여지가 있습니다. 모든 것은 프로그램 (또는 코드)의 정의에 정확히 무엇을 포함하는지에 달려 있습니다.
Mackie Messer

35

이것은 컴퓨터 그래픽, 특히 최적화 목적의 소프트웨어 렌더러에서 수행되었습니다. 런타임에 많은 매개 변수의 상태가 검사되고 최적화 된 버전의 래스터 라이저 코드가 생성되어 (잠재적으로 많은 조건부 제거) 삼각형과 같은 그래픽 프리미티브를 훨씬 더 빠르게 렌더링 할 수 있습니다.


5
흥미로운 읽기는 DDJ에 대한 Michael Abrash의 3 부 Pixomatic 기사입니다 : drdobbs.com/architecture-and-design/184405765 , drdobbs.com/184405807 , drdobbs.com/184405848 . 두 번째 링크 (Part2)에서는 픽셀 파이프 라인 용 Pixomatic 코드 용접기에 대해 설명합니다.
typo.pl 2011

1
주제에 대한 아주 좋은 기사입니다. 1984 년부터, 그러나 여전히 좋은 읽기 : Rob Pike, Bart Locanthi, John Reiser. Blit의 비트 맵 그래픽에 대한 하드웨어 소프트웨어 장단점 .
Mackie Messer 2011

5
Charles Petzold는 "Beautiful Code"라는 책에서 이런 종류의 한 가지 예를 설명합니다. amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/…
Nawaz 2011

3
이 답변은 코드 생성 에 대해 이야기 하지만 질문은 코드 수정 에 대한 질문입니다 ...
Timwi

3
@Timwi-코드를 수정했습니다. if 's의 큰 체인을 처리하는 대신 모양을 한 번 파싱하고 렌더러를 다시 작성하여 매번 확인할 필요없이 올바른 유형의 모양을 설정했습니다. 흥미롭게도 이것은 현재 opencl 코드에서 일반적입니다. 즉석에서 컴파일되기 때문에 런타임에 특정 경우에 대해 다시 작성할 수 있습니다.
Martin Beckett 2011

23

한 가지 유효한 이유는 asm 명령어 세트에 필요한 명령어가 없기 때문에 직접 구축 할 수 있습니다. 예 : x86에서는 레지스터의 변수에 인터럽트를 생성하는 방법이 없습니다 (예 : ax에서 인터럽트 번호로 인터럽트 생성). opcode에 코딩 된 const 번호 만 허용되었습니다. 자가 수정 코드를 사용하면이 동작을 모방 할 수 있습니다.


그럴 수 있지. 이 기술을 사용하고 있습니까? 위험 해 보입니다.
Alexandre C.

4
@Alexandre C .: 기억한다면 많은 런타임 라이브러리 (C, Pascal, ...)가 인터럽트 호출을 수행하기 위해 함수를 DOS 시간으로 처리해야했습니다. 이러한 함수는 매개 변수로 인터럽트 번호를 가져 오므로 이러한 함수를 제공해야합니다 (물론 숫자가 일정하다면 올바른 코드를 생성 할 수 있었지만 보장되지는 않았습니다). 그리고 모든 라이브러리는 자체 수정 코드로이를 구현했습니다.
flolo 2011-04-04

코드 수정없이 스위치 케이스를 사용할 수 있습니다. 축소는 출력 코드가 더 커진다는 것입니다
phuclv

17

일부 컴파일러는 정적 변수 초기화에 사용하여 후속 액세스에 대한 조건부 비용을 피했습니다. 즉, 처음 실행될 때 no-ops로 해당 코드를 덮어 써서 "이 코드를 한 번만 실행"을 구현합니다.


1
특히 뮤텍스 잠금 / 잠금 해제를 피하는 경우 매우 좋습니다.
Tony Delroy 2011-04-04

2
정말? ROM 기반 코드 또는 쓰기 방지 된 코드 세그먼트에서 실행되는 코드의 경우 어떻게합니까?
Ira Baxter 2011

1
@Ira Baxter : 재배치 가능한 코드를 생성하는 컴파일러는 최소한 시작 중에 코드 세그먼트가 쓰기 가능하다는 것을 알고 있습니다. 따라서 "일부 컴파일러에서 사용했다"는 말은 여전히 ​​가능합니다.
MSalters 2011

17

많은 경우가 있습니다.

  • 바이러스는 일반적으로 실행 전에 자체 수정 코드를 사용하여 코드를 "난독 화"했지만이 기술은 리버스 엔지니어링, 크래킹 및 원치 않는 해커를 좌절시키는 데에도 유용 할 수 있습니다.
  • 어떤 경우에는 런타임 동안 (예 : 구성 파일을 읽은 직후) 특정 지점이있을 수 있습니다.-프로세스의 나머지 수명 동안-특정 분기는 항상 또는 불필요하게 사용되지 않습니다. 분기 할 방법을 결정하기 위해 일부 변수를 확인하면 분기 명령어 자체가 그에 따라 수정 될 수 있습니다.
    • 예를 들어 가능한 파생 유형 중 하나만 처리되어 가상 디스패치가 특정 호출로 대체 될 수 있음을 알 수 있습니다.
    • 사용 가능한 하드웨어를 감지하면 일치하는 코드를 사용하여 하드 코딩 될 수 있습니다.
  • 불필요한 코드는 no-op 명령어로 대체하거나 그 위로 점프하거나 다음 코드 비트를 제자리로 직접 이동할 수 있습니다 (위치 독립적 opcode를 사용하는 경우 더 쉬움).
  • 자체 디버깅을 용이하게하기 위해 작성된 코드는 전략적 위치에서 디버거가 예상하는 트랩 / 신호 / 인터럽트 명령을 삽입 할 수 있습니다.
  • 사용자 입력을 기반으로하는 일부 술어 표현식은 라이브러리에 의해 원시 코드로 컴파일 될 수 있습니다.
  • 런타임까지 표시되지 않는 몇 가지 간단한 작업을 인라인합니다 (예 : 동적으로로드 된 라이브러리에서) ...
  • 자체 계측 / 프로파일 링 단계를 조건부로 추가
  • 크랙은이를로드하는 코드를 수정하는 라이브러리로 구현 될 수 있습니다 ( "자체"가 정확히 수정하는 것은 아니지만 동일한 기술과 권한이 필요함).
  • ...

일부 OS의 보안 모델은 자체 수정 코드가 루트 / 관리자 권한 없이는 실행할 수 없음을 의미하므로 범용 사용에는 비실용적입니다.

Wikipedia에서 :

엄격한 W ^ X 보안을 사용하는 운영 체제에서 실행되는 응용 프로그램 소프트웨어는 쓰기가 허용 된 페이지에서 명령을 실행할 수 없습니다. 운영 체제 자체 만 명령을 메모리에 쓰고 나중에 해당 명령을 실행할 수 있습니다.

이러한 OS에서는 Java VM과 같은 프로그램도 JIT 코드를 실행하기 위해 루트 / 관리자 권한이 필요합니다. (자세한 내용은 http://en.wikipedia.org/wiki/W%5EX 참조)


2
자체 수정 코드에는 루트 권한이 필요하지 않습니다. Java VM도 마찬가지입니다.
Mackie Messer

일부 OS가 그렇게 엄격한 줄은 몰랐습니다. 그러나 일부 응용 프로그램에서는 확실히 의미가 있습니다. 하지만 루트 권한으로 Java를 실행하면 실제로 보안이 강화되는지 궁금합니다.
Mackie Messer 2011-04-04

@Mackie : 그것을 줄여야한다고 생각하지만, 메모리 권한을 설정 한 다음 유효한 uid를 일부 사용자 계정으로 다시 변경할 수 있습니다 ...?
Tony Delroy 2011-04-04

예, 엄격한 보안 모델에 수반되는 권한을 부여하는 세분화 된 메커니즘이 있어야합니다.
Mackie Messer 2011

15

합성 OS는 기본적으로 부분적으로 API 호출에 대한 프로그램을 평가하고, 그 결과로 OS 코드를 교체했다. 주요 이점은 많은 오류 검사가 사라 졌다는 것입니다 (프로그램이 OS에 어리석은 작업을 요청하지 않을 경우 검사 할 필요가 없기 때문입니다).

예, 이것이 런타임 최적화의 예입니다.


나는 요점을 보지 못한다. 시스템 호출이 OS에 의해 금지된다고 말하면 코드를 확인해야한다는 오류가 다시 나타날 수 있습니다. 그렇지 않습니까? 오류 코드를 반환하는 대신 실행 파일을 수정하는 것은 과도한 엔지니어링이라고 생각합니다.
Alexandre C.

@Alexandre C. : 그런 식으로 널 포인터 검사를 제거 할 수 있습니다. 종종 호출자에게는 인수가 유효하다는 것이 명백합니다.
MSalters 2011

@Alexandre : 링크에서 연구를 읽을 수 있습니다. 나는 그들이 매우 인상적인 속도 향상을 가지고 생각하고, 그게 포인트가 될 것입니다 : -}
아이라 박스터

2
비교적 사소하고 I / O 바운드가 아닌 syscall의 경우 상당한 절감 효과가 있습니다. 예를 들어, Unix 용 데몬을 작성하는 경우 stdio 연결을 끊고 다양한 신호 처리기를 설정하기 위해 수행하는 일련의 상용구 시스템 호출이 있습니다. 호출의 매개 변수가 상수라는 것을 알고 있다면 결과는 항상 동일하며 (예 : stdin 닫기) 일반적인 경우에 실행하는 많은 코드가 필요하지 않습니다.
Mark Bessey 2011

1
논문을 읽으면 8 장에는 데이터 수집을위한 중요하지 않은 실시간 I / O에 대한 매우 인상적인 숫자가 포함되어 있습니다. 이것이 1980 년대 중반의 논문이고 그가 실행하고 있던 기계가 10 이었다는 것을 기억하십니까? Mhz 68000에서 그는 평범한 오래된 소프트웨어로 CD 품질의 오디오 데이터 (초당 44,000 개 샘플) 를 캡처 할 수있었습니다 . 그는 Sun 워크 스테이션 (고전적인 Unix)이 그 속도의 약 1/5에 불과할 수 있다고 주장했습니다. 나는 그 당시의 오래된 어셈블리 언어 코더였으며 이것은 꽤 훌륭합니다.
Ira Baxter

9

몇 년 전 나는 아침에자가 수정 코드를 디버깅하려고하는데, 한 명령이 다음 명령의 대상 주소를 변경했습니다. 즉, 분기 주소를 계산하고있었습니다. 어셈블리 언어로 작성되었으며 프로그램을 한 번에 하나씩 단계별로 실행했을 때 완벽하게 작동했습니다. 그러나 프로그램을 실행했을 때 실패했습니다. 결국, 나는 기계가 메모리에서 2 개의 명령어를 가져오고 있다는 것을 깨달았고 (명령이 메모리에 배치 되었기 때문에) 내가 수정하고 있던 명령어를 이미 가져 왔으므로 기계는 수정되지 않은 (잘못된) 버전의 명령어를 실행하고있었습니다. 물론 디버깅 할 때는 한 번에 하나의 명령 만 수행했습니다.

내 요점은 자체 수정 코드는 테스트 / 디버그하기가 매우 까다로울 수 있으며 종종 하드웨어 또는 가상 머신의 동작에 대한 숨겨진 가정을 가지고 있습니다. 더욱이 시스템은 (현재) 멀티 코어 머신에서 실행되는 다양한 스레드 / 프로세스간에 코드 페이지를 공유 할 수 없습니다. 이것은 가상 메모리 등에 대한 많은 이점을 무효화합니다. 또한 하드웨어 수준에서 수행 된 분기 최적화를 무효화합니다.

(참고-저는 자체 수정 코드 범주에 JIT를 포함하지 않았습니다. JIT는 코드의 한 표현에서 대체 표현으로 변환하고 있으며 코드를 수정하는 것이 아닙니다)

대체로 그것은 단지 나쁜 생각 일뿐입니다. 정말 깔끔하고, 정말 모호하지만 정말 나쁩니다.

물론-당신이 가진 모든 것이 8080과 ~ 512 바이트의 메모리라면 당신은 그러한 관행에 의지해야 할 수도 있습니다.


1
잘 모르겠습니다. 좋은 것과 나쁜 것이 이것에 대해 생각하기에 적합한 범주가 아닌 것 같습니다. 물론 당신은 당신이 무엇을하고 있는지, 그리고 왜 그것을하고 있는지를 정말로 알아야합니다. 그러나 그 코드를 작성한 프로그래머는 아마도 프로그램이 무엇을하는지보기를 원하지 않았을 것입니다. 물론 이와 같은 코드를 디버그해야한다면 불쾌합니다. 그러나 그 코드는 그렇게 될 가능성이 큽니다.
Mackie Messer 2011

최신 x86 CPU는 문서에서 요구하는 것보다 더 강력한 SMC 감지 기능을 제공합니다 . 자가 수정 코드를 사용하여 x86에서 오래된 명령어 가져 오기 관찰 . 그리고 대부분의 비 x86 CPU (예 : ARM)에서 명령어 캐시는 데이터 캐시와 일관되지 않으므로 새로 저장된 바이트를 명령어로 안정적으로 실행하려면 수동 플러시 / 동기화가 필요합니다. community.arm.com/processors/b/blog/posts/... . 어느 쪽이든 한 번 수정하고 여러 번 실행하지 않는 한 최신 CPU 에서 SMC 성능은 끔찍 합니다.
Peter Cordes 2018

7

운영 체제 커널의 관점에서 모든 Just In Time 컴파일러 및 링커 런타임은 프로그램 텍스트 자체 수정을 수행합니다. 대표적인 예는 Google의 V8 ECMA Script Interpreter입니다.


5

자체 수정 코드 (실제로는 "자체 생성"코드)의 또 다른 이유는 성능을위한 Just-In-time 컴파일 메커니즘을 구현하는 것입니다. 예를 들어 algebric 표현식을 읽고 입력 매개 변수 범위에 대해 계산하는 프로그램은 계산을 설명하기 전에 기계어 코드의 표현식을 변환 할 수 있습니다.


5

하드웨어와 소프트웨어간에 논리적 차이가 없다는 오래된 밤나무를 알고 있습니다. 코드와 데이터간에 논리적 차이가 없다고 말할 수도 있습니다.

자가 수정 코드 란 무엇입니까? 데이터가 아닌 명령으로 해석 될 수 있도록 실행 스트림에 값을 넣는 코드입니다. 물론 실제로 차이가 없다는 이론적 관점이 함수 언어에 있습니다. 나는 e가 동등한 지위를 가정하지 않고 명령형 언어와 컴파일러 / 통역사에서 간단한 방식으로 이것을 할 수 있다고 말하고있다.

제가 말하고있는 것은 데이터가 프로그램 실행 경로를 변경할 수 있다는 실제적인 의미입니다 (어떤 의미에서는 이것은 매우 분명합니다). 나는 프로그램이 명령에서 명령으로 이동하는 방식과 같이 구문 분석에서 통과하는 테이블 (데이터 배열)을 생성하고 상태에서 상태로 이동 (다른 변수도 수정)하는 컴파일러 컴파일러와 같은 것을 생각하고 있습니다. , 프로세스에서 변수 수정.

따라서 컴파일러가 코드 공간을 생성하고 완전히 분리 된 데이터 공간 (힙)을 참조하는 일반적인 인스턴스에서도 실행 경로를 명시 적으로 변경하기 위해 데이터를 수정할 수 있습니다.


4
논리적 차이는 없습니다. 사실입니다. 그러나 자기 수정 집적 회로를 너무 많이 보지 못했습니다.
Ira Baxter

@Mitch, IMO가 exec 경로를 변경하는 것은 코드의 (자체) 수정과 관련이 없습니다. 게다가 데이터와 정보를 혼동합니다. 나는 LSE b / c의 내 답장에 대한 yr의 코멘트 대답 할 수 없다. 나는 2 월부터 3 년 (1,000 일) 동안 미국인과 영국인이 영어를 소유하고 있지 않다는 나의 POV를 meta-LSE로 표현하는 것을 금지했다.
Gennady Vanin Геннадий Ванин 2011

4

최고의 알고리즘을 만들기 위해 진화를 사용하는 프로그램을 구현했습니다. DNA 청사진을 수정하기 위해 자체 수정 코드를 사용했습니다.


2

한 가지 사용 사례는 바이러스 백신 프로그램을 테스트하기위한 합법적 인 DOS 실행 가능 COM 파일 인 EICAR 테스트 파일 입니다.

X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

실행 파일은 인코딩 가능한 명령어의 수를 크게 제한하는 [21h-60h, 7Bh-7Dh] 범위의 인쇄 / 입력 가능한 ASCII 문자 만 포함해야하므로 자체 코드 수정을 사용해야합니다.

자세한 내용은 여기 에 설명되어 있습니다.


DOS에서 부동 소수점 연산 디스패치에도 사용됩니다.

일부 컴파일러는 CD xxx87 부동 소수점 명령어 대신 0x34-0x3B 범위의 xx 를 방출 합니다. CD명령에 대한 opcode 이므로 int인터럽트 34h-3Bh로 점프하여 x87 보조 프로세서를 사용할 수없는 경우 소프트웨어에서 해당 명령을 에뮬레이트합니다. 그렇지 않으면 인터럽트 처리기가이 2 바이트를로 대체하여 9B Dx나중에 실행이 에뮬레이션없이 x87에 의해 직접 처리됩니다.

MS-DOS에서 x87 부동 소수점 에뮬레이션을위한 프로토콜은 무엇입니까?


1

리눅스 커널은 다만 그것을로드 가능한 커널 모듈이있다.

Emacs도이 기능을 가지고 있으며 저는 항상 그것을 사용합니다.

동적 플러그인 아키텍처를 지원하는 모든 것은 본질적으로 런타임에 코드를 수정하는 것입니다.


4
거의. 항상 상주하지는 않는 동적으로로드 가능한 라이브러리를 갖는 것은 자체 수정 코드와 거의 관련이 없습니다.
Dov

1

지속적으로 업데이트되는 데이터베이스에 대해 통계 분석을 실행합니다. 사용 가능한 새로운 데이터를 수용하기 위해 코드가 실행될 때마다 통계 모델이 작성되고 다시 작성됩니다.


0

이것이 사용될 수있는 시나리오는 학습 프로그램입니다. 사용자 입력에 대한 응답으로 프로그램은 새로운 알고리즘을 학습합니다.

  1. 유사한 알고리즘에 대한 기존 코드베이스를 조회합니다.
  2. 유사한 알고리즘이 코드베이스에없는 경우 프로그램은 새 알고리즘을 추가합니다.
  3. 유사한 알고리즘이 존재하는 경우 프로그램 (아마도 사용자의 도움을 받아)은 기존 알고리즘을 수정하여 이전 목적과 새로운 목적을 모두 제공 할 수 있습니다.

Java에서이를 수행하는 방법에 대한 질문이 있습니다. Java 코드의 자체 수정 가능성은 무엇입니까?


-1

이것의 가장 좋은 버전은 Lisp 매크로 일 것입니다. 전처리 기일 뿐인 C 매크로와 달리 Lisp를 사용하면 항상 전체 프로그래밍 언어에 액세스 할 수 있습니다. 이것은 lisp에서 가장 강력한 기능에 대한 것이며 다른 언어에는 존재하지 않습니다.

나는 결코 전문가가 아니지만 lisp 녀석 중 한 명이 그것에 대해 이야기하게하십시오! 그들이 Lisp가 주변에서 가장 강력한 언어이고 현명한 사람들은 그들이 옳다고 말하는 이유가 있습니다.


2
실제로 자체 수정 코드를 생성합니까 아니면 더 강력한 전 처리기 (함수를 생성 할 것)입니까?
Brendan Long

@Brendan이 : 참, 그러나 그것은 이다 전처리 할 수있는 올바른 방법. 여기에는 런타임 코드 수정이 없습니다.
Alexandre C.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.