Powodem definiowania zmiennej zewnętrznej wewnątrz funkcji nie ma sensu jest następujący:
Kiedy deklarujesz symbolem extern, mówisz kompilatora, aby połączyć wszystkie te wystąpienia tej wartości w tym samym symbolem. Wszelkie wystąpienia extern int i; w twoim programie łączyłoby się z zewnętrznie zdefiniowanym i. Spójrz na ten przykład:
#include <iostream>
using namespace std;
extern int i;
int i = 10;
void test()
{
std::cout << "Hi" << i << std::endl;
}
int main()
{
extern int i;
i++;
test();
}
Ten przykład powinien wypisać hi11. HOwever, jeśli usuniemy zewnętrzny plik wewnątrz głównego, wyprowadzi on 10. To dlatego, że bez zewnętrznego, nie łączę się z globalnym i, ale tworzę jego własną lokalną kopię i.
Powód, dla którego zdefiniowanie extern i wewnątrz funkcji nie ma sensu, jest tym, o ile pozwolimy jakiejkolwiek funkcji "zdefiniować". Która funkcja działa pierwsza? Kiedy zostanie zdefiniowany?
Załóżmy następujący przykład, aby był ważny, jaki byłby wynik ???
#include <iostream>
using namespace std;
extern int i;
int i = 10;
void test()
{
std::cout << "Hi" << i << std::endl;
}
void test2() {
extern int i = 1000;
std::cout<< "HI" << i << std::endl;
}
void test3() {
extern int i;
i = 1000;
std::cout<< "HI" << i << std::endl;
}
int main()
{
extern int i;
i++;
test();
i = 0;
test2();
}
Czy wyjście test2 powinno wynosić 0, czy 1000? Spójrz też na mój test3, tutaj zwięźle mówimy, połącz moje i do zewnętrznego zdefiniowanego i, i przypisz mu wartość jako 1000. To bardzo różni się od próby "zainicjowania" wartości.
W skrócie, zmienne zewnętrzne mają sens tylko jako globale i powinny być zdefiniowane w zasięgu globalnym. W twoich przykładach pierwsza wersja też mnie nie kompiluje. Uważam to za interesujące. Warto przyjrzeć się dokumentom standardowym, aby zobaczyć, czy jest to zwięźle określone, lub czy Twój kompilator może obsługiwać to w sposób zaprojektowany w celu dodania dodatkowej ochrony ...
ponieważ standard twierdzi, że jest nieprawidłowy? –
Zaskakuje mnie, że pierwszy kompiluje ... czy możesz podać więcej tła? Używam G ++ v4.2.1 – ChrisCM
@JonatanGoebel Kiedy standard zdefiniowałby taką rzecz, mieliby (głównie) racjonalne uzasadnienie. Chciałem poznać możliwy powód takiego ograniczenia. [Coś na linii, jak zachowanie czegoś niezdefiniowanego pomaga kompilatorowi]. –