programing

GCC: 상수 변수가 .rodata에 없는 이유

stoneblock 2023. 9. 16. 08:29

GCC: 상수 변수가 .rodata에 없는 이유

가 GCC 을 라 요 요 라 을 static const에에 .rodata트로).textELF 또는 그러한 파일의 최적화를 위한 세그먼트(segments).하지만 그렇지 않은 것 같습니다.

저는 입니다를 사용하고 .gcc (GCC) 4.7.0 20120505 (prerelease)GNU/Linux가 탑재된 노트북에서 사용할 수 있습니다.ΔΔ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ, .bss세그먼트:

/*
 * this is a.c, and in its generated asm file a.s, the following line gives:
 *   .comm a,4,4 
 * which would place variable a in .bss but not .rodata(or .text)
 */
static const int a;

int main()
{
    int *p = (int*)&a;
    *p = 0;  /* since a is in .data, write access to that region */
             /* won't trigger an exception */
    return 0;
}

그렇다면 이것은 버그일까요, 아니면 기능일까요?버그질라에 버그로 제출하기로 했는데 먼저 도움을 요청하는 게 나을 수도 있습니다.

가 GCC 에서 가 를 할 에 const 변수를 두지 ?.rodata?

업데이트됨:

인 초기화: 한 를 한 :const int a = 0;)는 ) 됩니다에 .rodataGCC를 통해 변수를 초기화하지 않은 상태로 두었습니다.따라서 이 질문은 나중에 종결될 수도 있습니다. 아마 저는 정확한 질문을 제시하지 못했을 것입니다.

또한 이전 글에서 변수 a가 '.data' 섹션에 있다고 적었는데, 이는 틀렸습니다.그것은 실제로 그들에게 놓여져 있습니다..bss초기화되지 않은 이후의 구간.지금 위의 글이 수정되었습니다.

컴파일러는 이를 일반화했고, 호환되는 다른 기호와 병합할 수 있으며, 명시적으로 초기화된 정의가 없으면 bss(디스크 공간을 사용하지 않음)로 이동할 수 있습니다.이를 로데이터에 넣는 것은 균형을 유지하는 것입니다. 런타임에 메모리를 절약(커밋 차지)하지만 디스크의 공간을 더 많이 사용하게 됩니다(대규모 어레이에 사용할 가능성이 있음).

에 에 ,-fno-commonGCC에 대한 옵션.

GCC가 하는 거지?개발자들에게 직접 묻지 않고는 그 질문에 제대로 답할 수 없습니다.만약 제가 추측해도 된다면, 최적화와 관련된 것이라고 장담합니다. 컴파일러들이 규칙을 강요할 필요가 없기 때문입니다.

그렇기는 하지만 언어 자체, 특히 정의되지 않은 행동을 보면 더 좋다고 생각합니다.정의되지 않은 행동에 대해서는 몇 가지 언급이 있지만, 그 중 어떤 것도 심도 있게 언급되지 않습니다.

상수 수정은 정의되지 않은 동작입니다.Const는 계약이며, 특히 C(및 C++)에서 그러합니다.

"하지만 만약 내가const_cast어떻게든 수정하고 싶은 거죠?"그러면 행동이 명확하지 않은 거죠.

정의되지 않은 동작이 의미하는 것은 컴파일러가 말 그대로 원하는 것은 무엇이든 할 수 있으며 컴파일러가 결정하는 것은 ISO 9899 표준을 위반하는 것으로 간주되지 않는다는 것입니다.

3.4.3

정의되지 않은 1가지 행동

휴대가 불가능하거나 잘못된 데이터의 프로그램 구성자를 사용할 때, 본 국제 표준이 요구 사항을 부과하지 않는 거동

2 참고 예측할 수 없는 결과로 상황을 완전히 무시하는 것부터 번역 또는 프로그램 실행 중에 환경의 특성을 나타내는 문서화된 방식으로 행동하는 것(진단 메시지의 발행 여부에 관계없이)까지 가능한 미정의 행동,(진단 메시지 발행과 함께) 번역 또는 실행을 종료합니다.

ISO/IEC 9899:1999, §3.4.3

이것이 의미하는 바는, 당신이 정의되지 않은 동작을 호출했기 때문에, 컴파일러가 하는 모든 것은 틀리지 않음으로써 기술적으로 정확하다는 것입니다.에르고, GCC가...

static const int a = 0;

을...그리고 그것을 a로 바꿉니다..rodata상징적으로...

static const int a; // guaranteed to be zero

을...그리고 그것을...bss기호.

전자의 경우, 모든 수정 시도가a일반적으로 (프록시에 의해서도) 분할 위반이 발생하여 커널이 실행 중인 프로그램을 강제로 죽일 수 있습니다.후자의 경우 프로그램이 충돌하지 않고 실행될 가능성이 높습니다.

그렇다고 해서 컴파일러가 어떤 것을 할지 추측하는 것은 타당하지 않습니다.Const는 계약이며, 일정해야 할 데이터를 수정하지 않음으로써 계약을 유지하는 것은 프로그래머인 당신에게 달려 있습니다.이 계약을 위반한다는 것은 정의되지 않은 행동과 그에 수반되는 모든 휴대성 문제 및 프로그램 버그를 의미합니다.

그래서 GCC는 몇 가지를 할 수 있습니다.

기호를 .rodata에 기록하여 OS 커널 아래에서 보호할 수 있습니다.

메모리 보호가 보장되지 않는 곳에 개체를 쓸 수도 있습니다. 이 경우...

이 변경될 수 있습니다.

을 변경한 후 즉시 다시 변경할 수 있습니다.

값이 변하지 않는다는 이유로 가해 코드를 완전히 삭제할 수 있습니다 (0 -> 0 으로 ...

int main(){
    int *p = &a;
    *p = 0;
    return 0;
}

...할...

int main(void){
    return 0;
}

당신이 태어나기 전에 부모님을 종료시키기 위해 T-800 기종을 제 시간으로 되돌려 보낼 수도 있습니다.

이 모든 행동은 합법적이며(표준을 준수한다는 의미에서 합법적입니다), 그래서 버그 보고는 정당하지 않았습니다.

선언된 개체에 쓰기const자격은 정의되지 않은 행동입니다. 어떤 일이든 일어날 수 있습니다. 심지어 그것도 말입니다.

C에서는 개체 자체가 불변임을 선언할 방법이 없으며, 개체에 대한 특정 접근을 통해 개체 자체가 불변임을 선언할 수 없습니다.여기 있습니다.int*, 따라서 컴파일러가 진단서를 발행하도록 강요받지 않는다는 점에서 수정은 "수정"입니다.C에서 깁스를 한다는 것은 자신이 무엇을 하고 있는지 알아야 한다는 것을 의미합니다.

GCC가 .rodata에 상수 변수를 넣을 수 없는 이유가 있습니까?

당신의 프로그램은 컴파일러에 의해 최적화됩니다 (심지어는-O0일부 최적화가 완료됨).지속적인 전파 수행: http://en.wikipedia.org/wiki/Constant_folding

컴파일러를 다음과 같이 속이려고 합니다(이 프로그램은 여전히 기술적으로 정의되지 않은 동작입니다)

#include <stdio.h>

static const int a;

int main(void)
{
    *(int *) &a = printf("");  // compiler cannot assume it is 0

    printf("%d\n", a);

    return 0;
}

언급URL : https://stackoverflow.com/questions/10818761/gcc-why-constant-variables-not-placed-in-rodata