프로그래밍수석 C 개발자, 시스템 프로그래머

C 언어에서 함수 인자의 계산 시 부작용이 어떻게 발생하나요? 인자의 계산 순서는 어떻게 되며, 여기서 발생할 수 있는 예기치 않은 상황은 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변

C 언어에서 함수 인자의 계산 순서는 표준에 의해 정의되지 않았다 (C99 이전까지). 인자가 좌에서 우로, 우에서 좌로 또는 컴파일러나 아키텍처의 재량에 따라 어떤 순서로든 계산될 수 있다.

  • 모든 표현식/부작용은 함수 호출 전에 완료되어야 하지만, 특정한 순서로 실행된다는 보장은 없다.
  • 이는 여러 인자에서 값을 변경하는 변수를 사용하는 것이 잠재적인 정의되지 않은 동작(unknown behavior)이나 아키텍처 간 차이의 원인이 될 수 있음을 의미한다.

예시

void fn(int a, int b) { /* ... */ } int x = 1; fn(x++, x++); // x++ 및 x++의 계산 순서는 정의되지 않음!

속임수 질문

"C에서 함수 인자가 어떤 순서로 계산되며, 코드를 작성할 때 이를 신뢰할 수 있나요?"

흔한 실수는 인자가 좌에서 우로 계산된다고 생각하는 것이다 (표현식과 유사하게). 실제로 각 함수 호출은 컴파일러(및 플랫폼)의 재량에 따라 컴파일된다.

void foo(int a, int b, int c); int x = 1; foo(x++, x++, x++); // 결과는 인자 계산 순서에 따라 달라짐

정확한 답변: 신뢰할 수 없다 — 동작이 정의되지 않았다!

이 주제에 대한 지식 부족으로 인한 실제 오류 예


이야기

다중 플랫폼 제품에서 프로그래머가 push(stack, stack->size++, data);를 작성했다. 대부분의 플랫폼에서 모두 작동했지만, 한 플랫폼에서는 데이터를 전달하기 전에 스택 크기가 증가했고, 다른 플랫폼에서는 이후에 증가했다. 데이터가 "손실"되거나 잘못 주소 지정되었고, 오류는 드물게 발생하고 디버깅이 매우 어려웠다.


이야기

네트워크 프로토콜 라이브러리에서 로그 함수가 통계 카운터를 증가시키는 표현식을 인자로 호출되었다. 통계 보고서는 잘못 생성되었고, 서로 다른 클라이언트에서 카운터의 인덱스가 다르게 나타났으며, 이는 예상된 순서로 실행되지 않았기 때문이었다.


이야기

장비 제어 인터페이스에서 초기화 함수가 포인터와 오프셋을 인자로 전달하며 증가시킨 경우(예: init(ptr++, cnt++);). 어떤 프로세서에서는 하드웨어가 올바르게 초기화되었고, 다른 프로세서에서는 오류가 발생했다. 하드웨어를 오랫동안 조사했지만 원인은 잘못된 C 코드에 있었다.