Pregunta ¿Cuál es la diferencia entre una definición y una declaración?


El significado de ambos me elude.


707
2017-09-11 12:27


origen


Respuestas:


UN declaración introduce un identificador y describe su tipo, ya sea un tipo, objeto o función. Una declaración es lo que el compilador necesita para aceptar referencias a ese identificador. Estas son declaraciones:

extern int bar;
extern int g(int, int);
double f(int, double); // extern can be omitted for function declarations
class foo; // no extern allowed for type declarations

UN definición realmente instancia / implementa este identificador. Sus lo que el enlazador necesita para vincular referencias a esas entidades. Estas son las definiciones que corresponden a las declaraciones anteriores:

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};

Una definición puede usarse en el lugar de una declaración.

Un identificador puede ser declarado tantas veces como quieras Por lo tanto, lo siguiente es legal en C y C ++:

double f(int, double);
double f(int, double);
extern double f(int, double); // the same as the two above
extern double f(int, double);

Sin embargo, debe ser definido Exactamente una vez. Si olvida definir algo que ha sido declarado y referenciado en alguna parte, entonces el vinculador no sabe a qué vincular las referencias y se queja de los símbolos faltantes. Si defines algo más de una vez, entonces el enlazador no sabe cual de las definiciones para vincular referencias y quejas sobre símbolos duplicados.


Desde el debate, ¿qué es una clase declaración contra una clase definición en C ++ sigue apareciendo (en respuestas y comentarios a otras preguntas), pegaré aquí una cita del estándar de C ++.
En 3.1 / 2, C ++ 03 dice:

Una declaración es una definición a menos que [...] sea una declaración de nombre de clase [...].

3.1 / 3 luego da algunos ejemplos. Entre ellos:

[Ejemplo: [...]
struct S {int a; int b; }; // define S, S :: a, y S :: b [...]
estructura S; // declara S
-ejemplo

Para resumir: el estándar C ++ considera struct x; ser un declaración y struct x {}; un definición. (En otras palabras, "declaración directa" un nombre inapropiado, ya que no hay otras formas de declaraciones de clase en C ++.)

Gracias a litb (Johannes Schaub) quien desenterró el capítulo y el verso en una de sus respuestas.


720
2017-09-11 12:43



De la sección estándar de C ++ 3.1:

UN declaración introduce nombres en una unidad de traducción o redeclara nombres introducidos por anteriores   declaraciones Una declaración especifica la interpretación y los atributos de estos nombres.

El siguiente párrafo dice (énfasis mío) que una declaración es una definición a no ser que...

... declara una función sin especificar el cuerpo de la función

void sqrt(double);  // declares sqrt

... declara un miembro estático dentro de una definición de clase

struct X
{
    int a;         // defines a
    static int b;  // declares b
};

... declara un nombre de clase

class Y;

... contiene el extern palabra clave sin un inicializador o cuerpo de función

extern const int i = 0;  // defines i
extern int j;  // declares j
extern "C"
{
    void foo();  // declares foo
}

... o es un typedef o using declaración.

typedef long LONG_32;  // declares LONG_32
using namespace std;   // declares std

Ahora, por la gran razón por la cual es importante entender la diferencia entre una declaración y una definición: el Una regla de definición. De la sección 3.2.1 del estándar de C ++:

Ninguna unidad de traducción contendrá más de una definición de cualquier variable, función, tipo de clase, tipo de enumeración o plantilla.


160
2017-09-11 13:53



Declaración: "En algún lugar, existe un foo".

Definición: "... ¡y aquí está!"


111
2017-09-11 18:20



Hay casos de borde interesantes en C ++ (algunos de ellos también en C). Considerar

T t;

Eso puede ser una definición o una declaración, dependiendo de qué tipo T es:

typedef void T();
T t; // declaration of function "t"

struct X { 
  T t; // declaration of function "t".
};

typedef int T;
T t; // definition of object "t".

En C ++, cuando se usan plantillas, hay otro caso marginal.

template <typename T>
struct X { 
  static int member; // declaration
};

template<typename T>
int X<T>::member; // definition

template<>
int X<bool>::member; // declaration!

La última declaración fue no una definicion. Es la declaración de una especialización explícita del miembro estático de X<bool>. Le dice al compilador: "Si se trata de crear instancias X<bool>::member, entonces no cree una instancia de la definición del miembro de la plantilla primaria, pero utilice la definición que se encuentra en otra parte ". Para que sea una definición, debe proporcionar un inicializador

template<>
int X<bool>::member = 1; // definition, belongs into a .cpp file.

43
2017-09-11 18:15



Declaración

Las declaraciones le dicen al compilador que   elemento o nombre del programa existe. UN   declaración introduce uno o más   nombres en un programa. Las declaraciones pueden   ocurrir más de una vez en un programa.   Por lo tanto, clases, estructuras,   tipos enumerados, y otros   los tipos definidos por el usuario se pueden declarar para   cada unidad de compilación.

Definición

Las definiciones especifican qué código o datos   el nombre describe. Un nombre debe ser   declarado antes de que pueda ser utilizado.


29
2017-09-11 12:35



Del estándar C99, 6.7 (5):

Una declaración especifica la interpretación y los atributos de un conjunto de identificadores. UN definición de un identificador es una declaración para ese identificador que:

  • para un objeto, hace que el almacenamiento se reserve para ese objeto;
  • para una función, incluye el cuerpo de la función;
  • para una constante de enumeración o nombre typedef, es la (única) declaración del identificador.

Del estándar de C ++, 3.1 (2):

Una declaración es una definición a menos que declare una función sin especificar el cuerpo de la función, contiene el especificador externo o una especificación de enlace y ni un inicializador ni un cuerpo de función, declara un miembro de datos estáticos en una declaración de clase, es una declaración de nombre de clase o es una declaración typedef, una declaración using o una directiva using.

Luego hay algunos ejemplos.

Tan interesante (o no, pero estoy un poco sorprendido por eso), typedef int myint; es una definición en C99, pero solo una declaración en C ++.


18
2017-09-11 14:03



De wiki.answers.com:

El término declaración significa (en C) que le está diciendo al compilador sobre el tipo, tamaño y en caso de declaración de función, tipo y tamaño de sus parámetros de cualquier variable, o tipo o función definida por el usuario en su programa. No el espacio está reservado en la memoria para cualquier variable en caso de declaración. Sin embargo, el compilador sabe cuánto espacio reservar en caso de que se cree una variable de este tipo.

por ejemplo, las siguientes son todas las declaraciones:

extern int a; 
struct _tagExample { int a; int b; }; 
int myFunc (int a, int b);

La definición, por otro lado, significa que además de todas las cosas que hace la declaración, el espacio también está reservado en la memoria. Puedes decir "DEFINICIÓN = DECLARACIÓN + RESERVA DE ESPACIO" a continuación, hay ejemplos de definición:

int a; 
int b = 0; 
int myFunc (int a, int b) { return a + b; } 
struct _tagExample example; 

ver Respuestas.


12
2017-09-11 12:30



Actualización C ++ 11

Como no veo una respuesta pertinente para C ++ 11, aquí hay una.

Una declaración es una definición a menos que declare a / n:

  • opaco enum - enum X : int;
  • parámetro de la plantilla - T en template<typename T> class MyArray;
  • declaración de parámetro - X y y en int add(int x, int y);
  • declaración de alias - using IntVector = std::vector<int>;
  • declaración de afirmación estática - static_assert(sizeof(int) == 4, "Yikes!")
  • declaración de atributo (definido por la implementación)
  • declaración vacía ;

Cláusulas adicionales heredadas de C ++ 03 por la lista anterior:

  • declaración de función - añadir en int add(int x, int y);
  • especificador externo que contiene la declaración o un especificador de enlace - extern int a; o extern "C" { ... };
  • miembro de datos estáticos en una clase - X en class C { static int x; };
  • declaración de clase / estructura - struct Point;
  • declaración typedef - typedef int Int;
  • usando declaración - using std::cout;
  • usando directiva - using namespace NS;

Una plantilla-declaración es una declaración. Una declaración de plantilla también es una definición si su declaración define una función, una clase o un miembro de datos estáticos.

Ejemplos de la norma que diferencia entre declaración y definición que encontré útil para comprender los matices entre ellos:

// except one all these are definitions
int a;                                  // defines a
extern const int c = 1;                 // defines c
int f(int x) { return x + a; }          // defines f and defines x
struct S { int a; int b; };             // defines S, S::a, and S::b
struct X {                              // defines X
    int x;                              // defines non-static data member x
    static int y;                       // DECLARES static data member y
    X(): x(0) { }                       // defines a constructor of X
};
int X::y = 1;                           // defines X::y
enum { up , down };                     // defines up and down
namespace N { int d; }                  // defines N and N::d
namespace N1 = N;                       // defines N1
X anX;                                  // defines anX


// all these are declarations
extern int a;                           // declares a
extern const int c;                     // declares c
int f(int);                             // declares f
struct S;                               // declares S
typedef int Int;                        // declares Int
extern X anotherX;                      // declares anotherX
using N::d;                             // declares N::d


// specific to C++11 - these are not from the standard
enum X : int;                           // declares X with int as the underlying type
using IntVector = std::vector<int>;     // declares IntVector as an alias to std::vector<int>
static_assert(X::y == 1, "Oops!");      // declares a static_assert which can render the program ill-formed or have no effect like an empty declaration, depending on the result of expr
template <class T> class C;             // declares template class C
;                                       // declares nothing

12
2018-06-26 19:43



definición significa función real escrita & declaración significa simple declarar función por ej.

void  myfunction(); //this is simple declaration

y

void myfunction()
{
 some statement;    
}

esta es la definición de función myfunction


4
2018-01-07 04:42