본문 바로가기
Programming Language/C++

[c++] GCC 에러 및 최적화 관련 컴파일 옵션 정리

by yongee97 2026. 2. 5.

* 환경

Ubuntu 22.04.5

g++ 11.4.0

c++ 17 기준

 

* 개요

경고 옵션 : -Wall -Wextra -Werror

최적화 옵션 : -O0/-O1/-O2

 

* 경고 옵션

1. Wall

- 자주 필요한 경고들을 묶어서 활성화하는 기능

- 코드는 동작하나, 실수 가능성이 있는 부분을 미리 감지

# wall.cpp
int main()
{
    int answer = 42;
    return 0;
}
# (1) 옵션 없음: 경고 없음
g++ -std=c++17 wall_unused_variable.cpp

# (2) -Wall: unused variable 경고 출력
g++ -std=c++17 -Wall wall_unused_variable.cpp

Wall 경고 출력

 

- 옵션 비활성화 시 : 빌드 성공

- 옵션 활성화 시 : unused variable 'answer' 경고 출력

 

2. Wextra

- 자잘하지만 실제 버그로 이어질 수 있는 코드를 감지하여 경고

- 인터페이스는 있으나 실제 구현이 없는 경우를 감지

# wextra.cpp
int add(int a, int b)
{
    return a;
}

int main()
{
    return add(1, 2);
}
# (1) 옵션 없음: 경고 없음
g++ -std=c++17 wextra.cpp
# (2) Wall : 경고 없음
g++ -std=c++17 -Wall wextra.cpp
# (3) Wextra : unused parameter 경고 출력
g++ -std=c++17 -Wall -Wextra wextra.cpp

Wextra 경고 출력

 

3. Werror

- 경고를 에러 취급

- 하나의 경고라도 뜨는 경우 빌드 실패

# (1) Wextra : unused parameter 경고 출력
g++ -std=c++17 -Wall -Wextra wextra.cpp
# (2) Werror : 경고가 에러로 변환되어 빌드 실패
g++ -std=c++17 -Wall -Wextra -Werror wextra.cpp

Werror 에러 출력

 

* 최적화 옵션

- 최적화 옵션은 실행 성능, 디버깅 편의, 바이너리 크기에 직접 영향

  • -O0: 최적화 없음(기본값). 디버깅 친화적, 성능은 낮음
  • -O1: 기본적인 최적화(일반적으로 성능 향상 체감)
  • -O2: 더 공격적인 최적화(대부분의 릴리즈 빌드에서 기본값으로 설정)
  • -O3: 매우 공격적인 최적화(루프 최적화/인라이닝 등)를 수행하며, 대신 코드 크기가 증가할 수 있음

- 최적화 별 성능 비교를 위해, 아래 예시 코드에 대하여 최적화 방법별로 빌드 후 결과 시간 출력하여 성능 비교

- 명령어 중 march=native 옵션은 로컬 CPU의 ISA를 적극적으로 활용하기 위한 옵션으로, 이 옵션을 활성화하면 이식성이 저하되어 다른 CPU에서 실행되지 않을 수 있음

- 여기선 O1과 O2의 성능 차이를 극대화하기 위해서 march=native 활성화했으며, 이 옵션을 비활성화할 경우 O1과 O2는 유의미한 차이를 보이지 않음

// opt_benchmark.cpp
#include <chrono>
#include <cstddef>
#include <iostream>
#include <vector>

static volatile float sink;

int main() {
    constexpr std::size_t N = 1u << 15;
    constexpr int R = 2000;

    std::vector<float> x(N), y(N);
    for (std::size_t i = 0; i < N; ++i) {
        x[i] = (i % 1000) * 0.001f;
        y[i] = ((i * 7) % 1000) * 0.002f;
    }

    using clock = std::chrono::steady_clock;
    auto t0 = clock::now();

    for (int r = 0; r < R; ++r) {
        for (std::size_t i = 0; i < N; ++i) {
            float v = x[i];
            v = v * 1.000123f + y[i];
            v = v * v + 0.33f;
            v = v * 0.99991f + 0.001f;
            x[i] = v;
        }
    }

    auto t1 = clock::now();

    float s = 0.0f;
    for (std::size_t i = 0; i < N; i += 31) s += x[i];
    sink = s;

    auto us = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count();
    std::cout << us << "\n";
}

 

for O in 0 1 2 3; do
  g++ -std=c++17 -O$O -march=native opt_benchmark.cpp -o demo_O$O
done

for O in 0 1 2 3; do
  echo "O$O"
  ./demo_O$O
done

최적화 방법 별 성능 비교

 

- 성능 비교 결과

  • -O0: 578582 us
  • -O1: 60499 us
  • -O2: 39589 us
  • -O3: 6831 us