programing

.bss vs COMMEN: 어디로 가는 거지?

codeshow 2023. 10. 9. 23:42
반응형

.bss vs COMMEN: 어디로 가는 거지?

내 책에서:

.bss:

초기화되지 않은 전역 C 변수

공통:

아직 할당되지 않은 초기화되지 않은 데이터 개체

제가 말씀드릴 수 있는 것은 확실한 차이는 보이지 않습니다.초기화되지 않은, 할당되지 않은 데이터 객체가 뭔지도 잘 모르겠어요...아무것도 아닌 것 같습니다.의 GNU다를해 봤습니다.readelf간단한 C 코드를 살펴보려 하지만 공통 기호를 찾을 수 없는 도구입니다. FORTRAN의 COMMEN TYPE다는

누가 나를 위해 그 둘을 구별해 줄 수 있습니까?만약 가능하다면, 바라건대 C 예?대단히 감사합니다.

edit: 이 게시물에서 변수 여기:

int c;
int main() {} ...

하지만 를 합니다. 하지만 사용하는 것은.objdump -tc가 .bss다에 .

혼란스러운

// file a.c
// file-scope

int a = 0;  // goes into BSS

a.ca.o,a기호는 BSS 섹션으로 들어갑니다.

// file b.c
// file-scope

int b;  // goes into COMMON section

b.cb.o,b기호는 COMMEN 섹션으로 들어갑니다.

a.o그리고.b.o,둘다요.a그리고.b기호는 BSS 섹션으로 들어갑니다.공통 기호는 실행 파일이 아닌 개체 파일에만 존재합니다.유닉스의 COMMEN 심볼은 특정 조건에서 하나의 공통 심볼 아래에서 동일한 변수(다른 컴파일 단위)의 여러 외부 정의를 허용하는 것입니다.

공유물은 연결 단계 전에만 나타납니다.공통은 나중에 bss나 데이터 ‚에 들어가는 것이지만 어디로 갈지는 링커에게 달려 있습니다.이렇게 하면 서로 다른 컴파일 단위에서 동일한 변수를 정의할 수 있습니다. 한 한,입니다가 것으로 알고 있습니다.int foo; 안에extern int foo;.

작동 방식은 다음과 같습니다.

$ cat > a.c
int foo;
$ cat > b.c
int foo;
$ cat > main.c
extern int foo;
int main(int argc, char **argv) { return foo; }
$ cc -c a.c && cc -c b.c && cc -c main.c && cc -o x a.o b.o main.o
$ objdump -t a.o | grep foo
0000000000000004       O *COM*  0000000000000004 foo
$ objdump -t b.o | grep foo
0000000000000004       O *COM*  0000000000000004 foo
$ objdump -t x | grep foo
0000000000600828 g     O .bss   0000000000000004              foo
$

이것은 여러 컴파일 단위에 있는 변수 중 최대 하나가 초기화된 경우에만 작동합니다.

$ echo "int foo = 0;" > a.c
$ cc -c a.c && cc -c b.c && cc -c main.c && cc -o x a.o b.o main.o
$ echo "int foo = 0;" > b.c
$ cc -c a.c && cc -c b.c && cc -c main.c && cc -o x a.o b.o main.o
b.o:(.bss+0x0): multiple definition of `foo'
a.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
$

이것은 고대 시스템과 호환되는 무서운 것입니다. 그리고 절대로 그것에 의존해서는 안됩니다.모든 컴파일 단위에서 전역 변수의 한 가지 정의만 제대로 수행하고, 헤더를 통해 다른 모든 곳에서 전역 변수를 선언합니다.

.common서로 다른 유닛을 연결하는 동안 동일한 변수를 선언할 수 있고 링크러는 동일한 위치에 그들을 찾을 수 있습니다.유형이 동일할 필요도 없기 때문에 일종의 링크 타임 유니온입니다.가입니다.COMMONFortran 의 특집입니다.허락하지 않으시면common그러면 C를 링크할 때, 그러한 상황은 링크 타임 에러를 초래할 것입니다.그런common링크는 초기화되지 않은 전역에 대해서만 가능합니다. 그렇지 않으면 어떤 초기화를 수행해야 할지 불분명하기 때문입니다.

세계인들은 앞으로bss는 C가 0으로 초기화된 것으로 정의하는 초기화되지 않은 전역일 뿐입니다.대부분의 객체 형식은 크기만 지정된 섹션을 지원하며 로더는 전체 섹션을 0으로 채웁니다.

P.S: 사용하는 경우gcc당신은 사용할 수 있습니다.-fno-common강제 옵션common에 대한 상징.bss아트가 주장하는 바와 같이 섹션은 좋고 권장되는 실천입니다.

static variables는 .bss 섹션에 들어갑니다.초기화되지 않은 전역 변수(정적 변수가 아님)는 .common 섹션에 들어갑니다.

static a;  //bss
int c;   //.common
main(){
}

언급URL : https://stackoverflow.com/questions/16835716/bss-vs-common-what-goes-where

반응형