extern char and include practices

A

atv

Alright, i have some questions concerning include files en global
variables.I hope someone is willing to answer these.

1).Why is it that if i define a global variable in a file, say main.c,
and i have also other functions defined in that file, i can use the
global in all functions, but once i split up the rest of the function in
other files, i cannot use the global? Isn't that strange, all the files
compiled should be treated as one program right ?

Or should i always define the variables somewhere, say main.c, and use
extern char var[]; in the other source files?

2). What is the proper way to use include files? If i split my code and
functions up in different files, what is the normal way of using
includes. Do you, each time for a new file, have a list of the includes
setup again in that file, or ?

Right now, i have a method i saw from some other code, by defining all
the include headers in one include.h, and using that include for all
files. That way you only have to include a file once, saves a lot of
typing. Is this a correct way or a very bad way of doing things.

3). I have code that is split up in multiple files. The main function
sits in main.c, and calls for example, a logging function, which sits
in log.c. Now log() needs to remember the amount of lines it has
written. How would i do this ? Declare a global in main and then use
extern int lines;? But that doesn't seem to work. What am i doing wrong?
Should it be static?
 
A

Allan Bruce

atv said:
Alright, i have some questions concerning include files en global
variables.I hope someone is willing to answer these.

1).Why is it that if i define a global variable in a file, say main.c,
and i have also other functions defined in that file, i can use the
global in all functions, but once i split up the rest of the function in
other files, i cannot use the global? Isn't that strange, all the files
compiled should be treated as one program right ?

Or should i always define the variables somewhere, say main.c, and use
extern char var[]; in the other source files?

If you have to use globals then the variable will be available to that file.
To use it in another .c file then yes you must use
extern TYPE VAR
The reason it is not immediately available to other files (I think) is to do
with scope. A global variable in one file has scope throughout the whole
file but not in others, just like if a variable is defined in a function -
it has scope within that function but not in others.
2). What is the proper way to use include files? If i split my code and
functions up in different files, what is the normal way of using
includes. Do you, each time for a new file, have a list of the includes
setup again in that file, or ?

Right now, i have a method i saw from some other code, by defining all
the include headers in one include.h, and using that include for all
files. That way you only have to include a file once, saves a lot of
typing. Is this a correct way or a very bad way of doing things.

What I do is use a "stdhdrs.h" which includes the common headers required
for my type of app. At the moment I am programming an OpenGL app in windows
so it looks like

#include <windows.h>
#include <fstream>
#include <gl\gl.h>
#include <gl\glu.h>
#include <cmath>

#pragma once // include only once

#define APP_VERSION "WinGalaga v0.0.3"

#define ENTER 13
#define ALTGR 17
#define SPACE ' '

(You may also notice that it uses c++ headers, but thats aside). As for
what should be in a .h file then I put in the function prototypes and not
much else, but the minimum to get it to compile. You should also have good
comments in your header file for usage.
3). I have code that is split up in multiple files. The main function
sits in main.c, and calls for example, a logging function, which sits
in log.c. Now log() needs to remember the amount of lines it has
written. How would i do this ? Declare a global in main and then use
extern int lines;? But that doesn't seem to work. What am i doing wrong?
Should it be static?

There are many ways to do this. Microsoft tend to throw everything into a
struct, I prefer to pass pointers e.g.

int log(int *xoNumLines)
{
// do something
*xoNumLines = NumLinesRead; // or whatever
}

HTH
Allan
 
R

rihad

Alright, i have some questions concerning include files en global
variables.I hope someone is willing to answer these.

1).Why is it that if i define a global variable in a file, say main.c,
and i have also other functions defined in that file, i can use the
global in all functions, but once i split up the rest of the function in
other files, i cannot use the global? Isn't that strange, all the files
compiled should be treated as one program right ?

It's all in visibility, really. A file scope variable with external linkage
defined in one translation unit will not just automagically be seen in other
translation units (because you do not compile a "program", you compile a
translation unit (which is, roughly, the processed *.c file after preprocessing
and various other stages).

To refer to a variable with external linkage defined somewhere (including, but
not limited to, the current translation unit), you would put

extern int i;

which tells the C compiler that `i' exists somewhere.
Or should i always define the variables somewhere, say main.c, and use
extern char var[]; in the other source files?

Yes, but you would normally put that line in the header file main.h and include
that header file.
2). What is the proper way to use include files? If i split my code and
functions up in different files, what is the normal way of using
includes. Do you, each time for a new file, have a list of the includes
setup again in that file, or ?

Yes, or wrap them in a single "includer", if that makes sense. But pay attention
so that no .h file is included more than once, because in most cases it is an
error (resulting in multiple definition errors). This can be achieved relatively
easily by using so called "inclusion guard". For example, to guard foo.h against
multiple inclusions, you would write something like

#ifndef FOO_H
#define FOO_H

/* body of foo.h here ... */

#endif


From now on, you don't have to worry that a file will be included more than once
in one translation unit. There are of course some other compiler-specific
solutions to prevent multiple inclusions (like #pragma once) which are a tiny
bit better (since you don't use up the preprocessor namespace), but these
pragmas are not portable, so better stick to the ifndef/endif trick.
Right now, i have a method i saw from some other code, by defining all
the include headers in one include.h, and using that include for all
files. That way you only have to include a file once, saves a lot of
typing. Is this a correct way or a very bad way of doing things.

It wouldn't do any harm, normally.
3). I have code that is split up in multiple files. The main function
sits in main.c, and calls for example, a logging function, which sits
in log.c. Now log() needs to remember the amount of lines it has
written. How would i do this ? Declare a global in main and then use
extern int lines;? But that doesn't seem to work. What am i doing wrong?
Should it be static?

The approach should work, if you're defining `int lines;' as a file scope
variable in main.c, and declaring it as `extern int lines;' either at file scope
in log.c, inside log(), or both.

Using a static variable inside log() another possible approach. It all depends
on what you want to do.
 
J

j

atv said:
Alright, i have some questions concerning include files en global
variables.I hope someone is willing to answer these.

1).Why is it that if i define a global variable in a file, say main.c,
and i have also other functions defined in that file, i can use the
global in all functions, but once i split up the rest of the function in
other files, i cannot use the global? Isn't that strange, all the files
compiled should be treated as one program right ?

Because what you think ``global'' means, isn't really global. It is a
misleading term.
Each translation unit will need a local declaration of the file-scope
variable
that has external linkage.
Or should i always define the variables somewhere, say main.c, and use
extern char var[]; in the other source files?

The definition can exist in your main translation unit(depending on the
purpose of the variable)
and can be identified elsewhere with the use of ``extern'' and if it is an
array, then
``extern char var[]'' would work.
2). What is the proper way to use include files? If i split my code and
functions up in different files, what is the normal way of using
includes. Do you, each time for a new file, have a list of the includes
setup again in that file, or ?

Hm, well.. if you use a set of standard headers throughout several
translation units
then grouping those commonly used standard headers in a common header file
seems okay to me. Certainly beats the otherwise toilsome work if you have
to deal with several translation units.
Right now, i have a method i saw from some other code, by defining all
the include headers in one include.h, and using that include for all
files. That way you only have to include a file once, saves a lot of
typing. Is this a correct way or a very bad way of doing things.

3). I have code that is split up in multiple files. The main function
sits in main.c, and calls for example, a logging function, which sits
in log.c. Now log() needs to remember the amount of lines it has
written. How would i do this ? Declare a global in main and then use
extern int lines;? But that doesn't seem to work. What am i doing wrong?
Should it be static?

Well, if the variable's purpose is to be used in this function only, then a
variable with
static storage is sufficient. I think you also need to ask yourself, how
many lines
do you expect this logfile to build up to? An int certainly won't hold that
much.
 
C

CBFalconer

atv said:
Alright, i have some questions concerning include files en global
variables.I hope someone is willing to answer these.

1). Why is it that if i define a global variable in a file, say
main.c, and i have also other functions defined in that file, i
can use the global in all functions, but once i split up the rest
of the function in other files, i cannot use the global? Isn't
that strange, all the files compiled should be treated as one
program right ?
No.


Or should i always define the variables somewhere, say main.c,
and use extern char var[]; in the other source files?

Yes. You should define it where it has its primary use. With
good design you will often find it is not needed as a 'global'
anyhow. Global is a misnomer anyhow, and I assume you are using
it to define something that has static duration and external
scope.
2). What is the proper way to use include files? If i split my
code and functions up in different files, what is the normal
way of using includes. Do you, each time for a new file, have a
list of the includes setup again in that file, or ?

The include file is used to specify the access allowed to the code
file. I.e., if you have written foo.c, then foo.h specifies those
elements of foo.c visible in other files. In those other files
you make them visible by including foo.h. You also include foo.h
in foo.c to ensure that those definitions are consistent. Include
guards are also handy.

This is NOT mandated by the standards, compilers, etc. but is
simply good practice.
Right now, i have a method i saw from some other code, by
defining all the include headers in one include.h, and using
that include for all files. That way you only have to include
a file once, saves a lot of typing. Is this a correct way or
a very bad way of doing things.

Ugh. This is analogous to always leaving your car with the keys
in the ignition and engine running. Both tend to lead to total
loss of control.
3). I have code that is split up in multiple files. The main
function sits in main.c, and calls for example, a logging
function, which sits in log.c. Now log() needs to remember the
amount of lines it has written. How would i do this ? Declare
a global in main and then use extern int lines;? But that doesn't
seem to work. What am i doing wrong? Should it be static?

That depends on what needs to know that count of lines. If only
log(), declare it as local to the log() function. If it has to
preserve its value between calls, make it static. If doing that
fouls up re-entrancy, pass its location to log as a parameter.

BTW your use of i in place of the (upper case) pronoun I is
annoying.
 
N

nobody

j said:
Because what you think ``global'' means, isn't really global. It is a
misleading term.
[snip]

Maybe that's why my copy of N869 doesn't mention 'global
variables', and instead defines 'scopes of identifiers' (6.2.1).
OK, OK, there is 1 (one) reference to term 'global variable'
(F.8.1-1). Without any definition of the term. It leads me to
believe that it was forgotten to be purged by mistake. But as
usual, I can be wrong.

[snip]
 
N

nobody

CBFalconer said:
The include file is used to specify the access allowed to the code
file. I.e., if you have written foo.c, then foo.h specifies those
elements of foo.c visible in other files. In those other files
you make them visible by including foo.h. You also include foo.h
in foo.c to ensure that those definitions are consistent. Include
guards are also handy.

This is NOT mandated by the standards, compilers, etc. but is
simply good practice.


Ugh. This is analogous to always leaving your car with the keys
in the ignition and engine running. Both tend to lead to total
loss of control.
<ot>
That is right. To regain control back may be *very* time consuming.
Suppose one is working on big project and has to use libraries
writen by other people (likely long gone from company). Library
authors "conveniently" provided "header dump" header files - one
per library. All those "top-level" include other files and they
include other and so on with almost arbitrary level of nesting
(I guess there is some limit in standard, but even without
reaching limit it can be quite a mess). One day one discovers
(s)he needs to use e.g. two of those libraries in program.
However, somwhere deep inside, one is using macro identifier
where the other is using same identifier as enumeration constant.
All would be well if one could rearrange order of includes, but
one can't (one is dependent on the other). So one has to throw
away "global" include files, dissect them up to "leaves" of
"include tree" (from all used libraries), take only "leaf"
include files and include them in correct order in C source file.
After this kind of experience, *I* prefer to spend few seconds
more today (to type in or copy/paste include directives only
for stuff that I need), than hours or days later just to get
the damn thing to compile.
This is not to say that there doesn't exist recently arrived
"professional" who would suggest to defer today's problem
avoidance to tomorrow's problem fixing, preferably at the
expense of someone else.
Here one gets only advice, choice is his/hers.
</ot>

[snip]
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top