본문으로 건너뛰기
Previous
Next
C++ Undefined Behavior : Why Release-Only Crashes Happen

C++ Undefined Behavior : Why Release-Only Crashes Happen

C++ Undefined Behavior : Why Release-Only Crashes Happen

이 글의 핵심

Undefined behavior in C++: out-of-bounds access, uninitialized reads, signed overflow, data races. Debug vs release, UBSan, and why compilers assume UB never happens.

UB often surfaces as crashes—see [segmentation fault](/en/blog/cpp-error-02-segmentation-fault/ debugging.

Introduction: “Debug is fine; Release crashes”

“With optimizations enabled, behavior changes”

Undefined behavior (UB) means the C++ standard imposes no requirements on what happens. Compilers assume UB does not occur and may optimize aggressively.

int arr[5] = {1, 2, 3, 4, 5};
int x = arr[10];  // UB: out-of-bounds read

This article covers:

  • Fifteen common UB patterns (grouped)
  • Why Debug and Release differ
  • UBSan and complementary tools
  • How optimizations interact with UB
  • Short case studies

Table of contents

  1. What is UB?
  2. UB patterns
  3. Debug vs Release
  4. UBSan
  5. Compiler optimization and UB
  6. Case studies
  7. Summary

1. What is undefined behavior?

Definition

If a program has undefined behavior, any outcome is allowed: crash, wrong results, or “impossible” optimizations.

UB vs implementation-defined vs unspecified

TermMeaning
UndefinedNo standard guarantee
Implementation-definedCompiler documents behavior
UnspecifiedOne of several allowed outcomes

2. UB patterns (representative)

  1. Out-of-bounds access
  2. Null pointer dereference
  3. Dangling pointer use
  4. Reading uninitialized automatic variables
  5. Signed integer overflow (int)
  6. Violating strict aliasing rules
  7. Using an object outside its lifetime
  8. Data races
  9. Mismatched allocation/deallocation
  10. Unsequenced conflicting side effects on the same scalar
  11. Invalid pointer arithmetic and dereference
  12. Misaligned access via casts (platform-dependent)
  13. Dangerous virtual calls during construction/destruction (design-dependent)
  14. Modifying string literals
  15. Type punning without memcpy/std::bit_cast where required

3. Debug vs Release

Debug often initializes stack slots or uses patterns that mask bugs; Release may leave variables uninitialized and optimize using “UB cannot happen” reasoning.

4. UBSan

g++ -g -fsanitize=undefined -std=c++17 -o myapp main.cpp
./myapp

Combine with -fsanitize=address and -fsanitize=thread where appropriate (separate builds often).

5. Compiler optimization and UB

Examples: null checks that become unreachable after illegal dereference assumptions; x + 1 > x treated as always true for signed int when overflow is assumed impossible.

6. Case studies (short)

  • Game server: signed underflow in combat math—use saturating or wider types.
  • Image processing: kernel indexing without border checks—clamp or loop interior only.
  • Finance: summing int prices—use long long or checked accumulation.

Summary

UB prevention checklist

  • Initialize before read
  • Validate indices and lifetimes
  • Avoid signed overflow; use wider types or checks
  • Synchronize shared data
  • Match new[]/delete[]
  • No data races

Sanitizer overview

ToolFocus
UBSanMany UB rules
ASanMemory errors
TSanData races

Rules

  1. UB is not “bad luck.”
  2. Debug passing does not prove Release safety.
  3. Use sanitizers in CI.
  4. Treat warnings seriously.
  5. Prefer RAII and safe abstractions.


Keywords

undefined behavior, UB, UBSan, release-only crash, signed overflow, data race

Practical tips

  • Enable UBSan during development for representative runs.
  • Test optimized builds regularly—not only Debug.
  • Add sanitizers to CI for main branches.

Closing

Undefined behavior is among the most dangerous C++ issues. Combine warnings, sanitizers, and sound types to ship reliable code. Next: RAII and smart pointers.


자주 묻는 질문 (FAQ)

Q. 이 내용을 실무에서 언제 쓰나요?

A. Undefined behavior in C++: out-of-bounds access, uninitialized reads, signed overflow, data races. Debug vs release, UBS… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.

Q. 선행으로 읽으면 좋은 글은?

A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.

Q. 더 깊이 공부하려면?

A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.


같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.


이 글에서 다루는 키워드 (관련 검색어)

C++, Undefined behavior, UB, Crash, Debugging, Release build, UBSan 등으로 검색하시면 이 글이 도움이 됩니다.