2009-10-29 2 views
0

Определяет область действия переменной, декларации или определения?Определяет ли объявление или определение область видимости переменной в C++?


документация, я прочитал говорит, что декларация определяет сферу, но мой собственный тест сказал наоборот:

я получаю «неопределенную ссылку на I» ошибку с линкером:

#include <iostream> // Stream declarations 
using namespace std; 
    extern int i; //declaration 
int prueba(); 

int main() { 
    int i; //Definition 
    i=6; 
    prueba(); 
} ///:~ 

int prueba(){ 
    cout << i; //cannot access to the scope of i; 
} 
+0

Этот вопрос имеет смысл только там, где декларация отличается от определения, что очень редко. Итак, если вы могли бы привести нам пример случая, о котором вы беспокоитесь, я уверен, что мы сможем ответить на него. –

+0

Отличие между определением и декларированием имеет смысл только для типов/функций, не так ли? Можно ли провести это различие с переменными? – jalf

+0

Я думаю, что @Michael Burr также указывает, что этот вопрос имеет «легкий» ответ, который просто говорит, что область действия * имя * является ее декларацией и «подробным, но громоздким» ответом, который фактически объясняет сферу действия переменной и который имеет множество особых случаев. Не уверен, что вопрос на самом деле требует. –

ответ

0

Определение определяет область действия.

1

Он входит в область применения ... декларатора определения. так

int x=3; 
{ 
    int x=x; // x is initialized to itself, uninitialized. 
} 

изофермионного C++ спецификации, к сожалению, не в свободном доступе, поэтому я не могу процитировать главу и стих.

4

Декларация. Вы можете объявить что-то внешнее, и оно видно в этом файле, независимо от того, где оно было определено. Аналогично, функция отображается везде, где она объявлена.

Кроме экстернов и функции, хотя, я не могу придумать способ, чтобы объявить переменную, которая также не определить его ...

EDIT: Ото, статические (глобальные) переменные, область является определяемый определением, которое ТАКЖЕ декларация.

РЕДАКТИРОВАТЬ 2: В принципе, я считаю, что у вас действительно нет определения, которое не является ТАКЖЕ декларацией. поэтому единственными интересными случаями являются то, что декларация не является также определением, и это в основном extern с глобальным в другом файле и объявлениями функций ...

+0

Хорошо, что большинство деклараций также являются определениями. –

+1

В C++ использование объявлений - это еще один способ объявить то, что не определяет его. –

+0

@litb - Я был уверен, что будет что-то C++, о котором я забыл. Несмотря на то, что они не скрыты, использование деклараций - это не совсем повседневные вещи (по крайней мере для меня). –

2

Оба определяют область действия - это просто, что они определяют область действия из тонко разных вещей.

Определение объекта в C/C++ определяет, в какой области видится фактический объект и определяет «наибольшую область видимости для объекта или функции».

Декларация определяет, при котором сфера конкретный «экземпляр» имени виден в.

Например, глобальная переменная определена в глобальном масштабе (конечно) и потенциально видны в глобальном масштабе или его более жесткий объем. Но следующее объявление глобальной переменной, g_var, видна только в функции foo():

void foo(void) 
{ 
    extern int g_var; // the variable g_var has global scope, but this 
         // declaration has function-level scope 

    printf("g_var is: %d\n", g_var); 
} 

Brian Postow's point, что это различие касается действительно только для глобальных переменных и функций, является хорошим, чтобы иметь в виду.

0

От online version стандарта C:

6.1.2.3 Имя метка является единственным видом идентификатора, который имеет функцию объема. Его можно использовать (в инструкции goto) где-нибудь в функции, в которой он появляется, и объявляется неявно его синтаксическим видом (за которым следует a: и инструкция).

6.2.1.4 Каждого другой идентификатор имеет объем определяется путем размещения его декларации (в описателе или спецификатора типа). Если описатель или спецификатор типа, который объявляет идентификатор выходит за пределы любого блока или списка параметров, то идентификатор имеет файл охват, который заканчивается в конце блока перевода. Если описатель или спецификатор типа, который объявляет идентификатор появляется внутри блока или в списке параметров деклараций в определении функции, идентификатор имеет блок объем, который заканчивается в конце соответствующего блока. Если описатель или спецификатор типа, который объявляет идентификатор появляется в списке деклараций параметров в функции прототипа (не является частью определения функции ), идентификатор имеет прототип функции сферы, которая заканчивается в конце функция декларатор. Если идентификатор обозначает два разных объекта в с таким же пространством имен, области могут быть перекрываются. Если это так, то область одного объекта (внутренняя область) будет строгим поднабором области действия другого объекта (внешний охват) . В пределах внутренний объем, идентификатор обозначает объект, объявленный в внутренней области ; объект, объявленный в , внешняя область скрыта (а не видна) во внутренней области.

Emphasis mine.

Смежные вопросы