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

8 minutos de lectura

avatar de usuario
Maciek

El significado de ambos se me escapa.

  • Francamente, tuve muchos problemas para saber cuál era cuál, así que no encontré los nombres obvios. No tuve ningún problema con los significados, solo qué nombres asociar con los significados.

    –David Thornley

    11 de septiembre de 2009 a las 14:10

  • Hemos analizado esto en detalle exhaustivo: stackoverflow.com/questions/671925/…

    – dmckee — gatito ex-moderador

    11 de septiembre de 2009 a las 14:17

  • Aún así, no es una pregunta duplicada, ya que se trata de C/C++, mientras que la otra pregunta se refiere a todos los idiomas, o ninguno, en general. Solo tiene respuestas duplicadas (ya que en esa otra pregunta, algunas respuestas optaron por ignorar todo el lenguaje excepto C y/o C++).

    –Steve Jessop

    11 de septiembre de 2009 a las 14:23

  • @DavidThornley Yo uso este truco: a definición da un más fino descripción de una determinada variable o función. Para recordar esto, recuerdo que la mitad de la palabra “definición” tiene un parecido con la palabra “más fino”. 🙂

    – Marco Leogrande

    27 de julio de 2012 a las 6:39


  • @MarcoLeogrande: ¡O “definitivo”!

    – Carreras de ligereza en órbita

    14/04/2013 a las 17:41

avatar de usuario
pedestal

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

Definición: “… y aquí está!”

  • La declaración es para que el compilador acepte un nombre (para decirle al compilador que el nombre es legal, el nombre se introduce con intención, no con un error tipográfico). La definición es donde se asocia un nombre y su contenido. El vinculador utiliza la definición para vincular una referencia de nombre al contenido del nombre.

    – Gab是好人

    11 de febrero de 2016 a las 14:41


  • “declara un miembro estático dentro de una definición de clase”: esto es cierto incluso si el miembro estático está inicializado, ¿correcto? podemos hacer el ejemplo struct x {static int b = 3; };?

    – RJ Falconer

    4 de marzo de 2014 a las 13:27

  • @RJFalconer Tienes razón; la inicialización hace no convertir necesariamente una declaración en una definición (al contrario de lo que cabría esperar; ciertamente esto me pareció sorprendente). Su modificación al ejemplo es ilegal a menos que b también se declara const. Consulte stackoverflow.com/a/3536513/1858225 y daniweb.com/software-development/cpp/threads/140739/… .

    – Kyle Strand

    14 de agosto de 2014 a las 17:08


  • Esto es interesante para mí. Según su respuesta, parece que en C++, una declaración es además una definición (con excepciones), mientras que en la norma C se formula desde la otra perspectiva (C99, sección 6.7, Declaraciones): “A definición de un identificador es una declaración para ese identificador que: [followed by criteria for different cases]”Diferentes formas de verlo, supongo. 🙂

    – Víctor Zamanian

    7 oct 2014 a las 13:52

  • La declaración es para que el compilador acepte un nombre (para decirle al compilador que el nombre es legal, el nombre se introduce con intención, no con un error tipográfico). La definición es donde se asocia un nombre y su contenido. El vinculador utiliza la definición para vincular una referencia de nombre al contenido del nombre.

    – Gab是好人

    11 de febrero de 2016 a las 14:45

avatar de usuario
leyendas2k

Actualización de C++11

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

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

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

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

  • declaración de función – agregar en int add(int x, int y);
  • especificador externo que contiene una 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 declaración de plantilla 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 del estándar que diferencia entre declaración y definición que encontré útiles 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

avatar de usuario
steve jesop

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 C++, 3.1(2):

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

Luego hay algunos ejemplos.

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

avatar de usuario
kate gregorio

De wiki.respuestas.com:

El término declaración significa (en C) que le está diciendo al compilador sobre el tipo, el tamaño y, en el caso de la declaración de la función, el tipo y el tamaño de sus parámetros de cualquier variable, o tipo o función definida por el usuario en su programa. No se reserva espacio 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, también se reserva espacio en la memoria. Puede decir “DEFINICIÓN = DECLARACIÓN + RESERVA DE ESPACIO” a continuación se muestran ejemplos de definición:

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

ver respuestas.

  • Esto también está mal (aunque mucho más cerca que los otros): struct foo {}; es un definición, no una declaración. una declaración de foo sería struct foo;. A partir de eso, el compilador no sabe cuánto espacio reservar para foo objetos.

    – sbi

    11 de septiembre de 2009 a las 12:37

  • @Marcin: sbi dice que “el compilador sabe cuánto espacio reservar en caso de que se cree una variable de este tipo” no siempre es cierto. struct foo; es una declaración, pero no le dice al compilador el tamaño de foo. agregaría eso struct _tagExample { int a; int b; }; es una definición. Entonces, en este contexto, es engañoso llamarlo una declaración. Por supuesto que lo es, ya que todas las definiciones son declaraciones, pero parece estar sugiriendo que no es una definición. Es una definición, de _tagExample.

    –Steve Jessop

    11 de septiembre de 2009 a las 13:01

  • @Marcin Gil: Lo que significa que la wiki de “Respuestas” no siempre es precisa. Tengo que votar negativamente por la desinformación aquí.

    –David Thornley

    11 de septiembre de 2009 a las 14:07

  • Aprendemos que lo que adatapost citó es cierto pero (IMO) realmente no responde la pregunta. Lo que Marcin citó es falso. Citar los estándares es cierto y responde a la pregunta, pero es muy difícil de entender.

    –Steve Jessop

    11 de septiembre de 2009 a las 14:18

  • @David Thornley: no hay problema 🙂 De esto se trata este sitio. Nosotros seleccione y verifique la información.

    –Marcin Gil

    11 de septiembre de 2009 a las 18:15

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad