Acerca de la definición provisional

4 minutos de lectura

avatar de usuario
Sadique

Leí de un libro sobre definición tentativa que,

Una definición tentativa es cualquier declaración de datos externos que no tiene especificador de clase de almacenamiento ni inicializador. Una definición tentativa se convierte en una definición completa si se llega al final de la unidad de traducción y no ha aparecido ninguna definición con un inicializador para el identificador.

Por favor explique lo que significa la declaración anterior. Además, ¿la diferencia entre Declaración y Definición? Me confundí debido a esto. 🙁 ¿Y por qué este programa no da un error:

#include <stdio.h>

int a;      //Tentative definition
int a;      //similarly this declaration too.
int main()  //not getting any error with this code why its so?
{
    printf("hi");
} 

Además, lo que está mal con este código:

#include<stdio.h>
printf("Hi");
int main(void){
    return 0;
}

  • ¿En qué libro leíste sobre la definición tentativa?

    – Destructor

    27/10/2015 a las 12:55

  • También vea ¿Cuál es la razón detrás de las definiciones tentativas en C?

    – Shafik Yaghmour

    13 de agosto de 2018 a las 15:57

avatar de usuario
Tyler McHenry

Una variable declaración dice, “hay una variable con el siguiente nombre y tipo en el programa”.

Una variable definición dice: “Estimado Sr. Compilador, asigne memoria para una variable con el siguiente nombre y escriba ahora”.

Por lo tanto, puede haber múltiples declaraciones para la misma variable, pero solo debe haber una definición.

En C, las declaraciones puras (que no son también definiciones) van precedidas de la palabra clave extern. Entonces, dado que no tiene esta palabra clave en su primer ejemplo, lo que tiene son dos definiciones. A primera vista, esto parecería ser un problema (y de hecho es un error en C++), pero C tiene una regla especial de “definición tentativa” que permite múltiples definiciones para la misma variable en la misma unidad de traducción siempre que todas coincide y como máximo uno tiene un inicializador. El compilador de C, entre bastidores, combina todas las definiciones tentativas en una sola definición.

Si hubiera intentado inicializar ambas definiciones, así:

int a = 1;
int a = 2;

Entonces habrías tenido un error.

Tu segunda pregunta es más directa. En C, simplemente no puede tener sentencias ejecutables fuera del cuerpo de una función. Simplemente no está permitido. Piénselo: ¿cuándo esperaría que se ejecutara si estuviera permitido?

  • @TylerMcHenry: es ilegal tanto en C como en C++, pero los compiladores de C implementan esto como una extensión común. Ver esta respuesta.

    – leyendas2k

    3 de marzo de 2014 a las 12:23

  • @legends2k No, esto no es ilegal en C… en la pregunta a la que se vincula (y también a la pregunta a la que se vincula la respuesta) involucra varios archivos. Múltiples definiciones tentativas (compatibles) en el mismo archivo no constituyen una infracción. La violación en esa pregunta se debe a que, al final de la unidad de traducción, si hay definiciones tentativas sin una definición completa, se implica una definición completa. Eso más múltiples archivos conduce a múltiples definiciones en el momento del enlace (excepto por la extensión común de las reglas de definición tentativa para abarcar múltiples archivos).

    – Teodoro Murdock

    18 mayo 2015 a las 21:59

  • ¿Por qué solo es legal con variables globales, no con variables locales? Con variables locales, da error de redeclaración?

    – Rishab Shinghal

    24 de diciembre de 2017 a las 14:13

  • @RishabShinghal: la única razón por la que C lo permite es para que sea compatible con el código escrito antes de agregar la palabra clave “externa”. Y extern no se aplica a variables locales donde nunca se permitieron duplicados.

    – Zan Lince

    15 de enero de 2018 a las 19:02


  • “C tiene una regla especial de ‘definición tentativa’ que permite múltiples definiciones para la misma variable en la misma unidad de traducción siempre que todas coincidan y, como máximo, una tenga un inicializador”. En C, si declara una variable en el ámbito del archivo y no especifica ni un enlace ni un inicializador, eso suele ser una declaración y no una definición. Solo si no existe una definición en la unidad de traducción, se creará una especie de definición implícita. Incluso eso no es realmente cierto, ya que el enlazador buscará en todas las unidades de traducción una definición real y usará cualquiera que encuentre (símbolo común).

    – jschultz410

    6 de marzo de 2021 a las 22:10

El primero funciona porque ambas definiciones de a son tentativas, las cuales pueden ser duplicadas tantas veces como lo estime oportuno. Al final de la unidad de traducción, no se ha visto ninguna definición no tentativa, por lo que lo que especificó para los atributos se combina con los valores predeterminados para dar una definición final de apor lo que tendrá vinculación externa, duración de almacenamiento estático y se inicializará en 0.

El problema con el segundo no tiene nada que ver con definiciones tentativas. Su printf("Hi"); necesita estar dentro de una función para funcionar, no es una declaración o una definición (tentativa o de otro tipo); simplemente no está permitido allí.

¿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