화요일, 4월 23, 2024
Home자동화C 언어가 “수십년 동안” 왕좌를 굳건히 지켜온 이유

C 언어가 “수십년 동안” 왕좌를 굳건히 지켜온 이유


‘C 언어’는 1972년 개발 이후 전 세계적으로 널리 사용되며 소프트웨어 시대의 핵심 기본 구성요소로 군림하고 있다. 그러나 지난 수십 년 동안 많은 새로운 언어가 등장했습니다. 그 중에는 C 언어의 패권에 노골적으로 도전하는 언어도 있었고, 인기를 얻으면서 C 언어를 조금씩 침식하는 언어도 있었습니다. C 언어를 C++, Java, C#, Rust, Python과 비교하고 ‘초보’ Carbon을 C 언어와 비교해 보겠습니다.

ⓒ게티이미지뱅크

C 대 C++

C 언어의 가장 일반적인 비교 지점은 C++입니다. 이름에서 알 수 있듯이 C++는 C 언어의 확장으로 개발되었습니다. C++의 구문과 접근 방식은 C와 유사하지만 네임스페이스, 템플릿, 예외 처리, 자동 메모리 관리 등 C가 기본적으로 제공하지 않는 매우 유용한 기능을 지원합니다. 데이터베이스나 기계 ​​학습 시스템과 같이 최고 수준의 성능이 필요한 프로젝트는 C++의 이러한 기능을 사용하여 작성되는 경우가 많습니다.

C++는 C보다 훨씬 더 적극적으로 확장되고 있습니다. 다가오는 C++ 23은 모듈, 코루틴, 더 빠른 컴파일, 모듈화된 표준 라이브러리를 포함한 많은 기능을 제공할 것입니다. 반면, C 표준의 최신 버전(C2x)은 추가 기능이 거의 없으며 이전 버전과의 호환성을 유지하는 데 중점을 둡니다.

문제는 C++의 모든 장점에는 단점도 있고, 이러한 단점이 상당하다는 점입니다. C++의 더 많은 기능을 사용할수록 더 복잡해지고 결과를 제어하기가 더 어려워집니다. 최악의 문제 대부분은 C++의 특정 부분 사용을 제한함으로써 피할 수 있습니다. 이러한 복잡성은 소스에서도 차단됩니다. 예를 들어, Linux 커널 개발 팀은 C++를 피하고 대부분의 Linux는 여전히 C로 작성됩니다(현재 Rust는 향후 커널 추가를 위한 언어로 간주되지만).

물론 C++에 고급 기능이 풍부한 데에는 분명한 이유가 있습니다. 그러나 미니멀리즘이 현재 및 미래의 프로젝트와 프로젝트 팀에 더 적합하다면 C를 사용하는 것이 더 합리적입니다.

C 대 자바
개발된 지 수십 년이 지난 지금도 Java는 엔터프라이즈 소프트웨어 개발의 중심으로 남아 있으며 일반 개발의 필수 요소입니다. Java의 구문은 C 및 C++에서 많이 차용되었습니다. 그러나 C와 달리 Java는 네이티브 코드로 컴파일되지 않습니다. 대신, Java의 JIT(Just-In-Time) 컴파일러는 Java 코드를 컴파일하여 대상 환경에서 실행합니다. JIT 엔진은 프로그램 동작을 기반으로 런타임에 루틴을 최적화하여 사전 컴파일된 C에서는 불가능한 많은 최적화 클래스를 허용합니다. 올바른 조건에서 JIT 컴파일된 Java 코드는 C 성능에 근접하거나 심지어 이를 초과할 수 있습니다.

Java 런타임은 메모리 관리도 자동화하지만 일부 새로운 애플리케이션은 이를 우회하여 작동합니다. 예를 들어 Apache Spark는 메모리를 직접 할당 및 관리하고 JVM의 가비지 수십 시스템의 오버헤드를 피하기 위해 Java 런타임의 ‘안전하지 않은’ 부분을 사용하여 메모리 내 처리를 부분적으로 최적화합니다.

또한 Java의 ‘한 번 작성하면 어디서나 실행’ 기능 덕분에 Java 프로그램은 비교적 적은 조정만으로 여러 대상 아키텍처에서 실행될 수 있습니다. 이와 대조적으로 C는 수많은 아키텍처로 포팅되었지만 예를 들어 특정 C 프로그램을 Linux에서 Windows로 가져오려면 일부 사용자 정의가 필요합니다.

이식성, 강력한 성능, 광범위한 소프트웨어 라이브러리 및 프레임워크 에코시스템의 조합으로 인해 Java는 엔터프라이즈 애플리케이션 개발에 선호되는 언어 및 런타임이 되었습니다. Java가 C에 비해 부족한 부분은 기계 가까이에서 실행되거나 하드웨어를 직접 처리하는 경우인데, 이는 애초에 언어의 의도된 초점이 아닙니다.

C 코드는 기계어로 컴파일되어 프로세스에서 직접 실행됩니다. Java는 JVM 인터프리터가 기계어로 변환하는 중간 코드인 바이트코드로 컴파일됩니다. 또한 Java의 자동 메모리 관리는 대부분의 환경에서 유용하지만 제한된 메모리 리소스를 최적으로 사용해야 하는 프로그램에는 C가 더 적합합니다.

C 대 C# 및 .NET
출시된 지 20년이 지난 지금도 C#과 .NET은 여전히 ​​기업용 소프트웨어 개발 분야의 주요 언어로 사용되고 있습니다. C# 및 .NET은 Java(관리 코드 컴파일러 시스템 및 범용 런타임)에 대한 Microsoft의 대응으로 간주됩니다. 또한 C와 Java 간의 비교만큼 C와 C#/.Net 간의 비교도 많습니다.

.NET은 Java(및 어느 정도 Python)와 마찬가지로 플랫폼 간 이식성과 방대한 통합 소프트웨어 에코시스템을 제공합니다. .NET에서 얼마나 많은 엔터프라이즈 개발이 이루어지는지 고려하면 이는 상당한 이점입니다. C# 또는 다른 .NET 언어로 프로그램을 개발하는 경우 .NET 런타임용으로 작성된 다양한 도구와 라이브러리를 활용할 수 있습니다.

Java와 유사한 .NET의 또 다른 장점은 JIT 최적화입니다. C# 및 .NET 프로그램은 C처럼 미리 컴파일할 수 있지만 주로 .NET 런타임에 의해 JIT 컴파일되고 런타임 정보를 통해 최적화됩니다. JIT 컴파일을 통해 C에서는 수행할 수 없는 .NET 프로그램 실행에 대한 모든 종류의 즉석 최적화가 가능합니다.

C 언어(및 어느 정도 Java)와 마찬가지로 C# 및 .NET은 메모리에 직접 액세스하기 위한 다양한 메커니즘을 제공합니다. 힙, 스택 및 관리되지 않는 시스템 메모리는 모두 .NET API 및 개체를 통해 액세스할 수 있습니다. 또한 개발자는 .NET의 안전하지 않은 모드를 사용하여 성능을 향상할 수 있습니다.

물론 단점도 있습니다. 관리되는 객체와 안전하지 않은 객체는 임의로 교환할 수 없으며, 두 객체 간의 마샬링으로 인해 성능이 저하될 수 있습니다. 따라서 .Net 애플리케이션 성능을 최대화한다는 것은 관리되는 개체와 관리되지 않는 개체 간의 이동을 최소화하는 것을 의미합니다.

관리되는 메모리와 관리되지 않는 메모리 간의 균형을 허용할 수 없거나 .NET 런타임이 대상 환경(예: 커널 공간)에 적합하지 않거나 전혀 사용할 수 없는 경우 C가 필요합니다. 또한 C# 및 .NET과 달리 , C는 기본적으로 직접 메모리 액세스를 비활성화합니다.

C 대 Go
Go의 구문에는 구분 기호 역할을 하는 중괄호부터 명령문을 종료하는 세미콜론까지 C에서 차용한 많은 요소가 있습니다. C에 익숙한 개발자라면 큰 어려움 없이 Go를 사용할 수 있습니다. Go의 디자인 목표 중 하나는 ‘읽기 쉬운 코드’였습니다. 개발자가 쉽고 빠르게 Go 프로젝트에 적응하고 짧은 시간 내에 코드 기반을 능숙하게 처리할 수 있도록 하는 데 중점을 둡니다. C 코드베이스는 프로젝트와 팀에서 사용하는 모든 매크로와 #ifdef로 가득 차 있는 경향이 있으므로 이해하기 어려울 수 있습니다. 의도적인 구문, 기본 코드 형식화 및 프로젝트 관리 도구는 C에서 이러한 제도적 문제를 방지합니다.

Go에는 동시성 관리 및 구성 요소 간 메시지 전달을 위한 고루틴, 채널, 언어 수준 도구와 같은 추가 기능도 있습니다. C에서는 이를 위해서는 수동으로 수행하거나 외부 라이브러리의 지원을 받아 수행해야 하지만 Go에서는 기본적으로 제공되므로 이러한 요소가 필요한 소프트웨어를 쉽게 구축할 수 있습니다.

Go와 C의 차이점은 메모리 관리입니다. Go 객체는 기본적으로 자동으로 관리되고 가비지 수집됩니다. 이는 대부분의 프로그래밍 작업에 매우 편리할 수 있습니다. 그러나 결정론적인 메모리 처리가 필요한 프로그램은 작성하기 어렵다는 문제가 있다.

Go에는 포인터 유형을 사용하여 임의의 메모리를 읽고 쓰는 것과 같은 일부 유형 처리 안전성을 우회하는 안전하지 않은 패키지가 포함되어 있습니다. 그러나 Unsafe에는 ‘Unsafe로 작성된 프로그램은 이식성이 없으며 Go 1 호환성 지침으로 보호되지 않을 수 있습니다’라는 경고가 함께 제공됩니다.

Go는 명령줄 유틸리티 및 네트워크 서비스와 같은 프로그램을 구축하는 데 적합합니다. 이는 이러한 프로그램에는 세부적인 조작이 거의 필요하지 않기 때문입니다. 그러나 하위 수준 장치 드라이버, 커널 공간 운영 체제 구성 요소, 메모리 레이아웃 및 관리에 대한 정밀한 제어가 필요한 작업의 경우 C로 작성하는 것이 적합합니다.

C 대 러스트
어떤 면에서 Rust는 C와 C++로 인한 메모리 관리 문제와 이들 언어의 많은 단점에 대한 해결책이라고 할 수 있습니다. Rust는 네이티브 기계 코드로 컴파일되기 때문에 성능 측면에서 C와 동등한 것으로 간주됩니다. 하지만 Rust의 가장 큰 매력은 내장된 메모리 안전성입니다.

Rust의 구문과 컴파일 규칙은 개발자가 일반적인 메모리 관리 실수를 피하는 데 도움이 됩니다. 프로그램에서 Rust 구문과 일치하지 않는 메모리 관리 문제가 발생하면 컴파일 자체가 발생하지 않습니다. Rust를 처음 사용하는 사람이나, 이전에 C와 같이 버그가 발생할 위험이 높은 언어를 사용했던 사람들은 Rust를 배우는 첫 단계로 컴파일러를 다루는 방법을 주의 깊게 배웁니다. Rust 지지자들은 이 단계가 장기적인 보상을 제공한다고 주장합니다. 즉, 속도를 희생하지 않고도 보다 안전한 코드를 얻을 수 있다는 것입니다.

게다가 Rust의 도구는 C 도구보다 개선되었습니다. Go와 마찬가지로 Rust의 프로젝트와 구성요소는 기본적으로 툴체인에 포함되어 있습니다. 추가적으로 패키지 관리, 프로젝트 폴더 구성 등이 기본으로 제공됩니다. C에서는 이러한 작업 처리 방식이 임시적일 뿐만 아니라 각 프로젝트와 팀이 서로 다른 방식으로 작업을 처리했습니다.

그러나 Rust의 장점은 C 언어 개발자에게 유리하지 않을 수 있습니다. Rust의 컴파일 시간 안전 기능은 비활성화할 수 없기 때문에 가장 사소한 Rust 프로그램이라도 Rust의 메모리 안전 규정을 준수해야 합니다. C는 본질적으로 덜 안전할 수 있지만 훨씬 더 유연하고 관대합니다.

또 다른 단점은 Rust 언어의 크기입니다. 표준 라이브러리를 고려해도 C에는 기능이 상대적으로 적습니다. Rust에는 많은 기능이 있으며 지속적으로 확장되고 있습니다. C++와 마찬가지로 Rust는 더 많은 기능을 갖고 있기 때문에 더 강력하지만, 더 복잡하기도 합니다. 기능적인 측면에서 C는 더 작은 언어이지만 모델링하기가 더 쉽기 때문에 Rust가 부담스러운 프로젝트에 더 적합합니다.

C 대 파이썬
Python은 요즘 소프트웨어 개발에 관한 대화에서 일반적인 주제입니다. Python은 ‘모든 목적을 위한 두 번째로 좋은 언어’이며 수천 개의 타사 라이브러리를 제공하여 가장 다재다능한 언어 중 하나입니다.

Python이 강조하는 점과 C와 다른 점은 실행 속도보다 개발 속도를 우선시한다는 점입니다. C로 작성하는 데 약 한 시간이 걸리는 프로그램을 Python으로는 몇 분 만에 만들 수 있습니다. 반면에 이 프로그램을 실행하는 데 C에서는 몇 초가 걸릴 수 있지만 Python에서는 몇 분이 걸릴 수 있습니다(일반적으로 Python 프로그램은 동일한 프로그램의 C 버전보다 훨씬 더 오래 걸립니다). 그러나 Python은 최신 하드웨어에서 실행되는 많은 작업을 수행할 수 있을 만큼 빠르며 이것이 인기를 끄는 이유입니다.

또 다른 큰 차이점은 메모리 관리입니다. Python 프로그램의 메모리는 Python 런타임에 의해 관리되므로 개발자는 메모리 할당 및 해제에 대해 걱정할 필요가 없습니다. 그러나 개발자가 점점 익숙해짐에 따라 런타임 성능은 저하됩니다. C 프로그램을 작성할 때 메모리 관리에 세심한 주의를 기울여야 하지만, 프로그램 속도는 순수 머신과 동일하게 유지됩니다.

그러나 내부적으로는 Python과 C가 밀접하게 연결되어 있습니다. 참조 Python 런타임은 C로 작성되어 Python 프로그램이 C 및 C++로 작성된 라이브러리를 래핑할 수 있습니다. 기계 학습 및 타사 라이브러리로 구성된 Python 생태계의 대부분은 C 코드를 기반으로 합니다.

그러므로 ‘C vs.’는 ‘파이썬’의 문제가 아니라, 오히려 애플리케이션의 어느 부분을 C로 작성해야 하는지, 파이썬으로 작성해야 하는지의 문제이다. 실행 속도보다 개발 속도가 더 중요하거나 성능 기준을 충족하는 대부분의 프로그램 부분을 독립적인 구성 요소로 격리할 수 있는 경우 순수 Python 또는 Python과 C 라이브러리의 조합이 C만 사용하는 것보다 더 나은 선택입니다. 그렇지 않으면 C가 적합합니다.

C 대 탄소
C 및 C++의 잠재적 경쟁자는 현재 개발 중인 새로운 언어인 ‘Carbon’입니다. Carbon의 목표는 간단한 구문, 최신 도구 및 코드 구성 기술, C 및 C++ 개발자가 직면한 만성 문제에 대한 솔루션을 통해 C 및 C++의 대안이 되는 것입니다. 또한 C++ 코드베이스와의 상호 운용성을 제공하여 기존 코드를 점진적으로 마이그레이션할 수 있도록 계획하고 있습니다. C와 C++는 최근 개발된 것보다 다소 오래된 도구와 프로세스를 제공하므로 이는 환영할 만한 계획입니다.

그렇다면 탄소의 단점은 무엇입니까? 요점은 프로덕션 환경에서 사용할 준비가 전혀 되어 있지 않은 실험적인 프로젝트라는 것입니다. 이 시점에서는 작동하는 컴파일러조차 없는 온라인 코드 탐색기일 뿐입니다. Carbon이 C나 C++에 대한 실질적인 대안이 되기까지는 더 많은 시간이 걸릴 것 같습니다.
ciokr@idg.co.kr



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments