2016-07-25 10 views
6

하나처음 나는 다음과 같은 C 코드가 C99 및/또는 C11 표준 (들)을 준수하는지 여부를 알고 싶습니다

void foo(int bar0, int bar1, int bar2) { 
    int *bars = &bar0; 

    printf("0: %d\n1: %d\n2: %d\n", bars[0], bars[1], bars[2]); 
} 

int main(int argc, char **argv) { 
    foo(8, 32, 4); 

    return 0; 
} 

이 코드를 컴파일

0 : 8
1 : 32
2 : 4

예상 비주얼 스튜디오 2013 인쇄를 사용하는 경우와 실행 0
+1

호기심을 만족 시키려고 하시겠습니까? 아니면 문제가 해결 될 것이라고 생각하십니까? – StoryTeller

+0

가변 인수는이 기술을 사용하여 인수를 반복하는 것처럼 보이기 때문에 호기심에서 벗어난 것입니다. –

답변

11

아니, 어디 근처.

C 표준은 함수 인수가 연속 메모리 위치 (또는 특정 주문의 경우)에 저장되는 것을 보증하지 않습니다. 함수 인수가 함수로 전달되는 방법을 결정하는 것은 컴파일러 및/또는 플랫폼 (구조)까지입니다.

더 명확하게하기 위해 전달 될 인수가 메모리 (예 : 스택)에 저장된다는 보장조차 없습니다. 그들은 하드웨어 레지스터 (적용 가능할 때마다 또는 일부를 위해)를 사용하여 작업을 빠르게 수행 할 수 있습니다. 대부분의 기능은 단일 레벨 통화 레지스터에 모든 인수를 전달할 수 있도록 예를 들어,

  • 파워

    파워 PC 아키텍처는 레지스터의 다수가 있습니다. [...]

  • MIPS

    32 비트 MIPS 대한 가장 일반적으로 사용되는 전화 협약 레지스터의 기능을 처음 네 개의 인자를 전달 O32 ABI이다 $a0 - $a3; 후속 인수는 스택에 전달됩니다. [...]

  • X86

    x86 아키텍처는 여러 가지 호출 규칙을 사용합니다. 아키텍처 레지스터의 수가 적기 때문에 x86 호출 규칙은 주로 스택에서 인수를 전달하는 반면 반환 값 (또는 그에 대한 포인터)은 레지스터에서 전달됩니다.

등등. full wiki article here을 확인하십시오.

따라서, 귀하의 경우, bars[0]유효 접근이지만, bars[1]bars[2]가 유효한지, 완전히, 기본 환경 (플랫폼/컴파일러)에 따라 달라집니다. 기대하는 행동에 의존하지 않는 것이 가장 좋습니다.

당신이 인수를 사용하지 않을 경우에는 단지 main()에 전달, 당신은 단순히 int main(void) {에 서명을 줄일 수 있습니다 (모든이 경우 ), nitpick하기 말했다.

+0

+1하지만 근대 아키텍처에서 첫 번째 함수 매개 변수가 메모리에 저장되지 않고 하드웨어 레지스터를 통과한다는 사실을 추가해야합니다. 그리고 아마도 컴파일러가 아니라 플랫폼 API라고 할 수 있습니다. –

+0

@JensGustedt 선생님, 저 앞에 더 많은 정보를 추가했습니다. 더 좋았어? –

5

표준이 지원하지 않습니다. 그것은 매우 장난입니다.

배열 색인화 및 포인터 산술은 배열에만 유효합니다. (작은 예외를 참고 :. 당신이 배열이나 스칼라 과거 포인터 하나를 읽을 수 있지만 당신이 존중 수 없습니다 그것은)

7

아니요 게시 된 표준을 준수하지 않습니다. 인수와 로컬 변수를 저장하는 방법과 컴파일러가 어디에 있는지. 한 컴파일러에서 작동 할 수있는 기능은 다른 컴파일러에서 작동하지 않을 수도 있고 동일한 컴파일러의 다른 버전에서 작동하지 않을 수도 있습니다.

C 사양은 스택을 언급하지 않고 지정하는 모든 범위 지정 규칙입니다.

+0

Variadic 함수도 표준의 일부로 보입니다. va_start, va_end는 표준 라이브러리의 일부이며, 이러한 매크로가 수행하는 것과 정확히 같습니다. 스택 매개 변수를 거쳐야합니다. – MichaelMoser

+3

@MichaelMoser 예, 매크로가 구현되는 방식은 표준에 포함되지 않습니다. 그리고 스택을 갖는 것은 C 컴파일러에 대한 요구 사항이 아닙니다 (특히 C 스펙에 없으므로). 이는 구현의 세부적인 부분입니다. –