External variable question

M

Mateusz_madi

Hi i have 2 modules program:

a.c
---------
#include<stdio.h>

int a=3;

void drukuj(){
printf("%d", a);
}

-----------
b.c
-----------

#include<stdio.h>

int a;

int main()
{
a=8;
drukuj();
}
---------

Why it prints 8 not 3.

Regards,
mateusz
 
D

David RF

Hi i have 2 modules program:

a.c
---------
#include<stdio.h>

int a=3;

void drukuj(){
        printf("%d", a);

}

-----------
b.c
-----------

#include<stdio.h>

int a;

int main()
{
        a=8;
        drukuj();}

Because a have global scope

Declare a as static in file b.c
static int a;
 
M

Mateusz_madi

Because a have global scope

Declare a as static in file b.c
static int a;- Ukryj cytowany tekst -

- Pokaż cytowany tekst -

There is something i don't understand about global variables. I found
in many pages that:
"Global - All the modules in the project - The life of the program
execution "
buth if i declare global let's say g in one module and would like to
increment it in second module it is impossible, so where is that
global (All the modules in the project) scope?
 
D

David RF

There is something i don't understand about global variables. I found
in many pages that:
 "Global - All the modules in the project -  The life of the program
execution "
buth if i declare global let's say g in one module and would like to
increment it in second module it is impossible, so where is that
global (All the modules in the project) scope?

Ok, I try to explain with my poor english

both a in a.c and b.c point to same location and have global scope, a
in b.c is redeclared, all variables declared without static duration
outside a function have global scope
 
R

Ralph Spitzner

Mateusz_madi said:
There is something i don't understand about global variables. I found
in many pages that:
"Global - All the modules in the project - The life of the program
execution "
buth if i declare global let's say g in one module and would like to
increment it in second module it is impossible, so where is that
global (All the modules in the project) scope?

no you simply declare it in say main.c int g;
initialize it (if compiler supports this) like
not writing int g; but int g=3;

then you 'recognize it as being there' in your other
'module'

extern int g; // cannot initialize at compile time

_then_ increment it it like say:

foo()
{
g++;
}

of course you have to call that function.

Are you coming from Delphi, Pascal or something ?

So, you can use any global from any function, but
your 'modules' get alive when main() is called, hence
you have no 'modules' that can have their own lives....

This was not very technical :p

But I think you have a general misperception of how that
executable is put together by the compiler/linker here...

Pls don't flame me for that :)
-rasp
 
J

James Kuyper

Hi i have 2 modules program:

a.c
---------
#include<stdio.h>

int a=3;

void drukuj(){
printf("%d", a);
}

-----------
b.c
-----------

#include<stdio.h>

int a;

int main()
{
a=8;
drukuj();
}

Because the initialization of 'a' to a value of 3 occurs before main()
starts executing. The assignment of the value of 8 to 'a' doesn't occur
until after main() starts executing. by the time main() calls druku, the
assignment is already complete.

When did you think the values of 3 and 8 would be given to 'a'?
 
B

bert

There is something i don't understand about global variables. I found
in many pages that:
 "Global - All the modules in the project -  The life of the program
execution "
buth if i declare global let's say g in one module and would like to
increment it in second module it is impossible, so where is that
global (All the modules in the project) scope?

Some dialects of C could have "extern int a" in
the module b.c, then it is clear that the "a"
which you overwrite in the second module is the
same global "a" as the one which you declared
and initialised in the first module.
--
 
B

Ben Bacarisse

Mateusz_madi said:
Hi i have 2 modules program:

a.c

This declares an identifier with external linkage and also defines it.
void drukuj(){
printf("%d", a);
}

-----------
b.c
-----------

#include<stdio.h>

int a;

This is called a tentative definition, because a similar definition may
come later that says some more about 'a';
int main()
{
a=8;
drukuj();
}

But here, at the end of the translation unit, that tentative definition
becomes and real one, just as if you had written "int a = 0;".

Answers so far have missed a key point: the program is undefined.
Anything could happen. The C standard says "If an identifier declared
with external linkage is used [...] somewhere in the entire program
there shall be exactly one external definition for the identifier".
 
B

Ben Bacarisse

bert said:
Some dialects of C could have "extern int a" in
the module b.c,

I think this is a little misleading. What do you mean by "some
dialects"? What you have proposed is standard C. It's been that way
since the very first days of C -- from pre-ANSI C right up to the
current proposed draft of the next standard. I'd argue that any dialect
that did not permit "extern int a;" to mean what you want would have
little right to be called C.
then it is clear that the "a"
which you overwrite in the second module is the
same global "a" as the one which you declared
and initialised in the first module.

I don't think "overwrite" is the best word here. The extern declaration
simply refers to the same 'a' that was defined in the first translation
unit. (C does not have "modules" but I don't think that matters -- it's
a useful and well-known term that does cause any serious confusion. C
does not really have globals either -- and in this particular case, it
does matter because it is exactly the source of the OP's confusion.)
 
B

Ben Bacarisse

David RF said:
Ok, I try to explain with my poor english

both a in a.c and b.c point to same location and have global scope, a
in b.c is redeclared, all variables declared without static duration
outside a function have global scope

That's not really the problem. The program is undefined because it has
two external definitions of an object with the same name.

Unfortunately your terms are rather confused. Normally this does not
matter, but in this case using the right terms helps to get everything
clear.

In C, a named object is characterised by three properties: the scope of
the name, the lifetime of the object and the linkage of the name. These
are related but also to some extent independent.

An external definition of an object (one that sits outside of any
function) gives it static duration -- even if it does not use the word
static! If an external declaration does use the keyword "static", this
alters the linkage but not the lifetime.

C does not have global variables in the same sense that some other
languages do. Normally, when people talk about "glabals" in C they mean
objects with external linkage, static duration and file scope. Using the
term "global" (or "global scope") is rarely a problem, but in this case
it lies at the heart of the OP's confusion so I think it pays to use the
right language. Here are some examples:

----------------
int a = 3; /* The name has file scope and external linkage.
The object named has static duration */

static int b = 42; /* The name has file scope but internal linkage.
The object has static duration */

void f(int a) /* f has file scope and external linkage but functions
don't have any storage duration.
a has block scope, no linkage and automatic duration. */
{
int b; /* block scope, no linkage, automatic duration. */
static int c; /* block scope, internal linkage and static duration */
extern int d; /* block scope, external linkage and static duration */
}

void g(int x); /* x has function prototype scope, no linkage and
(insofar as it makes any sense) automatic duration. */

int t; /* A tentative definition of a name with file scope and external
linkage naming an object with static duration. *.

int t2; /* Another tentative definition. */

int t2 = 42; /* Not a re-definition since the previous one was
tentative. */

/* Here, at the end of the translation unit, the tentative definition of
't' is treated as if it had been "int t = 0;". I.e. the tentative
definition becomes a real one. */
----------------

There are two rather curious details. An object with automatic duration
that is not a variably modified array exists from entry into the block
until the block is exited[1]. A variably modified array only exists
from the point of it's definition:

int peculiar(unsigned int s)
{
int *ip = 0;
top: if (ip) return *ip;
int a[1];
a[0] = 42;
ip = a;
goto top;
}

is well-defined but if 'a' were changed to be "int a;" then the
behaviour would be undefined.

[1] Even this needs care to define properly but I'll leave it as
self-evident for the moment.
 
D

David RF

Ok, I try to explain with my poor english
both a in a.c and b.c point to same location and have global scope, a
in b.c is redeclared, all variables declared without static duration
outside a function have global scope

That's not really the problem.  The program is undefined because it has
two external definitions of an object with the same name.

Unfortunately your terms are rather confused.  Normally this does not
matter, but in this case using the right terms helps to get everything
clear.

In C, a named object is characterised by three properties: the scope of
the name, the lifetime of the object and the linkage of the name.  These
are related but also to some extent independent.

An external definition of an object (one that sits outside of any
function) gives it static duration -- even if it does not use the word
static!  If an external declaration does use the keyword "static", this
alters the linkage but not the lifetime.

C does not have global variables in the same sense that some other
languages do.  Normally, when people talk about "glabals" in C they mean
objects with external linkage, static duration and file scope.  Using the
term "global" (or "global scope") is rarely a problem, but in this case
it lies at the heart of the OP's confusion so I think it pays to use the
right language.  Here are some examples:

----------------
int a = 3; /* The name has file scope and external linkage.
              The object named has static duration */

static int b = 42; /* The name has file scope but internal linkage.
                      The object has static duration */

void f(int a) /* f has file scope and external linkage but functions
                 don't have any storage duration.
                 a has block scope, no linkage and automatic duration. */
{
    int b; /* block scope, no linkage, automatic duration. */
    static int c; /* block scope, internal linkage and static duration */
    extern int d; /* block scope, external linkage and static duration */

}

void g(int x); /* x has function prototype scope, no linkage and
                  (insofar as it makes any sense) automatic duration. */

int t; /* A tentative definition of a name with file scope and external
          linkage naming an object with static duration. *.

int t2; /* Another tentative definition. */

int t2 = 42; /* Not a re-definition since the previous one was
                tentative. */

/* Here, at the end of the translation unit, the tentative definition of
   't' is treated as if it had been "int t = 0;".  I.e. the tentative
   definition becomes a real one. */
----------------

There are two rather curious details.  An object with automatic duration
that is not a variably modified array exists from entry into the block
until the block is exited[1].  A variably modified array only exists
from the point of it's definition:

  int peculiar(unsigned int s)
  {
       int *ip = 0;
  top: if (ip) return *ip;
       int a[1];
       a[0] = 42;
       ip = a;
       goto top;
  }

is well-defined but if 'a' were changed to be "int a;" then the
behaviour would be undefined.

[1] Even this needs care to define properly but I'll leave it as
self-evident for the moment.


Thanks for the correction
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top