왜 C와 C ++에서 운영 체제가 저수준 작업을 수행합니까? 왜 C ++이 아닌가?


20

Windows 용 위키 백과 페이지 , 그것은 윈도우 부트 로더 및 작업 스위처에 대한 국회로 작성 상태, 및 C 커널 루틴 C ++.

IIRC, extern "C"'d 블록 에서 C ++ 함수를 호출 할 수 있습니다 . 커널 함수에 C를 사용하여 순수한 C 앱이 (같은 printf등) 사용할 수 있지만 extern "C "블록 으로 래핑 할 수 있다면 왜 C로 코드를 작성해야합니까?


10
다양한 "C ++가있을 때 C를 사용하는 이유는 무엇입니까?" 여기에 질문이 있습니까? 이것은 반드시 그 중 하나의 중복 아니지만, 그들은 입니다 관련.

1
"외부에서 C ++ 함수를 호출 할 수 있습니다."C "블록을 C ++로" C 함수를 호출 할 수 있습니까?
Code-Guru

@ Code-Guru no, 내 보낸 C와 C ++ 함수의 유일한 차이점은 이름 데코레이션과 C ++에서는 this변수 의 추가입니다.
Cole Johnson

2
ISR에서 예외를 던져서 어떤 일이 발생하는지 확인
James

또 다른 C 대 C ++ 질문.
Machado

답변:


31

대부분 역사적 이유 때문입니다. Windows 커널의 일부는 원래 C로 작성되었습니다. 1983 년, 30 년 전에 Windows 1.0이 공개 되었을 때 C ++은 거의 릴리스되지 않았기 때문 입니다. Microsoft는 이전 버전과의 호환성을 판매 지점으로 만들었고 C ++에서 버그 호환 버전의 C- 파트를 다시 작성하면 효과적인 이점을 얻기 위해 많은 노력이 필요하기 때문에 이러한 C 라이브러리는 "영원히"유지됩니다.


+1, 나는 이것이 가장 현실적인 대답이라고 생각합니다 (C ++을 좋아하지 않거나 저수준 항목에 대해 C ++ 컴파일러를 신뢰하지 않는 Windows 커널 개발자가있을 수 있음). 예를 들어 여기에서 stackoverflow.com/questions/520068/… 을 살펴보십시오 . Linux 커널이 C로 작성된 이유
Doc Brown

@ back2dos-C 코드는 버리지 않지만 사용되거나 업데이트되지 않는다는 의미는 아닙니다. Windows 8에서 C ++ 라이브러리로 포팅 된 C 라이브러리 내에 원래 작성되고 포함 된 작업을 수행하는 최소한 하나의 메소드가 있음을 보증합니다
Ramhound

8
최신 Windows 릴리스에 Windows 1.0 코드가 있다고 생각하기가 어렵습니다. Windows ME는 Windows NT 코드 기반을 기반으로하지 않은 마지막 Windows 릴리스입니다. 심지어 그조차도 새로운 RT 커널로 대체되었습니다 (내가 이해하는 것처럼 하위 호환성을 보장하지는 않습니다).
TMN December

@TMN는 : - 내가 이길 1.0에서 지금 거기로가는 길에 확신 인수는 하나 대부분의 아마 정확 했다 여전히 현재 Win8 코드 기반의 일부 C로 작성된 라이브러리의 많은, 그리고 MS에서 아무도 어떤 볼 수 없습니다 C ++로 다시 작성하면 도움이됩니다.
Doc Brown

1
어쨌든 Windows 커널과 통신하는 코드는 거의 없습니다. 기본적으로 드라이버 만 수행합니다. 응용 프로그램은 일반적으로 Win32 API 또는 POSIX API와 통신합니다.
MSalters

24

대부분의 사람들이 지적했듯이, 이유는 훨씬 역사적이지만 아무도 언급하지 않은 것이 있으며 사람들이 여전히 저수준의 C 코드를 작성하는 이유라고 생각합니다.

C는 사양이 (상대적으로) 짧다는 의미에서 작은 언어입니다. C ++은 거대 하고 과소 평가입니다. 프로그래머에게는 그다지 중요하지 않을 수도 있지만 (그렇다고 생각하지만) 공식적인 검증 을 원한다면 매우 중요합니다 . 또한 C 코드 분석을위한 기존 도구가있어 버그 등을 예방할 수 있습니다

그리고 이것은 다른 산업에 비해 배포되는 버그 비용이 매우 높은 임베디드 소프트웨어에서 매우 중요합니다 (웹을 비교하면 모든 사용자에게 즉시 패치를 적용 할 수 있음). 미션 크리티컬 소프트웨어 및 의료 제품은 말할 것도 없습니다.

BitC와 같이 더 나은 언어로 저수준 프로그래밍에서 C를 지배적 인 위치에서 옮기려는 시도가 있었지만 지금까지는 성공하지 못했습니다.


4
+1 순수한 C에서 미션 크리티컬 소프트웨어 (예 : 항공 소프트웨어)를 언급합니다. 그러나 의료 소프트웨어에서는 C ++도 사용됩니다 (C ++에서는 매우 어려운 공식 검증 대신 광범위한 테스트가 사용됨).
Giorgio

1
또한 C는 안전한 부분 집합 MISRA-C를 가지고 있습니다. C ++에 해당하는 것이 있지만 실제로는 표준이 아닙니다 (아직). 안전 핵심 프로그래밍의 추세는 라이브러리와 컴파일러가 MISRA와 같은 안전한 하위 집합을 사용해야한다는 것입니다. 전체 C ++ 표준 라이브러리의 MISRA-C ++ 호환 버전을 다시 작성하는 것은 대부분 악몽 일 것입니다.

2
@Lundin MISRA 가이드 라인은 안전한 부분 집합이 아닙니다. 여전히 C 포인터를 안전하지 않게 만드는 기본 포인터 및 기타 기능이 있습니다. 주로 구현 관련 동작을 사용하거나 문서화하지 않는 데 중점을 둡니다.
피트 Kirkham

@PeteKirkham MISRA-C는 가장 고전적인 포인터 버그를 모두 잡아서 정적 분석을 시행합니다. 산업 안전 표준 (IEC 61508 등)은 MISRA-C를 C의 안전한 부분 집합으로 승인 한 것으로 보입니다. 제한된 도구로 거의 아는 언어 인 SPARK Ada를 선택하지 않는 한 미션 크리티컬 소프트웨어를위한 다른 유용한 대안은 많지 않습니다. 지원하다.

2
이것이 정답으로 최고의 답변으로 선택되어 있어야합니다. C가 역사적 이유로 만 사용된다고 제안하는 다른 사람들은 그 자체로 히스테리 적입니다.
Rob

15
  1. C 런타임은 훨씬 작습니다.
  2. C ++을 하위 구조로 변환하는 것은 C보다 덜 투명합니다 (2 개의 빠른 예는 참조 및 vtable 참조).
  3. C는 보통 안정적인 ABI를 가지고 있습니다. C ++은 보통 그렇지 않습니다. 즉, 시스템 호출 인터페이스는 최소한 C 스타일이어야합니다. 또한 모든 종류의 동적 모듈을 원한다면 일관된 ABI를 갖는 것이 크게 도움이됩니다.

(2) 및 (3)의 경우 +1 나는 확신하지 않는다 (1).
Thomas Eding

7
@Thomas Eding : C ++ 런타임은 C 런타임과 예외, RTTI 및 다른 메모리 할당 자와 같은 C ++ 기능으로 구성됩니다. 그것이 큰지 여부에 대한 YMMV . (그리고 표준 라이브러리가 있습니다 ...)
wnoise

아, 나는 예외와 새로운 / 삭제 풀을 잊어 버렸습니다. RTTI 나는 결코 사용하지 않는다 : D
Thomas Eding

11

그 이유는 기술적 인 것이 아닙니다. 조립의 약간은 피할 수 있지만,이되지 않습니다 강제로 , 그들은 가끔 C를 사용 하고자 합니다. 우리 회사는 거의 전적으로 C ++로 작성된 자체 소유 커널을 사용하지만 임베디드 커널은 C ++ 응용 프로그램으로 모 놀리 식으로 컴파일되므로 대부분의 다른 사람들과 마찬가지로 커널에 대한 C 인터페이스를 지원할 필요가 없습니다. C 인터페이스 를 사용 하는 경우 C ++로 작성하는 데 사용할 있지만 C로 인터페이스 코드를 작성하는 것이 더 쉽습니다 extern "C".

대부분의 타사 코드로 인해 C 파일이 많이 있습니다. 타사 저수준 코드는 거의 항상 C로 제공됩니다. C 코드를 다른 방식보다 C ++ 앱에 통합하는 것이 훨씬 쉽기 때문입니다.


6

커널 개발자는 종종 소스에서 즉시 드러날 때 코드가 실제로하는 일을 더 행복하게 느끼는 사람들입니다.

C ++에는 코드가 수행하는 기능을 일반 C 코드보다 숨기는 것보다 더 많은 기능이 있습니다. 그것을 사용하는 코드.

C ++의 힘은 라이브러리와 프레임 워크를 만드는 데 매우 강력한 도구라고 생각합니다. C ++ 애플리케이션 개발자는 라이브러리를 사용하여 애플리케이션을 작성하는 데 능숙한 경우에도 템플릿으로 채워진 라이브러리의 내장에서 완전히 손실됩니다. 그리고 C ++ 라이브러리 권한을 작성하는 것은 매우 어려운 프로그래밍 작업이며 응용 프로그램 개발자의 이익을위한 훌륭한 프레임 워크를 제공하기 위해서만 수행됩니다. C ++ 라이브러리는 내부적으로 단순하지 않으며 응용 프로그램 프로그래머의 관점에서 볼 때 강력하지만 단순합니다.

그러나 커널 API는 C ++ API가 될 수 없으며 언어에 구애받지 않는 API 여야하므로 C ++의 멋진 기능은 해당 인터페이스에서 직접 사용할 수 없습니다. 또한 커널은 실제로 독립적으로 개발 된 "라이브러리"와 "애플리케이션"부분으로 나뉘어 있지 않으며, 많은 응용 프로그램을 쉽게 만들 수 있도록 하나의 라이브러리로 논리적으로 더 많은 노력을 기울입니다.

또한 보안 및 안정성은 커널 내에서 더 중요하며 가상 메소드는 일반 콜백 또는 다른 C와 유사한 메커니즘보다 훨씬 더 동적이므로 분리 및 확인하기가 훨씬 어렵습니다.

즉, 커널을 포함하여 C ++로 C 프로그램을 작성할 수는 있지만 C ++의 대부분의 기능은 커널에서 잘 사용되지 않습니다. 그리고 많은 사람들은 프로그래밍 도구가 당신이하지 말아야 할 일을하지 못하게해야한다고 주장합니다. C ++은 그렇지 않습니다.


+1. 커널 개발자로서 나의 "규칙"은 "캐시 라인을 쉽게 터치"할 수 없다면 사용하는 언어가 좋은 것보다 더 해롭다는 것입니다.
Brendan

설명 : 커널의 경우 CPU가 사용자 공간에서 대부분의 시간을 소비하고 커널 코드가 산발적으로 사용된다고 가정해야합니다 (예 : 사용자 공간이 커널 API를 호출하거나 인터럽트가 발생하는 경우). 즉, "콜드 캐시"를 가정해야합니다. 최신 CPU (RAM이 CPU 속도에 비해 느린 경우) 캐시 및 TLB 미스가 비싸므로 ( "콜드 캐시"기대 값과 결합 된) "캐시 라인 터치"메트릭은 성능 및 / 또는 확장성에있어 매우 중요한 지표가됩니다.
Brendan

5

Bjarne Stroustrup, 1999 년 7 월 인터뷰에서 :

이 언어들 중 어느 것도 다른 현대 언어들과 근본적으로 다르거 나 극적으로 더 나은 언어는 없었습니다. 그러나 그들은 충분히 좋고 행운과 사회적 요인의 수혜자였습니다.


2
데이비드를 환영합니다. 인용하거나 인용 할 때 참고 문헌을 제공하는 것이 좋습니다 (추가됨)
Andrew

3

C는 설계 상 매우 낮은 수준의 언어입니다. 어셈블러에서 한 걸음 떨어져 있습니다. 대상 칩셋을 알면 약간의 지식으로 C를 ASM에 수동으로 "컴파일"할 수 있습니다. 이러한 종류의 "금속에 근접한"언어는 높은 수준의 최적화 (성능, 메모리 효율성 등)를위한 핵심 요소입니다. 그러나 이것은 금속에 가깝기 때문에이 언어를 사용하면 무료로 많은 것을 얻을 수 없습니다. 그것은 절차적이고 객체 지향적이지 않은 언어이기 때문에 그러한 구조로 작업하려면 메모리에서 다중 값 구조를 만들고 소비하는 많은 상용구 코드가 필요합니다.

C ++은 "C one better"로, 일부 효율성 손실을 희생시키면서 동적 메모리 할당, 내장 구조 마샬링, 사전 정의 된 코드의 큰 라이브러리 등과 같은 사용하기 쉬운 기능을 추가합니다 관리 런타임 환경보다). 평균 코더의 경우, 장점은 메모리 할당 등의 항문 보유 제어가 필요하지 않은 코드베이스 영역의 단점보다 훨씬 큽니다.

이 둘의 조합은 꽤 전통적인 것입니다. C를 사용하여 코드베이스에서 성능이 가장 중요하고 메모리가 효율적인 영역을 작성하면 C ++ 코드의 메소드 호출을 통해보다 추상적 인 방식으로 작업 할 수 있습니다. 이는 Uber 성능보다 더 우아하고 체계적으로 설계 될 수 있습니다. 엄청나게 최적화 된 C 코드.


2
효율성에 관해, 나는 스스로 반복 할 것이다. (1) C ++ 사람들은 그것이 헛소리라고 말할 것이다. (2) 나는 이것이 사실이어야 할 이유가 없으며 구체적인 예를 원한다고 말하고 있습니다. 덜 효율적인 코드를 작성하는 것이 쉬운 방법의 예가 아니라 C만큼 효율적이되는 방법의 예는 과도한 추악함을 요구합니다.

3
"못생긴"을 정의; 나는 생활을 위해 C #으로 코딩하고, StackOverflow에서 C ++ 코드 예제를 볼 때마다 언어의 일상적인 사용에서 얼마나 많은 쪼그리고 앉는 지에 대해 울었습니다. C ++ 방식으로 코딩 할 때 종종 C 코드를보고 울었습니다. 수동 포장 구조 유형, 수동 점프 실행 포인터 계산, 임베디드 ASM ... yuck. 어떤 사람들은 Java / .NET 프로그래머들 사이에서 저수준 지식의 상실을 비난합니다. 생산성에 큰 도움이됩니다.
KeithS

1
당신은 내 질문에 대답하지 않았다;) "못생긴"은 "못생긴 C ++ 전문가 표준"을 의미합니다. 다시 말해, "현대 C ++"을 사용할 수없고 C만큼 효율적일 수있는 예제입니다.

2
사실 일 수도 있습니다 (정직하게 모르겠습니다). 커널 개발 (및 다른 몇 가지 분야)의 경우 일반 프로그래머에 대해서는 이야기하지 않습니다.

3
사람들은 C-> C ++가 연속체라는 것을 잊습니다. 너무 자주, 이러한 주장은 현대적인 좋은 C ++과 C를 비교하는 것입니다. C 프로그램을 사용하여 비교적 짧은 시간 안에 C ++ 컴파일러로 컴파일하면 정확하게 실행됩니다. 최신 C ++ 기능이 "너무 느리다"면 사용하지 마십시오. 그것은 심지어 같은 것들을 포함 할 수 있습니다 iostream. "너무 느리다"는 C ++보다 C ++을 사용하는 좋은 구실이 아닙니다.
로봇

1

C를 사용하면 대부분의 시간을 당면한 문제와 솔루션을 코딩하는 방법에 대해 생각할 수 있습니다. C ++에서는 C ++과 수많은 기능, 함수 및 모호한 구문에 대해 생각하게됩니다.

또한 많은 C ++ 상점에서 코드는 최신 디자인 패턴 또는 위대한 신 Stroustrup의 이해할 수없는 최신 선언에 매료 된 "패션 경찰"에 의해 모니터링됩니다. 예쁜 코드는 작업 코드보다 가치가 높아 지므로 최신 Boost 템플릿 집합을 찾는 것이 비즈니스에 적합한 솔루션을 찾는 것보다 더 중요합니다.

내 경험은 모든 영리한 기능과 C ++의 OO 순도에 대해 일반 C로 코딩하면 작업이 더 빠르고 효과적으로 완료된다는 것입니다.


0

C 부분이 C ++ 부분에 사용되는 C ++ 컴파일러에 이식성이 좋지 않을 수 있습니다. 어쩌면 C 코드는 C ++ 컴파일러와 충돌하는 방식으로 C 컴파일러와 혼잡 할 수 있습니다.

양질의 C ++ 컴파일러가 있다면 프로젝트에서 C와 C ++를 혼합 할 이유가 거의 없습니다. 거의.

한 가지 이유는 프로젝트가 다른 프로젝트와 C 코드를 공유하고 코드가 C ++로 컴파일되지 않기 때문에 해당 코드의 C ++ 포크를 유지하고 싶지 않기 때문입니다.


-1

extern "C"블록을 뒤로 하면 C 호출 규칙이 블록 내의 모든 기능에 사용됩니다. 따라서 C의 C ++ 함수가 아닌 C ++에서 순수한 C 함수를 호출 할 수 있습니다. 직접 작성하는 것보다 이미 존재하며 (아마도 디버깅 및 최적화 된) 것입니다. OTOH, C ++는 사람들이 함께 작업 할 멋진 고급 기능을 많이 제공하므로 나머지 기능에도 사용됩니다.


-2

C를 프로그래밍 언어로 사용하는 다양한 수준의 임베디드 플랫폼이 있습니다 (물론 어셈블리 언어를 언제든지 자유롭게 사용할 수 있습니다)

'Level'의 경우 시스템의 내부 SRAM 및 ROM 리소스 수준에 대해 이야기하고 있습니다.

이러한 플랫폼은 때때로 리소스가 제한됩니다 (예 : 일부 8051 플랫폼에는 128 바이트의 사용자 SRAM 만 있음)

적은 양의 RAM으로 동적 메모리 할당을 지원하는 것은 의미가 없습니다. (신규 / 삭제) 또는 C의 malloc

C에서 C ++ 로의 주요 개선 중 하나는 객체 지향 패러다임입니다. C ++는 메모리 풋 프린트가 큰 소프트웨어에 적합합니다.

최대 32KB의 크기 제한이있는 내장 펌웨어에는 없습니다. (예 : 16 비트 MCU 플랫폼)

일반적으로 C 컴파일러보다 복잡한 C ++ 컴파일러가 필요하지 않습니다. (적어도 SDK 제공 업체는이를 귀찮게하지 않습니다).

사실 32 비트 ARM7 플랫폼에서 C ++ 컴파일러를 거의 찾을 수 없습니다.

복잡할만한 가치가 없습니다.

일부 8051 (8 비트) : 1MB ROM, 128B RAM

TI MSP430 (16 비트) : 32KB ROM, 4KB RAM

ST Microelectronics ARM 32 비트 Cortex ™ -M3 CPU 코어 (STM32F103T4) : 16 또는 32KB 플래시 메모리 6 또는 10KB SRAM


2
이것은 이미 여기에 게시 된 다른 답변에 새로운 것은 아닙니다.
Martijn Pieters

ARM 용 32 비트 C ++ 컴파일러? 원하는 경우 iOS 용 C ++ 컴파일러를 얻기 위해 몇 가지 수정 후에 소스에서 LLVM을 직접 컴파일 할 수 있습니다.
Cole Johnson

-4

몇 가지 가능한 이유가 있습니다.

  • C는 C ++에 비해 약간 더 효율적입니다.
  • 그들이 사용하는 일부 라이브러리는 C로 작성되었습니다.
  • 그들은 C로 작성된 Linux 커널의 일부를 사용합니다.

편집 : 결과적으로 세 번째 인수는 사실이 아닙니다 (댓글 참조).


5
(1) C ++ 사람들은 다르게 구걸 할 것입니다. 그리고 객관적으로 이것이 사실이어야 할 이유가 없습니다. (2) C ++은 C 코드를 잘 호출 할 수 있습니다 (이전 버전과의 호환성 및 전체 요점입니다 extern "C").

1
MS가 Linux 커널의 일부를 사용하고 Linux 커널이 GPL 인 경우 Windows도 GPL이어야 함을 의미하지 않습니까?
TomJ

1
@TomJ는 실제로 리눅스에 수천 라인을 기증해야하는 이유입니다. + 왜 Linux 개발을 지원한다고 생각하십니까?
Pijusn

2
@Pius 그의 요점은 (그리고 그는 AFAIK입니다.) Windows 커널에 연결된 GPL의 코드가 있다면, 전체 커널은 GPL이어야합니다 (저작권 보유자와 별도의 계약이없는 경우).

@ delnan, 세부 정보가 확실하지 않습니다. 저는 변호사가 아니므로 이에 대해 언급 할 수 없습니다. 그러나 몇 년 전에 이것에 관한 작은 추문이있었습니다. 확실하지는 않지만 나는 모든 미친 물건에 관한 네트워킹 모듈 일 수 있다고 생각합니다.
Pijusn

-4

C는 C ++보다 더 나은 언어 일 것입니다. 그리고 C ++이 대중화되기 전에 일부 코드가 작성되었으므로 사람들은이를 대체 할 이유가 없었습니다.

그리고 C ++에는 커널에서 사용할 때주의하지 않으면 코드를 손상시킬 수있는 많은 기능이 있기 때문에.


C ++은 동적 라이브러리를 기대합니까? 그리고 동적 메모리는 무엇입니까?

4
의 경우 -1입니다 [stuff] that C++ expects. C ++가 C보다 많은 힙을 사용하는 이유는 무엇입니까? C ++에 C보다 많은 dll이 필요한 이유는 무엇입니까? TRUE NOT TRUE
Thomas Eding

1
수정 : C ++로 작성된 라이브러리가 손실됩니다. 따라서 C ++ 또는 C를 사용하는 경우 다시 제곱 1로 돌아갑니다. 템플릿, 클래스, 소멸자, const 및 기타 모든 종류의 장점을 사용할 수있는 경우 C 기능으로 제한하는 이유는 무엇입니까?
Thomas Eding

6
뭐? 템플릿, 예외, 객체 (생성자, 소멸자, 오버로드 된 연산자 포함, 이제 구성 이동 및 실질적으로 다른 모든 것 등) 등은 메모리의 출처 (스택, 정적 메모리, 사용자 지정 풀 등)에 관계없이 정상적으로 작동합니다. . 표준 컨테이너는 기본적으로 힙 할당을 사용하지만 할당자를 사용자 지정할 수 있으며 커널 사용자는 자체 컬렉션 및 메모리 관리를 작성합니다. -1

2
참고 : 귀하의 답변이 지금까지 적극적으로 해롭다 고 생각하지 않기 때문에 공감대를 삭제했지만, 특히 유용하거나 통찰력있는 것으로 간주하지는 않습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.