Problem ze rozumieniem zachowania gcc

Odpowiedz Nowy wątek
2011-09-27 13:54
Marcin
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?

Pozostało 580 znaków

2011-09-27 14:27
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


░█░█░█░█░█░█░█░█░█░█░█░
edytowany 1x, ostatnio: krwq, 2011-09-27 14:28

Pozostało 580 znaków

2011-09-27 14:33
Marcin
0

Dlaczego kompilator nie daje żadnych ostrzeżeń?

Pozostało 580 znaków

2011-09-27 14:56
ciekawe
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

Pozostało 580 znaków

2011-09-27 15:05
0

Taki kod przyprawia o palpitację serca...

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


Szacuje się, że w Polsce brakuje 50 tys. programistów
Pokaż pozostałe 3 komentarze
Mnie nie przeszkadza, że ktoś używa, ale z czasem sam doszedłem do wniosku, że zmienne globalne są po prostu nie wygodne w większych programach. W małych programikach mi nie przeszkadzają. - krwq 2011-09-27 18:31
Stałe to nie zmienne globalne, przynajmniej nie jeśli chodzi o intencje. Dorabiasz const i jak jakiś element po tym pisze do dajesz po łapach... Zmienne globalne to też nie do końca singletony, bo do singletonów z reguły dobierasz się funkcjami. Czyste zmienne globalne to takie (##!^!@#) coś co nie wiesz gdzie albo dlaczego jest zmieniane... (jak w przykładzie z początku wątku). - vpiotr 2011-09-27 20:38
czepiasz się. - krwq 2011-09-27 20:42
No trochę tak. Ale cała inżynieria programowania to czepianie się... - vpiotr 2011-09-27 20:54
ale C# z C++ robisz :P może on pisze kod na uC... - krwq 2011-09-27 21:00

Pozostało 580 znaków

2011-09-27 15:14
tcc
0

tcc zachowuje się tak samo

Pozostało 580 znaków

2011-09-27 17:25
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++.


"(...) otherwise, the behavior is undefined".

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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