Redeklaracja zmiennej, wolno czy nie wolno?

0

Program:

#include <iostream>
using namespace std;

int main()
{

	extern int x; // declaration
	int x = 42;   // definition
	cout<<x<<endl;
}

Kompilacja:

maciek@corei3:~/Pulpit/C++$ g++ plik.cpp
plik.cpp: In function ‘int main()’:
plik.cpp:8:6: error: redeclaration of ‘int x’
  int x = 42;   // definition
      ^
plik.cpp:7:13: note: previous declaration ‘int x’
  extern int x; // declaration

Dlaczego kompilator wywala "redeklaracja int x" czyż w Symfonii C++ nie jest napisane iż zmienną można deklarować tyle razy ile się chce, a dopiero definicję można wykonać tylko raz?

3

Tu problemem jest zakres zmiennej.
extern int x; ma sens tylko dla zmiennych globalnych, których powinno się unikać (a na pewno już w bibliotekach).
W kontekście zmiennej lokalnej ten zapis nie ma sensu i najwyraźniej twój kompilator ignoruje to słowo kluczowe.

Ze zmienią globalną jest jak piszę Grębosz
https://wandbox.org/permlink/1dXIsUeOtcNJ9SB4

Zresztą clang mówi że mu twój kod nie pasuje, w bardziej logiczny sposób:
https://wandbox.org/permlink/ajTPERaxIHGRWOG6

prog.cc:8:9: error: non-extern declaration of 'x' follows extern declaration
int x = 42;   // definition

A tu masz wariację, która pokazuje, że extern wychodzi poza scope main (dla clang).
https://wandbox.org/permlink/BYB32LIYpaSmgeWk

3

extern wewnątrz funkcji nie jest kompletnie bez sensu - zakres widoczności jest wtedy ograniczony do tej funkcji (albo innego zakresu wewnątrz którego jest ta deklaracja) a zadeklarowany identyfikator zmiennej traktowany jest jak lokalny. Niemniej jednak odnosi się on do identyfikatora poza funkcją, np:

#include <iostream>
using namespace std;

int main()
{
    extern int x; // declaration
    cout<<x<<endl;
}
int x = 42;   // definition

https://wandbox.org/permlink/ogApOZ0n1m9lObR1

Ponieważ extern int x powoduje, że występuje już identyfikator x w głównym zakresie funkcji main() to nie możesz zdefiniować go po raz kolejny.

0

Czyli w jednej funkcji może być tylko jedna deklaracja tej samej zmiennej?

2

Czyli w jednej funkcji może być tylko jedna deklaracja tej samej zmiennej?

Nie w jednej funkcji a w jednym bloku:

int main()
{
    extern int x; // declaration
    cout<<x<<endl;
    {
        int x = 24;  //local for scope
        cout<<x<<endl;
    }
}
int x = 42;   // definition
2
Delor napisał(a):

Czyli w jednej funkcji może być tylko jedna deklaracja tej samej zmiennej?

Nie w jednej funkcji a w jednym bloku:

int main()
{
    extern int x; // declaration
    cout<<x<<endl;
    {
        int x = 24;  //local for scope
        cout<<x<<endl;
    }
}
int x = 42;   // definition

Tyle że to nie jest "ta sama zmienna", tylko niezależne zmienne o tej samej nazwie.
Nie daje to niczego pozytywnego, a myli we wzrokowym przeglądzie kodu, w nowszych językach bywa zakazane

2

W takim razie tak:

int main()
{
    extern int x; // declaration
    cout<<x<<endl;
    {
        extern int x;  //declaration
        cout<<x<<endl;
    }
}
int x = 42;   // definition

Deklaracja zmiennej drugi raz w tej samej funkcji.
Właściwie to nawet tak:

int main()
{
    extern int x; // declaration
    extern int x;  //declaration
    cout<<x<<endl;
}
int x = 42;   // definition
2

Redeklaracja tej samej zmiennej jest dozwolona. Problemem w oryginalnym poście jest to, że deklaracja extern deklaruje zmienną spoza zakresu funkcji, ale nadaje jej identyfikator wewnątrz obecnego zakresu (odpowiednie {} w funkcji). Definicja zmiennej o tej samej nazwie zdefiniowałaby inną zmienną (na potrzeby przykładu nazwijmy ją main()::x) i dodałaby identyfikator x w odpowiednim zakresie - ale to już niemożliwe, bo taki jest nadany dla innej rzeczy.

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