Reputation:
If we declare an object or function without defining it, how are we allowed to use it before its declaration and how are we not allowed to use it before its declaration ? (For a similar question using a forwarded declared structure tag before its definition, basically how we are allowed to use an incomplete type and how not, see https://stackoverflow.com/a/45725061/3284469)
Does it matter if the declaration appears in file scope or block scope?
Does it matter if its definition appears in the same or a different translation unit?
For example
extern int i;
(what can we do with i here?)
(what can't we do with i here?)
int A = i+3; // error: initializer element is not constant. This is an error not due to forward declaration of int i
int i = 3;
void fun();
(what can we do with fun here?)
(what can't we do with fun here?)
void fun(){};
Upvotes: 7
Views: 112
Reputation: 106092
what can we do with i here
With
extern int i;
i
can be declared as many times as required in the program. You can have an initializer
extern int i = 0;
what can't we do with i here?
You can't use i
without defining it in the program.
extern int i;
int main(void)
{
i = 10; // Will through an error
return 0;
}
In case of function this keyword only tells that the linkage for the function is extern
. By default linkage of a function declaration/definition is extern.
Upvotes: 0
Reputation: 726809
Declaring an object is a promise to provide a definition at some other place. Once you declare a function or an external variable, from that point on you are allowed to do anything that you would be allowed to do to a function or a variable that you have defined.
The scope of the declaration has no effect on what you can do, only on the location in code where you can do it.
In most cases, code translator requires all external references to be satisfied at the time the code is linked. Otherwise, you get a linking error.
One exception to this rule is using declared object in a sizeof
expression, which does not require an access to underlying object:
extern int undefined;
size_t res = sizeof(undefined);
The above will not break a link, because sizeof
expression does not generate access to its arguments.
Upvotes: 4
Reputation: 34638
www.cprogramming.com say's:
When you declare a variable, a function, or even a class all you are doing is saying: there is something with this name, and it has this type. The compiler can then handle most (but not all) uses of that name without needing the full definition of that name. Declaring a value--without defining it--allows you to write code that the compiler can understand without having to put all of the details. This is particularly useful if you are working with multiple source files, and you need to use a function in multiple files. You don't want to put the body of the function in multiple files, but you do need to provide a declaration for it.
extern int i;
Here, an integer type variable i
has been declared (but no definition i.e. no memory allocation for variable i
so far). And we can do this declaration as many times as needed.
void fun();
Function fun()
declare, but not defined. but it does tell the compiler that it can use this function and expect that it will be defined somewhere.
Upvotes: 0
Reputation: 249394
You can do anything with the declaration except for inlining it. For example:
void fun();
inline void fun(){}
After the declaration you can call the function, unless the definition is marked inline
in which case it will result in a linker error because the definition does not emit a symbol to link against. Even if you don't say inline
explicitly, an optimizing compiler may inline calls to the function if the definition has been seen.
Upvotes: 0