🔷 개요: -Warray-bounds
경고가 왜 문제인가?
Xcode 프로젝트에서 외부 라이브러리나 암호화 함수(특히 Blake2b)를 사용하다 보면 다음과 같은 컴파일 오류를 만날 수 있습니다:
bashCopyEditerror: array subscript is partly outside array bounds [-Werror=array-bounds]
이 오류는 실제 런타임에서 문제가 없을 수도 있지만, 컴파일러의 정적 분석이 위험하다고 판단한 경우에도 발생합니다. Blake2b
의 SIMD 최적화 코드가 대표적인 사례입니다.
🔍 원인 분석: Blake2b 내부 코드를 살펴보자
Blake2b는 고속 해시 알고리즘으로, 내부적으로 직접 메모리 접근 및 정렬된 구조체를 사용합니다.
예시 코드: 문제의 핵심
cCopyEdittypedef struct __attribute__((aligned(64))) blake2b_state {
uint64_t h[8];
uint64_t t[2];
uint64_t f[2];
uint8_t buf[2 * BLAKE2B_BLOCKBYTES]; // 문제 발생 지점
size_t buflen;
uint8_t last_node;
} blake2b_state;
cCopyEditstatic void blake2b_compress(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) {
const uint64_t *m = (const uint64_t *)block;
// ...
v[0] ^= m[0]; // 🔥 컴파일러가 여기서 경고를 날릴 수 있음
}
왜 경고가 나는가?
block
은uint8_t
배열인데uint64_t
포인터로 캐스팅됨 → 정렬 불일치 가능성 존재.m[0]
접근은 8바이트 정렬이 보장되지 않으면 undefined behavior일 수 있음.- Clang이나 GCC는 정렬을 보장하지 못할 경우 보수적으로 경고를 발생시킴.
⚠️ 특히
__attribute__((aligned(64)))
가 지정되어 있더라도, 이를 사용하는 코드가 정확히 정렬된 메모리를 전달하지 않으면 경고 또는 런타임 문제가 발생합니다.
⚙️ 해결 방법: 컴파일러 플래그로 우회
문제가 되는 부분을 직접 수정하기보다, 대부분의 Xcode 프로젝트에서는 다음과 같이 경고를 무시하는 방식을 택합니다.
Podfile의 예 (CocoaPods 사용 시):
rubyCopyEditpost_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['OTHER_CFLAGS'] = '$(inherited) -Wno-error=array-bounds'
config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO'
end
end
end
의미
설정 | 의미 |
---|---|
-Wno-error=array-bounds | 배열 경계 초과에 대한 경고를 에러로 취급하지 않음 |
GCC_WARN_ABOUT_RETURN_TYPE = NO | C 코드에서 반환형 관련 경고 무시 (Blake2b 구현체가 종종 미지정 상태로 선언됨) |
🧪 대안: 코드 수정 시 고려사항
직접 Blake2b 코드를 수정해 문제를 없애고 싶다면, 다음을 고려해야 합니다.
1. 메모리 정렬 보장
cCopyEdit// safer casting
uint64_t m[16] __attribute__((aligned(64)));
memcpy(m, block, BLAKE2B_BLOCKBYTES);
2. 컴파일 타겟에 따른 차이
- ARM64(iOS 디바이스): 정렬 문제에 더 민감
- x86_64(macOS): 상대적으로 관대하지만, 컴파일러 설정이 보수적으로 되어 있으면 동일하게 경고 발생
🧠 왜 이런 일이 생길까?
핵심은 컴파일러의 정적 분석(Static Analysis)
컴파일러는 런타임 상황을 정확히 알 수 없기 때문에 다음과 같은 보수적인 접근을 택합니다:
- 포인터가 안전하게 정렬되지 않았다고 추정하면 경고
- 코드가 안전하다고 사람은 알아도, 컴파일러는 모름
- 보안상 안전하지 않은 코드를 경고로 막는 문화 → 특히 암호화 함수에서 민감함
✅ 실전 팁 요약
상황 | 해결책 |
---|---|
CocoaPods 사용 | post_install 에서 -Wno-error=array-bounds 추가 |
직접 코드 수정 | memcpy() 사용하여 안전한 정렬 캐스팅 |
CMake/Makefile 프로젝트 | CFLAGS += -Wno-error=array-bounds 설정 |
경고가 많아 디버깅 어려움 | -Warray-bounds 자체를 끄는 것도 고려 (단, 위험성 존재) |
🔚 결론
Blake2b는 성능을 위해 하드코딩된 메모리 최적화를 사용하는 만큼, 컴파일러의 정적 검사와 자주 충돌합니다. 경고 무시는 빠른 해결책이지만, 실제 문제가 아닌지 확인하고 우회 설정을 적용하는 것이 가장 안전한 방식입니다.
코드 한 줄로 해결되지만, 무시된 경고 속에 숨어있는 진짜 문제도 함께 감지하는 습관이 필요합니다.
답글 남기기