2014-03-05 1 views
3

표준 C (ISO/IEC 9899 : 1999) 섹션 6.5.3.4는 sizeof의 연산자 함수 타입 또는이있는 식에 적용되지 않는다왜 표준를 금지를 sizeof 함수에 적용될

말한다 불완전 유형

왜? readelf으로 실행 파일을 검사하면 컴파일하는 동안 함수 크기를 완벽하게 알 수 있습니다.

Symbol table '.symtab' contains 67 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
....... 
    37: 0000000000400541 16 FUNC LOCAL DEFAULT 13 clean 
....... 
    46: 00000000004005f0  2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini 
...... 
    49: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_2.2.5 
    52: 00000000004005f4  0 FUNC GLOBAL DEFAULT 14 _fini 
    53: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_ 
ed 
    58: 0000000000400560 137 FUNC GLOBAL DEFAULT 13 __libc_csu_init 

    62: 000000000040052c 21 FUNC GLOBAL DEFAULT 13 main 

여기 0 크기는 공유 라이브러리, 예를 들면 [email protected]@GLIBC_2.2.5 함수로부터 함수에 속한다. 그래서 내가 libc 정보를 확인, 여기 readelf -a /lib/x86_64-linux-gnu/libc.so.6 출력의 조각이 [email protected]@GLIBC_2.2.5

      Size Type 
    ........... 
    399: 0000000000070ec0 392 FUNC WEAK DEFAULT 12 [email protected]@GLIBC_2.2.5 

관련이있다는 단순히 불필요한 기능으로, 또는 C 철학을 중단하거나, 내가 볼 수없는이 몇 가지 기술적 인 문제?

+0

만약에 함수가 인라인 되었다면? 크기를 어떻게 계산할 수 있습니까? –

답변

4

sizeofunsigned char [sizeof(type)]이라는 표현이있는 객체에서만 의미가 있기 때문에 생각합니다. 이제 C에서 함수에는 표현이 없습니다 (함수 포인터 유형에서 데이터 포인터 유형으로의 변환이 없음). sizeof이라는 의미있는 사용법이 없다고 말할 수 있습니다.

2

readelf로 실행 파일을 검사하면 컴파일하는 동안 함수의 크기를 완벽하게 알 수 있습니다.

하지만 다른 최적화 옵션과 동일한 시스템, 또는 같은 컴파일러에 다른 컴파일러 사용하여 코드를 컴파일 할 경우 gcc를 사용하는 경우,이 크기 보통 changes.For 예는, gcc -O0 사용하여 코드를 컴파일하려고 및 gcc -O2을 입력 한 다음 함수의 코드 크기를 비교하십시오.

그러나 컴파일러에서 최적화를 수행하면 최적화하려고하는 코드의 동작이 변경되지 않는다고 가정합니다. 그리고 표현식이 다른 최적화 수준에서 다른 값을 가지도록하면 코드의 동작이 변경됩니다.

어셈블러 및/또는 링커는 컴파일러에서 생성 된 어셈블리 코드에 대한 최적화 또는 수정을 수행 할 수 있으므로 일부 기능의 코드 크기가 변경 될 수 있습니다.

또한 C는 함수형 프로그래밍 언어가 아니며 함수는 1 급 클래스 객체가 아니므로 변수에 저장할 수없고 다른 함수에 인수로 전달할 수 없다는 것을 의미합니다. 함수의 크기를 얻는다.

+0

그 이유는 내가 컴파일하는 동안 알려진 기능의 크기를 확인합니다. 그들은 알려져있다. 컴파일 중에 알려진 크기 인 경우 sizeof는 현재 컴파일의 함수 크기를 현재 최적화 수준으로 반환 할 수 있습니다. – Dabo

+0

하지만 컴파일러가 최적화를 시도해도 최적화하려고하는 코드의 동작은 변경되지 않습니다. 그리고 표현식이 다른 최적화 수준에서 다른 값을 가지도록하면 코드의 동작이 변경됩니다. –

+2

컴파일러는 링크 시간에 더 최적화 될 수 있기 때문에 함수의 마지막 크기를 알지 못합니다. –

1

C의 주된 요점은 명령어를 추상화하므로 프로그램의 2 진 표현을 다룰 필요가 없다는 것입니다. 이는 어셈블러에 비해 많은 장점을 제공합니다. 주로 생산성, 이식성이 향상되었습니다.

어쨌든 데이터에 액세스하거나 복사 할 수 없기 때문에 모든 기능이 유용하지는 않습니다. 시스템은 실행 가능 메모리를 실행 전용으로 표시 할 수 있으므로 필요한 C 표준 당신은 그런 시스템에서 구현 될 수없는 것들을 할 수 있어야합니다.

컴파일이 훨씬 어려울 것입니다.근본적으로 모든 것이 끝나면 기능의 크기를 채우는 것으로 돌아가는 별도의 패스가 필요합니다.

말하자면 엄청나게 멋진 기능 일 것입니다. if (sizeof (* function) == 0)이 인라인되었는지 등을 확인할 수 있습니다. 그러나 c99가 실제로 구현되지 않았다고 생각하면 어디서나, 나는 심지어 최선의 경우 시나리오 하에서는 2050 년 이전에 쉽게 사용할 수 없다고 말할 것이다.

+0

다른 리버스 엔지니어링 작업에 유용 할 수도 있고 작은 임베디드 시스템에 유용 할 수도 있습니다. 그러나 그것은 단지 추측 일 뿐이며 실제로는 함수의 크기를 알 필요가 없습니다. – Dabo