Quote:
>>int array[100];
>>and included that file in various routines and the 'main' program,
>>The compiler told me I repeat the definition of "array" and the second
Why did you include the file in various ROUTINES? Or did you
mean modules? But in that case, it is highly unlikely the compiler would
have warned you - more likely it would have been the linker.
Quote:
>All variables defined outside a function are considered as global variables.
>For every global variable, there is only one variable definition. By
>definition under ANSI C, the variable needs to be initialized to indicate
>that is a varaible definition, not a variable declaration.
Oh, no. A global object variable with an initializer or one
without the linkage specifier "extern" prepended to it classifies as a
definition. Thus extern int i = 0; and int i; and static int i; are all
definitions. (This is really a simplification, I am assuming that no
variable is being declared more than once in the same file.)
Quote:
>The memory is
>allocated for it here and only once. (I am sure that there are conventions
>for declaring global variables, please refer to your favorite C books under
>the "storage class section.") The scope of the variable is from the end of
>the variable definition to the end of the file.
Actually the scope of the variable starts from the point of
occurrence of the *variable name* in the declaration.
Thus int i = sizeof(i); is valid.
I know, it matters not, still ....
Quote:
>Other places that are not
>part of the scope of variable and wish to refer to it can use "extern"
>keyword to extend its scope.
Right.
To elaborate, the "extern" keyword can also be used to refer to
a file-scope variable which has been hidden by a declaration in an outer
block;
int i;
int main(void){int i = 10; .... {extern int i;...}}
The "i" in the innermost block will now refer to the i declared at
file-scope. If you really are including a .h file in several _routines_,
you might just have to take this into consideration.
(I never post on issues of programming style; so I will refrain from
pointing out that this type of usage is bad style.)
Quote:
>Since you included the header file in all your files but did not indicate
>which one was the variable definition, the compiler could not figure out
>what was your intention. It assumed that each variable declared inside
>the header file is a variable definition. Thus, the compiler complained.
Doubtful. More likely it was the linker that would have complained.
Can the compiler have enough intelligence to do this? Possible, of course,
but in practice, do such compilers exist? Lint should help out, however.
Quote:
>A proper way of manipulating a global variable in this particular case
>would be :
> - Declaring the array "array" outside a function with initialization.
> This variable should be placed in the file where you mainly use it.
> eg:
> int array[100] = 0;
Ooops, what sort of an initialization is that?
Do int array[100] = {0};
An ANSI-conforming compiler should be able to accept just
int array[100]; in place of this.
Quote:
>>OK, so I changed the "incl.h" file:
>>#ifdef MAIN_MODULE
>> int array[100];
>>#else
>> extern int *array;
>>#endif
>In the #else part, you declared a variable of "pointer to int". Its
>definition was declared somewhere else.
Actually there would be *no* definition for array (of type int *)
in this case. This is undefined behaviour. But I believe you are talking of
a typical UNIX environment, which, as you say, might end up taking any one
of the declarations as a definition.
But as others have pointed out, his problem is that the #else
should have had extern int array[100];.
Quote:
>Although the names of the two
>variables were looked the same, the compiler treated them separately.
>While you were using the variable, which was a pointer to int, it was
>pointing no objects. The pointer was initialized to NULL by default.
..
>However, since the "extern" keyword was proceded in each
>declaration of the variable, the compiler would treat any one of them as
>the variable definition and the rest as the variable declarations. There
>is no guarantee that which one will be chosen.
This also is doubtful. If one of the extern int *array; declarations
is taken to be a definition (by the linker), it means the linker would have
two objects with the same name array (one of type int [100] and the other of
type int *). Shouldn't the linker complain then and there itself?
What looks to me more likely is that the compiler exports the
definition of array (int array[100]) from one file. It also reports
unresolved external references of array from all other files (the compiler
thinks these are references to int *). The linker does not know about
"C" types, so it just goes ahead and resolves all references to "array"
(which the compiler had coded to be references to int *) to refer to the
array "array" (ie., to int array[100]). The code runs, and as explained
by Chris Volpe in a previous posting, crashes.
------
/* Pointers are, more often that not, pointlessly used. */
/* Ajoy Krishnan T,
Software Engineer, Hughes Software Systems,
New Delhi - 19, India.