Problem ze rozumieniem zachowania gcc

0

Witam, mam problem, który objaśnię niewielkim kodem:

test1.c:

 
#include <stdio.h>
#include "test2.h"

char bufor[100];

int main (int argc, char **argv)
{
	bufor[0] = 'B';
	make_data();
	printf("%s\r\n", bufor);
	return 0;
}

test2.c

#include <stdio.h>
#include "test2.h"

char bufor[11];

void make_data(void)
{
	int i;

	for(i = 0; i < sizeof(bufor)-1; i++)
	{
		bufor[i] = 'A';
	}
	bufor[i] = 0x00;
}

test2.h:

void make_data(void);

teraz kompilacja i wykonanie:

# gcc test1.c test2.c -o test -Wall
# ./test
AAAAAAAAAA
#

WTF?

0

wydaje mi się, że powinieneś dodać słówko static:
static char bufor[11];
static char bufor[100];

ponieważ bez tego zmienne oraz funkcje są widoczne we wszystkich jednostkach kompilacji, tylko trzeba kompilator poinformować o ich istnieniu

0

Dlaczego kompilator nie daje żadnych ostrzeżeń?

0

Ciekawe, g++ daje ostrzeżenia.

/tmp/ccTItELk.o:(.bss+0x0): multiple definition of `bufor'
/tmp/ccVIr5U5.o:(.bss+0x0): first defined here
/usr/bin/ld: Warning: size of symbol `bufor' changed from 100 in /tmp/ccVIr5U5.o to 11 in /tmp/ccTItELk.o
collect2: ld returned 1 exit status

Pewnie to jakiś feature języka

0

Taki kod przyprawia o palpitację serca...

Poczytaj "Why global variables are evil":
http://www.learncpp.com/cpp-tutorial/42-global-variables/

0

tcc zachowuje się tak samo

0

Ten problem w ogóle nie dotyczy kompilatora tylko linkera.

ld zgłasza warning:

ld napisał(a)

/tmp/ccemIl3S.o: warning: common of `bufor' overridden by larger common
/tmp/ccALavXW.o: warning: larger common is here

W manie można przeczytać o tym:

man ld napisał(a)

The linker merges multiple common symbols for the same variable into a single symbol. If they are of different sizes, it picks the largest size.

W C taka globalna zmienna jest tylko zdeklarowana i nie zdefiniowana (common symbol). W C++ deklaracja takiej zmiennej od razu jest definicją i linker nie wie co ma począć z dwiema definicjami. Kiedy doda się definicję tych zmiennych w obu plikach gcc pokazuje ten sam błąd linkera co g++.

1 użytkowników online, w tym zalogowanych: 0, gości: 1