Table of Contents
휴대용 C 코드를 작성하는 것은 전문 소프트웨어 엔지니어링의 코너스톤이며, 다양한 하드웨어 아키텍처, 운영 체제 및 컴파일러를 최소 재작업으로 실행할 수 있도록 응용 프로그램을 가능하게 합니다. 포트 가능은 유지 보수 오버 헤드를 줄이고, 사용자 기반을 확장하고, 진화 플랫폼에 대한 미래 증거 코드를 확장합니다. 이 문서는 C 표준 및 수십 년의 실제 경험을 바탕으로 진정한 포용성을 달성하기위한 전장 모범 사례를 활용합니다.
플랫폼의 차이점 이해
포트 가능 기술을 적용하기 전에 개발자는 플랫폼 사이에 존재하는 변화의 종류를 인식해야합니다. 이러한 차이는 4 가지 넓은 범주를 경작합니다. 컴파일러 행동, 운영 체제 API, 하드웨어 아키텍처 및 리소스 제약.
Compiler 변리사
C 컴파일러 - GCC, Clang 및 MSVC에서 IAR 및 Keil과 같은 임베디드 도구로 C 표준을 준수의 다양한 수준으로 구현합니다. 그들은 서명, 비트 ‐ 필드 레이아웃, 구조 패딩 및 또는 의 정확한 세만성을 다룰 수 있습니다. 언어 확장 (예 : GNU C 확장, Microsoft’s ]도 숨겨진 문제를 해결할 수 있습니다.
운영 시스템 차이
POSIX-like system (Linux, macOS, BSD)는 많은 API를 공유하지만 Windows는 시스템 호출의 기본 설정에 노출됩니다. File I/O, 나사, 동적 연결, 신호 및 프로세스 제어는 종종 조건부 컴파일 또는 요약 레이어가 필요합니다. 파일명 케이스 감도 및 경로 분리기 (backslash vs. forward slash)는 관리가 필요합니다.
하드웨어 아키텍처 및 Endianness
프로세서는 단어 크기 (32 비트 대 64 비트), 바이트 순서 (큰 ‐ 엔도 또는 작은 ‐ 엔도), 정렬 요구 사항 및 명령 세트 기능에 따라 다릅니다. 를 가정하는 코드는 32 비트 또는 ]에 점적 적합 많은 플랫폼에 실패합니다. Endianness는 네트워크 전송 또는 파일 저장을위한 직렬화 된 데이터가 발생할 때 중요합니다.
자원 제약
임베디드 시스템 또는 심하게 임베디드 대상은 운영 체제가 부족할 수 있으며, 제한된 스택/허브 크기가 제한되어 있으며, ]]를 제공합니다. 휴대용 코드는 메모리 가용성 및 실행 지원에 대해 가정을 피해야합니다.
휴대용 C Code에 대한 핵심 모범 사례
표준 C 라이브러리에 의존
C 표준 라이브러리 (ISO/IEC 9899)는 모든 준수 컴파일러가 공급해야 하는 기본 라인을 제공합니다. , , , ]와 같은 기능들은 플랫폼 전반에 걸쳐 동일하게 작용합니다. ]] (POSIX)와 같은 플랫폼 별 동일하게 행동하십시오. 수학 작업의 경우 ] [FLT: 13]]]를 선호합니다.
Fixed-Width Integer 유형 사용
헤더는 , ], ]와 같은 유형의 정확한 크기를 보장한다. 항상 예를 들어, 프로토콜 버퍼 또는 하드웨어 레지스터를 정의 할 때 값의 범위가 중요 할 때 사용. 마찬가지로, 사용 형식의 specifiers (, ]) 이러한 유형의 포트를 인쇄하기 위해.
#include <stdint.h>
#include <inttypes.h>
int32_t val = -100;
printf("Value: %" PRId32 "\n", val);
펀드형에 대한 가정을 피하십시오.
은 32 비트, 은 64 비트, 또는 가 서명되어 있음을 가정하지 마십시오. ]과 ]을 사용하여 (]], ]]) 컴파일 시간에 파생 속성에. 포인터의 경우, 또는 ]를 사용하여 저장해야합니다.
손잡이 내의성 Explicitly
기계 (네트워크, 파일, 또는 공유 메모리)를 통해 바이너리 데이터를 교환 할 때, 항상 알려진 바이트 순서로 변환 – 기존 네트워크 바이트 순서 (큰 ‐endian). POSIX 기능 , , , ] 널리 사용할 수 있습니다; 비 POSIX 시스템의 경우, 및 실행 시간 감지를 사용하여 자신의 구현을 제공합니다.
Abstract 파일 시스템 운영
파일 경로 delimiters는 (]] 유닉스에, ] 윈도우에서. 매크로를 사용하거나 경로 정상화하는 작은 유틸리티 기능. 디렉토리 iteration에 대 한, POSIX API는 표준; 윈도우에서 같은 인터페이스 뒤에 를 포장할 수 있습니다. 절대 경로가 하드 코딩을 방지.
Minimise 정의 및 구현 ‐ 정의 Behaviour
C 표준은 정의되지 않은 또는 구현 정의로 많은 작업을 지정합니다. 예로는 입력의 폭보다 더 많은 것을 교대하고, ]을 증발시키는 서명 된 정수 과잉, 포함됩니다. Cppcheck 또는 ]Clang‐Tidy 같은 패턴을 잡기 위해, 엄격하게 준수되는 코드 작성.
Compile‐Time Selection를 위한 활용도 Preprocessor Macros
조건 컴파일은 플랫폼 별 코드에 필수적이지만, 오용은 엉망을 만들 수 있습니다. 잘 알려진 사전 정의 매크로를 사용합니다. , ], ], ], ]]와 같은 컴파일러 매크로를 사용합니다. 항상 각 분지를 문서화하고 플랫폼 별 섹션을 작은 유지하십시오.
#ifdef _WIN32
#include <windows.h>
#define SLEEP(ms) Sleep(ms)
#else
#include <unistd.h>
#define SLEEP(ms) usleep((ms)*1000)
#endif
시스템 통화에 대한 Abstraction 레이어 사용
스레드, 소켓, 타이머 및 메모리 관리, 얇은 래퍼를 만들. 예를 들어, 정의 ] 유형과 ] 유닉스에 POSIX 스레드에 맵을하는 기능 및 윈도우. 같은 접근은 동적 라이브러리에 작동 (] 대. ]). 많은 오픈 소스 라이브러리 (예 : [LTLTLTLT0]]] [LT0]]]]] [LT0]]]]]]]] ]]]]
Multiple Platforms의 시험 조기 및 의제
연속 통합 (CI) 파이프라인은 Linux, macOS, Windows 및 임베디드 대상에서 테스트 스위트를 컴파일하고 실행해야합니다. 배포하기 전에 아키텍처 별 버그를 잡기 위해 크로스 컴파일러 및 에뮬레이터 (예 : QEMU)를 사용합니다. [[FLT : 0]]]ctest[[FLT : 1] 또는 [FLT : 2]] CMake / CTest[FLT : 3]는 강제적 인 능력을 돕습니다.
고급 Portability 기술
CMake 또는 Autotools와 시스템 구성
현대 빌드 시스템은 구성 시간에 플랫폼 특성을 감지 할 수 있습니다. CMake의 , ], ]] 모듈은 코드를 포함 할 수있는 ]를 생성합니다. 이것은 진실의 단일 지점과 함께 brittle ] 체인을 대체합니다.
// Generated config.h
#define HAVE_STDINT_H 1
#define WORDS_BIGENDIAN 0
#define SIZEOF_LONG 8
휴대용 인라인 회의 및 Intrinsics
성능이 요구될 때 플랫폼 별 지침 (예: SIMD, CPUID), 별도의 파일에 캡슐화하고 빌드 중에 올바른 파일을 선택하십시오. 컴파일러 인트릭 (예: GCC/Clang/ICC/VS)에서 컴파일러 인트릭 (]과 같은 아키텍처에서 컴파일러에 더 휴대용이기 때문에 인라인 어셈블리보다는 GCC/Clang/ICC/VS)에서 컴파일러를 사용합니다.
Align Data Structures의 장점
구조 포장 및 정렬은 다를 수 있습니다. ]과 ] C11 (]])에서 정렬을 시행합니다. 이전 컴파일러의 경우, 사전 처리기 기반 작업 (]를 GCC, 를 고용합니다.
Signal Handling 호환성
신호 상수 (, ]) 및 안전 신호 처리는 널리 다릅니다. POSIX ] API는 이전 에 선호됩니다. Windows에서 신호는 콘솔 제어 핸들러를 통해 에뮬레이션됩니다. 일반적인 기능 뒤에 정확한 신호 등록은 놀랍게 피도록 합니다.
Real-World Pitfalls 및 Them을 방지하는 방법
Fallback 없이 재해
은 POSIX에 표준이지만 많은 임베디드 플랫폼과 이전 Windows 환경에서 누락됩니다. plibc 또는 최소 ]]과 같은 휴대용 구현을 사용합니다.
을 호출하는 정수입니다.
C 표준은 ]는 실시간 표현할 수 있는 실제 유형입니다. 어떤 임베디드 시스템에서는 불신호가 없는 32비트 값입니다. 다른 사람에는 64비트 서명 정수가 있습니다. 이 차이를 위해 ]에서 arithmetic을 수행하지 마십시오.
시스템 통화의 안전
, , ] static 버퍼를 사용 하 여 스레드 안전 하지 않습니다. reentrant 변형을 사용 하 여 (], ]]) 가능한 플랫폼에 낙하된 구현을 제공 하 고.
관련 기사
C 코드는 모든 분야와 투자입니다. C 표준에 밀접하게 붙어서 고정 폭 유형, 초록 체계 공용영역을 선택하고, 다수 플랫폼의 맞은편에 시험은, 개발자 마이크로 제어기에 슈퍼컴퓨터에서 배열하는 환경에서 믿을 수 있는 실행하는 소프트웨어를 생성할 수 있습니다. 이 관행은 여기에서 – 현대 건축 체계 윤곽과 정체되는 분석과 결합해 – 십자가 플랫폼 C 발달을 위한 튼튼한 기초를 형성합니다. 기억: 휴대용은 기침이 아닙니다; 그것은 프로젝트의 주위에 분할한 프로젝트의 과정을 지불하는 목표입니다.