# NASA의 소프트웨어 개발 10가지 규칙

> Clean Markdown view of GeekNews topic #19260. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=19260](https://news.hada.io/topic?id=19260)
- GeekNews Markdown: [https://news.hada.io/topic/19260.md](https://news.hada.io/topic/19260.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-02-17T08:34:15+09:00
- Updated: 2025-02-17T08:34:15+09:00
- Original source: [cs.otago.ac.nz](https://www.cs.otago.ac.nz/cosc345/resources/nasa-10-rules.htm)
- Points: 36
- Comments: 6

## Summary

NASA의 소프트웨어 개발 규칙은 임베디드 시스템을 위한 것이지만, 다른 개발 환경이나 언어에서도 적절한 지에 대한 논의가 필요합니다. 규칙들은 단순한 제어 흐름 유지, 루프 상한 설정, 동적 메모리 할당 금지 등을 포함하며, 각 규칙에 대한 비판적 분석이 제시되었습니다. 특히, 현대의 정적 분석 도구를 활용하여 지나친 제한 대신 더 정교한 분석 기법을 사용하는 것이 유용하다는 의견이 있습니다.

## Topic Body

- NASA의 10가지 소프트웨어 개발 규칙에 대한 비판적 분석  
  - 이 규칙들은 극도로 중요한 임베디드 시스템(예: 우주선 소프트웨어)을 위한 것  
  - 하지만 이러한 규칙이 다른 개발 환경에서도 적절한지, 또는 다른 언어(C가 아닌 언어)에서도 적용 가능한지에 대해 논의가 필요함  
  
### 1. 단순한 제어 흐름 유지 (goto, setjmp/longjmp, 재귀 금지)  
-	이 규칙은 예외 처리(setjmp()/longjmp())와 재귀를 금지함.  
-	재귀가 반드시 비효율적인 것은 아님. 적절한 방법을 사용하면 재귀도 종료를 보장할 수 있음.  
-	강제로 재귀를 루프로 변환하면 유지보수가 어려운 코드가 될 위험이 있음.  
  
비판:  
-	종료 보장이 중요하지만, 극단적인 제한은 가독성과 유지보수를 저해할 수 있음.  
-	무조건적인 재귀 금지는 불필요한 복잡성을 초래할 가능성이 큼.  
  
### 2. 모든 루프는 명확한 상한을 가져야 함  
-	컴파일러가 루프 반복 횟수를 정적으로 분석할 수 있어야 함.  
-	그러나 단순히 상한을 설정하는 것만으로는 실제 실행 시간 보장이 어려움.  
-	재귀 깊이 제한을 두는 것이 루프 상한을 두는 것만큼 안전할 수 있음.  
  
비판:  
-	단순히 상한을 두는 것만으로는 현실적인 실행 가능 시간을 보장하지 못함.  
-	상한을 설정해도 너무 큰 값이라면 사실상 무한 루프와 다를 바 없음.  
  
### 3. 초기화 이후 동적 메모리 할당 금지  
-	임베디드 시스템에서는 메모리가 한정적이므로 메모리 부족으로 인한 충돌을 방지하려는 목적.  
-	하지만 수동 메모리 관리보다 예측 가능한 동적 할당이 더 안전할 수도 있음.  
-	예를 들어, 실시간 가비지 컬렉터(RTGC) 를 사용하면 동적 할당도 예측 가능하게 만들 수 있음.  
  
비판:  
-	동적 할당 자체를 금지하는 것보다, 메모리 사용 패턴을 분석하여 안전성을 확보하는 것이 더 나은 접근 방식일 수 있음.  
-	현대적인 정적 분석 도구(SPlint 등)를 활용하면 동적 메모리 관련 오류를 사전에 감지할 수 있음.  
  
### 4. 함수 크기는 A4 용지 한 장 이내로 제한 (약 60줄)  
-	함수가 너무 길면 가독성이 떨어진다는 논리.  
-	하지만 현대 개발 환경에서는 코드 폴딩 기능이 있어, 함수 길이보다 논리적 단위의 크기가 더 중요함.  
  
비판:  
-	물리적인 크기(줄 수)보다 논리적 복잡성을 기준으로 삼아야 함.  
-	함수를 작게 쪼개는 것 자체가 목표가 되어서는 안 됨 → 오히려 유지보수를 어렵게 만들 수도 있음.  
  
### 5. 함수당 최소 두 개의 assert 문 사용  
-	assert는 디버깅과 문서화에 매우 유용함.  
-	하지만 무조건적인 개수 제한은 비효율적일 수 있음.  
  
비판:  
-	assert의 개수보다 데이터 유효성 검사가 필요한 위치를 명확히 하는 것이 중요함.  
-	모든 인자와 외부 입력을 검증하는 것이 더 실용적임.  
  
### 6. 데이터 객체의 스코프 최소화  
-	지역 변수 사용을 권장하는 좋은 원칙.  
-	하지만 함수뿐만 아니라 타입과 함수의 스코프도 최소화해야 함.  
  
비판:  
-	Ada, Pascal, JavaScript, 함수형 언어에서는 타입과 함수도 지역적으로 선언 가능 → NASA 규칙보다 더 나은 접근 방식.  
  
### 7. 함수 반환 값 및 매개변수 유효성 검증 필수  
-	반환 값을 반드시 체크해야 함.  
-	하지만 모든 경우를 체크하는 것은 현실적으로 어려움.  
  
비판:  
-	실행 오류를 방지하려면 가능한 많은 검사가 필요하지만, 실용적인 한계를 고려해야 함.  
-	특히 C에서는 반환 값 체크가 중요하지만, 현대 언어(Java, Rust 등)에서는 타입 시스템을 활용해 더 안전하게 처리 가능.  
  
### 8. 전처리기 사용 제한 (헤더 포함 및 단순 매크로만 허용)  
-	복잡한 매크로, 토큰 결합, 가변 인자 매크로(...) 금지.  
-	하지만 가변 인자 매크로는 디버깅 도구로 유용할 수 있음.  
  
비판:  
-	전처리기 사용을 제한하는 것보다 가독성 좋은 매크로 스타일을 권장하는 것이 바람직함.  
-	#ifdef 같은 조건부 컴파일을 막으면, 플랫폼 독립적인 코드 작성이 어려워질 수 있음.  
  
### 9. 포인터 사용 제한 (이중 포인터 금지, 함수 포인터 금지)  
-	함수 포인터 사용 금지 → 높은 안정성을 목표로 함.  
-	하지만 함수 포인터는 콜백, 전략 패턴, 디바이스 드라이버 등에 필수적임.  
  
비판:  
-	함수 포인터 없이 switch-case로 함수 선택을 강제하면 코드 가독성이 떨어지고 유지보수가 어려워짐.  
-	운영체제, 네트워크 스택, 드라이버 개발에서는 함수 포인터가 필수적임.  
-	포인터 제한보다 안전한 포인터 사용을 보장하는 방법(C++ 스마트 포인터, Rust 등)이 더 나은 해결책.  
  
### 10. 모든 코드에 대해 컴파일러 경고를 최대로 설정하고, 정적 분석 도구 사용  
-	이 규칙은 매우 좋은 권장 사항.  
-	컴파일러 경고 제거 + 정적 분석 도구 사용 = 안정성 향상.  
  
비판:  
-	NASA의 다른 규칙(예: 포인터 금지, 함수 크기 제한)은 단순히 정적 분석 도구의 한계를 극복하려는 목적이 있음.  
-	하지만 현대 정적 분석 도구는 매우 발전했으므로, 지나친 제한보다 더 정교한 분석 기법을 활용하는 것이 유용함.

## Comments



### Comment 34726

- Author: regentag
- Created: 2025-02-18T08:32:05+09:00
- Points: 3

전부 다 실시간, 임베디드 관점에서 보면 이해되고 필요한 규칙들이네요. 정적분석기가 이 규칙들을 대신해 줄 수 있을까요?  
  
예를들어, 동적할당을 허용했을 때 모든 사용 시나리오에서 메모리 할당에 성공한다는것을 보장할 수 있을까요?  
  
소프트웨어 테스트를 공부하면 항상 첫날 첫시간에 언급되는 명제들이 있죠. 그 중 하나가 "완벽한 테스트는 불가능하다"구요.

### Comment 34724

- Author: smboy86
- Created: 2025-02-18T07:41:10+09:00
- Points: 1

반대가 더 눈에 가는거보니  
저랑은 안 맞는 규칙인거 같네요 ㅎㅎ

### Comment 34681

- Author: rtyu1120
- Created: 2025-02-17T11:03:32+09:00
- Points: 1

NASA뿐만 아니라 항공/자동차 등 생명이 직결되어 있는 산업군에서는 비슷한 코딩 규칙을 적용하는 경우가 많아 보이더라고요 ㅎㅎ

### Comment 34678

- Author: ssssut
- Created: 2025-02-17T10:51:41+09:00
- Points: 2

https://github.com/kubernetes/kubernetes/blob/v1.32.2/pkg/controller/volume/persistentvolume/pv_controller.go#L61-L64  
Kubernetes 소스코드 중 NASA Space Shuttle 애플리케이션 소스코드 작성 방법으로 작성했다 하는 'space shuttle style' 코드 블록이 생각났네요.  
관련 HN Thread: https://news.ycombinator.com/item?id=18772873

### Comment 34664

- Author: neo
- Created: 2025-02-17T08:34:16+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=43061977) 
* 원문을 읽어보면 각 항목의 목적을 설명하고 있음
* 원문은 주로 C 언어를 대상으로 하며, C로 작성된 중요한 응용 프로그램의 신뢰성을 더 철저히 검사할 수 있도록 최적화하려고 함
* 원저자는 자신이 무엇을 하는지 명확히 이해하고 있으며, C 코드를 검증하는 여러 방법을 설명함
* 원문에 있는 논리는 모두 완벽하게 이해됨
  - 아마도 작은 시스템에서 C를 배웠기 때문일 것임
  - 임플란트 의료 기기를 위한 하드웨어용 C를 배웠으며, 실험실에서도 유사한 지침을 따랐음
* 마지막 단락은 훌륭함
  - 규칙이 처음에는 엄격하게 느껴질 수 있지만, 코드의 정확성에 생명이 달려 있을 수 있는 경우를 고려해야 함
  - 자동차의 안전벨트처럼 처음에는 불편할 수 있지만, 시간이 지나면 자연스럽게 사용하게 됨
* 이 규칙에 대한 나의 비판은 OP와는 매우 다를 것임
  - setjmp/longjmp를 옹호하는 글을 처음부터 진지하게 받아들이기 어려웠음
  - 이 패턴은 접근해본 사람이라면 누구나 명백히 문제가 있음
  - 글은 setjmp/longjmp가 예외 처리라고 주장함
  - 예외 처리는 좋다고 주장함
  - 두 번째 전제에 심각한 문제가 있음
* 루프에 대해 최대 반복 횟수를 설정하라는 의미임
  - 10^90은 어리석고 관련이 없음
  - 이 지점 이후로 글을 읽지 않았음
* 규칙을 비판한다면 다음과 같은 점에 초점을 맞출 것임
  - 함수 본문의 길이는 이해의 단순성과 상관관계가 없으며, 오히려 규칙이 암시하는 것과 반대일 수 있음
  - 2개의 단언은 완전히 임의적이며, 단언할 수 있는 모든 것을 단언해야 함
  - Ada, Pascal (Delphi), JavaScript, 또는 함수형 언어를 사용하는 사람들은 가능한 한 지역적으로 타입과 함수를 선언해야 함
* JavaScript에서의 개인적인 접근 방식은 명시적으로 값을 캡처하려는 경우를 제외하고 중첩된 방식으로 함수를 정의하지 않는 것임
  - 오래된 정신 모델 때문일 수 있음
  - 성능 프로파일링에서 함수가 호출될 때마다 재정의된다고 보여졌음
  - 현대 JavaScript 인터프리터가 이렇게 작동한다고는 생각하지 않음
  - 화살표 함수 도입 이후로 깊은 최적화가 이루어졌을 것임
  - 오래된 습관은 쉽게 사라지지 않음
  - 지역 변수를 캡처하지 않는 명명된 함수는 파일/모듈 범위에 유지함
* 다른 많은 노트는 흥미롭고 매우 세세한 부분임
  - "기술적으로 정확한 것이 가장 좋은 정확성"이라는 방식으로 오래된 엔지니어들이 좋아함
  - NASA 규칙이 전달하려는 신중함의 일반적인 톤이 매우 좋다고 생각하며 대부분을 지지함
* 문맥상, 이것들은 "규칙"이라기보다는 제안된 관행임
  - 공식적인 "규칙"은 "NPR" 같은 이름의 문서에 있음
  - 개발자는 이 "규칙"을 준수하거나 무시할 의무가 없음
* GCC는 컴파일 후 스택 사용량과 호출자-피호출자 관계를 얻을 수 있음
  - setjmp()와 longjmp()는 예외를 처리하는 나쁜 방법임
  - 청소 코드가 실행되지 않음
  - 규칙의 정신을 따르면 청소가 필요한 자원이 없어야 함
* 주요 문제는 각 응용 프로그램에서 다르게 나타남
  - 반복 제한이 초과되거나 시작 시 할당된 고정 자원이 충분하지 않을 때 어떻게 할 것인가
* 요즘 프로그래머들은 코드를 화면에서 읽기 때문에 종이 크기가 더 이상 관련이 없는 이유가 명확하지 않음
  - 표준 페이지와 문자 크기에 대한 반복이 있었음
  - 종이의 한계뿐만 아니라 인간의 한계 때문임
* 재귀에 대한 규칙은 필요한 스택 공간의 정적으로 알려진 경계를 보장하기 위한 것임
  - 컴파일러에 의존한다는 비판은 맞지만, 런타임의 상한을 도출하기 위한 전제 조건임
  - 안전이 중요한 시스템에서는 보장된 응답 시간이 필요함
* 제목은 규칙에 대한 _비판_임을 나타내야 함
* 엄격한 타입 사용을 권장함
  - 모든 스칼라 타입에 대해 엄격한 타입 사용
  - 제국 단위와 미터법 단위를 혼합하지 않음

### Comment 34910

- Author: roxie
- Created: 2025-02-21T13:32:00+09:00
- Points: 1
- Parent comment: 34664
- Depth: 1

> 제목은 규칙에 대한 _비판_임을 나타내야 함  
  
222
