Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the rationale behind tentative definitions in C?

Tags:

Consider following program. Will this give any compilation errors?

#include <stdio.h>
int s=5;
int s;
int main(void)
{
     printf("%d",s);
}

At first glance it seems that compiler will give variable redefinition error but program is perfectly valid according to C standard. (See live demo here http://ideone.com/Xyo5SY).

A tentative definition is any external data declaration that has no storage class specifier and no initializer.

C99 6.9.2/2

A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.

My question is, what is rationale for allowing tentative definitions? Is there any use of this in C? Why does C allow tentative definitions?

like image 442
Destructor Avatar asked Oct 18 '15 17:10

Destructor


People also ask

What is tentative declaration in C?

Beginning of C only. A tentative definition is any external data declaration that has no storage class specifier and no initializer. A tentative definition becomes a full definition if the end of the translation unit is reached and no definition has appeared with an initializer for the identifier.

What is tentative variable?

Assigns tentative values for the variables in a term. These are typically used to register values the variables are given in a partial or initially inconsistent solution. These values may be changed through later calls to the same predicate.

What are definitions in C?

What is #define in C? #define is a preprocessor directive that is used to define macros in a C program. #define is also known as a macros directive. #define directive is used to declare some constant values or an expression with a name that can be used throughout our C program.


2 Answers

Tentative definitions was created as a way to bridge incompatible models that existed pre-C89. This is covered in the C99 rationale section 6.9.2 External object definitions which says:

Prior to C90, implementations varied widely with regard to forward referencing identifiers with internal linkage (see §6.2.2). The C89 committee invented the concept of tentative definition to handle this situation. A tentative definition is a declaration that may or may not act as a definition: If an actual definition is found later in the translation unit, then the tentative definition just acts as a declaration. If not, then the tentative definition acts as an actual definition. For the sake of consistency, the same rules apply to identifiers with external linkage, although they're not strictly necessary.

and section 6.2.2 from the C99 rationale says:

The definition model to be used for objects with external linkage was a major C89 standardization issue. The basic problem was to decide which declarations of an object define storage for the object, and which merely reference an existing object. A related problem was whether multiple definitions of storage are allowed, or only one is acceptable. Pre-C89 implementations exhibit at least four different models, listed here in order of increasing restrictiveness:

like image 128
Shafik Yaghmour Avatar answered Sep 24 '22 19:09

Shafik Yaghmour


Here's an example of a case where it's useful:

void (*a)();

void bar();
void foo()
{
    a = bar;
}

static void (*a)() = foo;

/* ... code that uses a ... */

The key point is that the definition of foo has to refer to a, and the definition of a has to refer to foo. Similar examples with initialized structures should also be possible.

like image 26
R.. GitHub STOP HELPING ICE Avatar answered Sep 25 '22 19:09

R.. GitHub STOP HELPING ICE