Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #151048 > unrolled thread
| Started by | Mehdi Amini <atorrses@gmail.com> |
|---|---|
| First post | 2020-04-05 13:10 +0430 |
| Last post | 2020-04-06 20:37 +0100 |
| Articles | 20 on this page of 25 — 10 participants |
Back to article view | Back to comp.lang.c
Ways to avoid global variables Mehdi Amini <atorrses@gmail.com> - 2020-04-05 13:10 +0430
Re: Ways to avoid global variables Mehdi Amini <atorrses@gmail.com> - 2020-04-05 13:23 +0430
Re: Ways to avoid global variables felix@palmen-it.de (Felix Palmen) - 2020-04-05 11:11 +0200
Re: Ways to avoid global variables Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-04-05 02:34 -0700
Re: Ways to avoid global variables James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-04-05 10:48 -0400
Re: Ways to avoid global variables James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-04-05 11:43 -0400
Re: Ways to avoid global variables James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-04-05 16:49 -0400
Re: Ways to avoid global variables Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-04-05 16:12 -0700
Re: Ways to avoid global variables James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-04-05 11:49 -0400
Re: Ways to avoid global variables Mehdi Amini <atorrses@gmail.com> - 2020-04-06 14:11 +0430
Re: Ways to avoid global variables Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-04-06 12:08 +0100
Re: Ways to avoid global variables David Brown <david.brown@hesbynett.no> - 2020-04-05 22:03 +0200
Re: Ways to avoid global variables James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-04-05 16:53 -0400
Re: Ways to avoid global variables Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-04-05 14:11 -0700
Ice cream (Was: Ways to avoid global variables) gazelle@shell.xmission.com (Kenny McCormack) - 2020-04-06 06:45 +0000
Re: Ways to avoid global variables David Brown <david.brown@hesbynett.no> - 2020-04-06 09:19 +0200
Re: Ways to avoid global variables Mehdi Amini <atorrses@gmail.com> - 2020-04-06 13:30 +0430
Re: Ways to avoid global variables Spiros Bousbouras <spibou@gmail.com> - 2020-04-06 09:25 +0000
Re: Ways to avoid global variables Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-04-06 03:03 -0700
Re: Ways to avoid global variables Spiros Bousbouras <spibou@gmail.com> - 2020-04-06 10:16 +0000
Re: Ways to avoid global variables Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-04-06 03:21 -0700
Re: Ways to avoid global variables Spiros Bousbouras <spibou@gmail.com> - 2020-04-06 10:50 +0000
Re: Ways to avoid global variables David Brown <david.brown@hesbynett.no> - 2020-04-06 13:46 +0200
Re: Ways to avoid global variables scott@slp53.sl.home (Scott Lurndal) - 2020-04-06 18:05 +0000
Re: Ways to avoid global variables Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-04-06 20:37 +0100
Page 1 of 2 [1] 2 Next page →
| From | Mehdi Amini <atorrses@gmail.com> |
|---|---|
| Date | 2020-04-05 13:10 +0430 |
| Subject | Ways to avoid global variables |
| Message-ID | <r6c5ie$5b9$1@dont-email.me> |
Hi,
What are the ways to avoid global variables in C ; This is one way that
I know:
// Code:
#include <stdio.h>
#include <stdlib.h>
int gv=0;
int main(void)
{
gv++;
printf("gv is %d\n",gv);
return EXIT_SUCCESS;
}
// Code:
#include <stdio.h>
#include <stdlib.h>
int func(void);
int main(void)
{
int v=func();
printf("v is %d\n",v);
return EXIT_SUCCESS;
}
int func(void)
{
static int sv=0;
sv++;
return sv;
}
Also using function parameters to pass variables , anything else ?
--
www.my-c-codes.com/
Farewell.
[toc] | [next] | [standalone]
| From | Mehdi Amini <atorrses@gmail.com> |
|---|---|
| Date | 2020-04-05 13:23 +0430 |
| Message-ID | <r6c69e$9bk$1@dont-email.me> |
| In reply to | #151048 |
On 4/5/20 1:10 PM, Mehdi Amini wrote:
> Hi,
>
> What are the ways to avoid global variables in C ; This is one way that
> I know:
>
> // Code:
> #include <stdio.h>
> #include <stdlib.h>
>
> int gv=0;
>
> int main(void)
> {
> gv++;
> printf("gv is %d\n",gv);
>
> return EXIT_SUCCESS;
> }
>
> // Code:
> #include <stdio.h>
> #include <stdlib.h>
>
> int func(void);
>
> int main(void)
> {
> int v=func();
> printf("v is %d\n",v);
>
> return EXIT_SUCCESS;
> }
>
> int func(void)
> {
> static int sv=0;
> sv++;
>
> return sv;
> }
>
> Also using function parameters to pass variables , anything else ?
>
To make it more clear, for the unfamiliars to static variables , I can
add this:
// Code:
#include <stdio.h>
#include <stdlib.h>
int func(void);
int main(void)
{
int v;
v=func();
v=func();
printf("v is %d\n",v);
return EXIT_SUCCESS;
}
int func(void)
{
static int sv=0;
sv++;
return sv;
}
--
www.my-c-codes.com/
Farewell.
[toc] | [prev] | [next] | [standalone]
| From | felix@palmen-it.de (Felix Palmen) |
|---|---|
| Date | 2020-04-05 11:11 +0200 |
| Message-ID | <dujolg-u7e1.ln1@mail.home.palmen-it.de> |
| In reply to | #151048 |
* Mehdi Amini <atorrses@gmail.com>:
> What are the ways to avoid global variables in C ; This is one way that
> [...]
> int func(void);
>
> [...]
> int func(void)
> {
> static int sv=0;
This just solves *one* problem of global variables, and arguable not the
important one. You have solved the scope problem (which isn't severe if
your compilation units are not too large and structured logically), but
you didn't solve the lifetime problem. E.g. this code will still
misbehave when used with threads.
My generic answer to your generic question would be: always pass the
objects (or pointers to them) in function arguments whenever they should
be worked on.
--
Dipl.-Inform. Felix Palmen <felix@palmen-it.de> ,.//..........
{web} http://palmen-it.de {jabber} [see email] ,//palmen-it.de
{pgp public key} http://palmen-it.de/pub.txt // """""""""""
{pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2020-04-05 02:34 -0700 |
| Message-ID | <d1e90a72-05b0-4a15-ae72-bc400df7bbcb@googlegroups.com> |
| In reply to | #151048 |
On Sunday, 5 April 2020 09:40:55 UTC+1, Mehdi Amini Valashani son of Bahram wrote:
> Hi,
>
> What are the ways to avoid global variables in C ; This is one way that
> I know:
>
> // Code:
> #include <stdio.h>
> #include <stdlib.h>
>
> int gv=0;
>
> int main(void)
> {
> gv++;
> printf("gv is %d\n",gv);
>
> return EXIT_SUCCESS;
> }
>
> // Code:
> #include <stdio.h>
> #include <stdlib.h>
>
> int func(void);
>
> int main(void)
> {
> int v=func();
> printf("v is %d\n",v);
>
> return EXIT_SUCCESS;
> }
>
> int func(void)
> {
> static int sv=0;
> sv++;
>
> return sv;
> }
>
> Also using function parameters to pass variables , anything else ?
>
Declare a struct globals in globals.h, instnatiate the struct in main,
the pass it down to every function that requires globals.
struct globals
{
int gv;
}
int main()
{
struct globals g;
g.gv = 42;
foo(&globals, 1, 2, 3);
}
This solution means that it is relatively easy to change to a system
in which you have two or more sets of globals, e.g. two 'worlds" in a
video game.
The other way is
static int gv;
int getgv() { return gv;}
void putgv(int x) { gv = x;}
This is considerd an anti-pattern. Whilst the theory is that you can
intercept gets and sets, in reality that seldom happens. All you are
doing is wrapping up the variable. It's better to know what gv is
used for, then group the functions that need access to it in one file.
So if, for example, it's a "nex payroll id" counter, the "create
employee" function would be in that file, put gv in the payroll id
field, and increment it. You'd then maybe have a function`"resetpayrollid"
which sets it to the base value.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-04-05 10:48 -0400 |
| Message-ID | <r6cr3a$bt1$1@dont-email.me> |
| In reply to | #151048 |
On 4/5/20 4:40 AM, Mehdi Amini wrote: > Hi, > > What are the ways to avoid global variables in C ; The single most important way is to pass around pointers to those variables, usually as function arguments. Functionally related variables can be grouped into structs, and then you only need to pass around a pointer to a single struct in order to access many different variables.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-04-05 11:43 -0400 |
| Message-ID | <r6cua6$1o0$1@dont-email.me> |
| In reply to | #151074 |
On 4/5/20 11:07 AM, Stefan Ram wrote: > James Kuyper <jameskuyper@alumni.caltech.edu> writes: >> The single most important way is to pass around pointers to those >> variables, usually as function arguments. > > Pointers can be the null pointer or point to entities > (functions or objects), but not to variables. The C standard doesn't define the term "variable". The C++ standard does, and in the C context the C++ standard's definition boils down to "named object". AFAICT, that definition fits all uses of the term "variable" as a noun in the C standard, so that's the definition I use. If a pointer can point to an object, it can, in particular, point at an object that happens to have a name. I'm curious - what do you consider the definition of "variable" to be, that justifies your claim that pointers can't point at them? > However, when global variables are a problem, one needs to > take into consideration whether any workaround solves the > problem or merely reduces its visibility. To do this, ask I've got a lot of experience with the problems that global variables can cause. I was made responsible for a large body of code written by scientists who were more familiar with Fortran than C, and more familiar with the relevant science than with Fortran. It contained a large number of global variables, and I was subject to rules that prohibited me from making changes to any source code file solely for the purpose of cleaning up such problems: I had to have either a defect that needed to be fixed or a new feature that needed to be implemented, and doing so had to require changes to a particular source code file I was modifying. Given those rules, I could only remove those variables slowly, and after working on that project for 30 years I had not yet succeeded in removing all of them. In my experience, by far the most common problem with global variables IS their excessive visibility, so I would not describe that as "merely".
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-04-05 16:49 -0400 |
| Message-ID | <r6dg8f$19s$1@dont-email.me> |
| In reply to | #151077 |
On 4/5/20 12:10 PM, Stefan Ram wrote:
> James Kuyper <jameskuyper@alumni.caltech.edu> writes:
>> On 4/5/20 11:07 AM, Stefan Ram wrote:
>>> Pointers can be the null pointer or point to entities
>>> (functions or objects), but not to variables.
>> I'm curious - what do you consider the definition of "variable" to be,
>> that justifies your claim that pointers can't point at them?
>
> A variable contains all the information that is given by the
> declaration of a name and by the scope of this declaration.
> This encompasses the name itself, its type, and also, for
> example, whether this is an automatic variable.
>
> For example, in the block,
>
> { int x; }
>
> , a variable with the name "x" and the type "int" and
> automatic storage duration is declared.
>
> Akin to:
>
> |In C, all variables must be declared before they are used,
> |usually at the beginning of the function before any
> |executable statements. A declaration announces the
> |properties of variables; it consists of a name and a list of
> |variables, such as
> |int fahr, celsius;
> |int lower, upper, step;
> The C Programming Language, Second Edition
>
> When one has a pointer to an object that is bound to a name,
> one cannot reach information about the name.
I could find only a couple of clauses in the standard where the
difference between your definition of a "variable" and mine matters:
7.17.2.1p2: "Concurrent access to the variable being initialized, even
via an atomic operation, constitutes a data race."
Since a pointer does not access a variable, but only the object, does
that mean that concurrent access to the object itself, when the access
is through pointers, would NOT constitute a data race?
Similarly 7.17.2.2p2.
..
>> In my experience, by far the most common problem with global variables
>> IS their excessive visibility, so I would not describe that as "merely".
>
> Global variables /hide/ dependencies of functions.
>
> For example, the behavior of
>
> void print( int const n ){ printf( "%d\n", n ); }
>
> depends on "stdout", but this is not shown in the interface.
Yes, and they hide those dependencies by being excessively visible.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2020-04-05 16:12 -0700 |
| Message-ID | <875zedplvx.fsf@nosuchdomain.example.com> |
| In reply to | #151077 |
ram@zedat.fu-berlin.de (Stefan Ram) writes:
> James Kuyper <jameskuyper@alumni.caltech.edu> writes:
>>On 4/5/20 11:07 AM, Stefan Ram wrote:
>>>Pointers can be the null pointer or point to entities
>>>(functions or objects), but not to variables.
>>I'm curious - what do you consider the definition of "variable" to be,
>>that justifies your claim that pointers can't point at them?
>
> A variable contains all the information that is given by the
> declaration of a name and by the scope of this declaration.
> This encompasses the name itself, its type, and also, for
> example, whether this is an automatic variable.
>
> For example, in the block,
>
> { int x; }
>
> , a variable with the name "x" and the type "int" and
> automatic storage duration is declared.
Like most definitions of the word "variable" I've seen, this makes
statements about variables or about what they do, but it doesn't
tell me what a variable *is*.
I think most programmers would assume that a "variable" is a kind
of object. Others might say that it's some kind of abstract thing
that can refer to an object. My best guess from your wording is
that a "variable" is a compile-time symbol table entry.
Given:
int x;
int *p = &x;
I would say that p points to a variable -- or, since C doesn't say
what a "variable" is, that p points to a named object. It's certainly
true that p does not give access to the name "x".
> Akin to:
>
> |In C, all variables must be declared before they are used,
> |usually at the beginning of the function before any
> |executable statements. A declaration announces the
> |properties of variables; it consists of a name and a list of
> |variables, such as
> |int fahr, celsius;
> |int lower, upper, step;
> The C Programming Language, Second Edition
>
> When one has a pointer to an object that is bound to a name,
> one cannot reach information about the name.
>
> When a pointer would be able to point to a variable, I would
> then also expect to be able to obtain the name via the pointer.
>
> Via recursion, several objects can be bound to a variable that
> is declared once. This shows that there is not a 1:1 correspondence
> between variables and objects.
>
>>In my experience, by far the most common problem with global variables
>>IS their excessive visibility, so I would not describe that as "merely".
>
> Global variables /hide/ dependencies of functions.
>
> For example, the behavior of
>
> void print( int const n ){ printf( "%d\n", n ); }
>
> depends on "stdout", but this is not shown in the interface.
>
>
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-04-05 11:49 -0400 |
| Message-ID | <r6cum5$4hs$1@dont-email.me> |
| In reply to | #151074 |
On 4/5/20 10:48 AM, James Kuyper wrote: > On 4/5/20 4:40 AM, Mehdi Amini wrote: >> Hi, >> >> What are the ways to avoid global variables in C ; > > The single most important way is to pass around pointers to those > variables, usually as function arguments. Functionally related variables > can be grouped into structs, and then you only need to pass around a > pointer to a single struct in order to access many different variables. I just realized that I left out an important part of that advice. Before you pass around those pointers, you should first change the global variables to not be global. At worst, they should have file scope definitions with internal linkage, but if you can, make them local to a function.
[toc] | [prev] | [next] | [standalone]
| From | Mehdi Amini <atorrses@gmail.com> |
|---|---|
| Date | 2020-04-06 14:11 +0430 |
| Message-ID | <r6etft$m7r$1@dont-email.me> |
| In reply to | #151078 |
On 4/5/20 8:19 PM, James Kuyper wrote:
> On 4/5/20 10:48 AM, James Kuyper wrote:
>> On 4/5/20 4:40 AM, Mehdi Amini wrote:
>>> Hi,
>>>
>>> What are the ways to avoid global variables in C ;
>>
>> The single most important way is to pass around pointers to those
>> variables, usually as function arguments. Functionally related variables
>> can be grouped into structs, and then you only need to pass around a
>> pointer to a single struct in order to access many different variables.
>
> I just realized that I left out an important part of that advice. Before
> you pass around those pointers, you should first change the global
> variables to not be global. At worst, they should have file scope
> definitions with internal linkage, but if you can, make them local to a
> function.
>
Is this an acceptable demo ?
// Code:
#include <stdio.h>
#include <stdlib.h>
#define N 3
typedef struct
{
int i;
char c;
} s_t;
s_t * container(s_t *);
s_t * adder(s_t *);
s_t init(void);
s_t caller(void);
int main(void)
{
s_t ms;
ms=caller();
printf("i is %d , c is '%c'\n",ms.i,ms.c);
return EXIT_SUCCESS;
}
s_t caller(void)
{
s_t sf=init();
int ind;
for(ind=0; ind<N; ind++)
adder(&sf);
return sf;
}
s_t * container(s_t * ins)
{
static s_t cs;
cs.i=ins->i;
cs.c=ins->c;
return &cs;
}
s_t * adder(s_t * ins)
{
ins->i++;
ins->c++;
return ins;
}
s_t init(void)
{
s_t fs={.i=0 , .c='0'};
return fs;
}
// Result:
$gcc -o main *.c -Wall -Wextra -pedantic -std=c11
$main
i is 3 , c is '3'
--
www.my-c-codes.com/
Farewell.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2020-04-06 12:08 +0100 |
| Message-ID | <87k12sc1n9.fsf@bsb.me.uk> |
| In reply to | #151120 |
Mehdi Amini <atorrses@gmail.com> writes:
> On 4/5/20 8:19 PM, James Kuyper wrote:
>> On 4/5/20 10:48 AM, James Kuyper wrote:
>>> On 4/5/20 4:40 AM, Mehdi Amini wrote:
>>>> Hi,
>>>>
>>>> What are the ways to avoid global variables in C ;
>>>
>>> The single most important way is to pass around pointers to those
>>> variables, usually as function arguments. Functionally related variables
>>> can be grouped into structs, and then you only need to pass around a
>>> pointer to a single struct in order to access many different variables.
>>
>> I just realized that I left out an important part of that advice. Before
>> you pass around those pointers, you should first change the global
>> variables to not be global. At worst, they should have file scope
>> definitions with internal linkage, but if you can, make them local to a
>> function.
>
> Is this an acceptable demo ?
I don't think so...
> // Code:
> #include <stdio.h>
> #include <stdlib.h>
>
> #define N 3
>
> typedef struct
> {
> int i;
> char c;
> } s_t;
>
> s_t * container(s_t *);
> s_t * adder(s_t *);
> s_t init(void);
>
> s_t caller(void);
>
> int main(void)
> {
> s_t ms;
> ms=caller();
> printf("i is %d , c is '%c'\n",ms.i,ms.c);
>
> return EXIT_SUCCESS;
> }
>
> s_t caller(void)
> {
> s_t sf=init();
> int ind;
> for(ind=0; ind<N; ind++)
> adder(&sf);
> return sf;
> }
>
> s_t * container(s_t * ins)
> {
> static s_t cs;
> cs.i=ins->i;
> cs.c=ins->c;
>
> return &cs;
> }
>
> s_t * adder(s_t * ins)
> {
> ins->i++;
> ins->c++;
>
> return ins;
> }
>
> s_t init(void)
> {
> s_t fs={.i=0 , .c='0'};
> return fs;
> }
This program can be re-written as:
#include <stdio.h>
typedef struct { int i; char c; } s_t;
s_t *adder(s_t *ins) { ins->i++; ins->c++; return ins; }
s_t init(void) { return (s_t){ .i = 0, .c = '0'}; }
s_t caller(void)
{
s_t sf = init();
for(int ind = 0; ind < 3; ind++)
adder(&sf);
return sf;
}
int main(void)
{
s_t ms = caller();
printf("i is %d, c is '%c'\n", ms.i, ms.c);
}
I don't see any connection to the discussion of "global variables" (a
problematic term in C).
The only function that seemed relevant was "container" and all that does
is return a pointer to a static object, thereby removing the need to
give it a name with external linkage. You have replaced a globally
named object with a globally named function that provides the same
unrestricted access to the object.
In the, the closest thing to a global variable is an object with static
storage duration and a name with external linkage. The more of these
you have, the harder it is to keep you code clear and maintainable.
You can improve matters by making objects with static storage duration
have only file-scope names. You might even, in some cases, be able to
give such objects names valid only in one function body (as you do with
"container") but you must not then return a pointer to that object or
you will make it globally accessible again.
Even if you restrict the linkage, and return a pointer to const type,
such objects are problematic. For example:
const char *num_length(int n)
{
static char buf[100];
sprintf(buf, "%n", n);
return buf;
}
will go wrong in expressions like
size_t msg_len = strlen(n_as_string(p)) + strlen(n_as_string(q)) + 2;
And don't even think about multi-threaded uses!
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-04-05 22:03 +0200 |
| Message-ID | <r6ddj4$dvu$1@dont-email.me> |
| In reply to | #151048 |
On 05/04/2020 10:40, Mehdi Amini wrote: > Hi, > > What are the ways to avoid global variables in C The first question you should be asking yourself is "what do I mean by global variables" ? Do you mean data with statically allocated addresses and program lifetime? Do you mean data that is used by a set of known functions (such as functions within one C file)? Do you mean data that is used randomly by lots of bits of code throughout the program? Do you include data that is dynamically allocated, but accessed from many different places? The second question you should be asking yourself is /why/ you think it is a good idea to avoid global variables in C? Is this just because you heard someone say it as a rule, or is it because you see it causing real problems?
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-04-05 16:53 -0400 |
| Message-ID | <r6dgfo$19s$2@dont-email.me> |
| In reply to | #151096 |
On 4/5/20 4:03 PM, David Brown wrote: > On 05/04/2020 10:40, Mehdi Amini wrote: >> Hi, >> >> What are the ways to avoid global variables in C > > The first question you should be asking yourself is "what do I mean by > global variables" ? Do you mean data with statically allocated > addresses and program lifetime? Do you mean data that is used by a set > of known functions (such as functions within one C file)? Do you mean > data that is used randomly by lots of bits of code throughout the > program? Do you include data that is dynamically allocated, but > accessed from many different places? I don't use the term "global variables", precisely because the term is not defined by the C standard. However, most uses of the term that I have seen refer to objects whose names have external linkage. > The second question you should be asking yourself is /why/ you think it > is a good idea to avoid global variables in C? Is this just because you > heard someone say it as a rule, or is it because you see it causing real > problems? Because their names have external linkage, they can be referred to from anywhere in the program, which makes it difficult to track down which particular pieces of code modify or use them.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2020-04-05 14:11 -0700 |
| Message-ID | <e74ffce3-e208-43d5-ab1a-df5e77b3c212@googlegroups.com> |
| In reply to | #151100 |
On Sunday, 5 April 2020 21:53:20 UTC+1, James Kuyper wrote: > On 4/5/20 4:03 PM, David Brown wrote: > > > The second question you should be asking yourself is /why/ you think it > > is a good idea to avoid global variables in C? Is this just because you > > heard someone say it as a rule, or is it because you see it causing real > > problems? > > Because their names have external linkage, they can be referred to from > anywhere in the program, which makes it difficult to track down which > particular pieces of code modify or use them. > There's another good reason. Say we are writing a video game, with a simulated world containing game objects. Now pretty much every medium-level function is going to need access to that world. For instance, if the player shoots, you've got to put the bullet into the world, then check for collisions with shootable objects, then maybe you've got to check for baddies and call their "try to evade bullet" procedures. However if you make the world global, then you can only have one world. If you wrap it up into a structure and pass it down, you can switch between worlds. Which you might well want to do at a later stage.
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2020-04-06 06:45 +0000 |
| Subject | Ice cream (Was: Ways to avoid global variables) |
| Message-ID | <r6ej6a$3n1$1@news.xmission.com> |
| In reply to | #151100 |
In article <r6dgfo$19s$2@dont-email.me>, James Kuyper <jameskuyper@alumni.caltech.edu> wrote: ... >I don't use the term "global variables", precisely because the term is >not defined by the C standard. I take it that you never use the term "ice cream" either, since that, also, is not defined by the C standard. -- Watching ConservaLoons playing with statistics and facts is like watching a newborn play with a computer. Endlessly amusing, but totally unproductive.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-04-06 09:19 +0200 |
| Message-ID | <r6el5n$vt$1@dont-email.me> |
| In reply to | #151100 |
On 05/04/2020 22:53, James Kuyper wrote: > On 4/5/20 4:03 PM, David Brown wrote: >> On 05/04/2020 10:40, Mehdi Amini wrote: >>> Hi, >>> >>> What are the ways to avoid global variables in C >> >> The first question you should be asking yourself is "what do I mean by >> global variables" ? Do you mean data with statically allocated >> addresses and program lifetime? Do you mean data that is used by a set >> of known functions (such as functions within one C file)? Do you mean >> data that is used randomly by lots of bits of code throughout the >> program? Do you include data that is dynamically allocated, but >> accessed from many different places? > > I don't use the term "global variables", precisely because the term is > not defined by the C standard. However, most uses of the term that I > have seen refer to objects whose names have external linkage. Agreed (on both counts). But I am not asking what /you/ mean by "global variables" - I am asking what the OP means. For some aspects (some risks of problems and some uses and benefits), any of my suggestions above could apply. I want him to think about the question, not give a set answer from what someone else thinks. > >> The second question you should be asking yourself is /why/ you think it >> is a good idea to avoid global variables in C? Is this just because you >> heard someone say it as a rule, or is it because you see it causing real >> problems? > > Because their names have external linkage, they can be referred to from > anywhere in the program, which makes it difficult to track down which > particular pieces of code modify or use them. > That depends entirely on the type of program. In a smaller, self-contained program it is extremely easy to track down where the variable is used in code - you do a text or symbol search for it. (Any good IDE will have "find references" tools.) On the other hand, if you access data via pointers rather than global name, it becomes extremely /difficult/ to find all uses of the variable - you may have to trace through many layers of functions to follow the path of the pointers. And while global variables have a bad reputation, and certainly can be misused in many ways, knee-jerk and thoughtless alternatives are often equally bad, or worse. That is why I want the OP to think about /why/ he wants to avoid global variables, to see what kind of program structure would be a better alternative.
[toc] | [prev] | [next] | [standalone]
| From | Mehdi Amini <atorrses@gmail.com> |
|---|---|
| Date | 2020-04-06 13:30 +0430 |
| Message-ID | <r6er3n$6le$1@dont-email.me> |
| In reply to | #151096 |
On 4/6/20 12:33 AM, David Brown wrote: > On 05/04/2020 10:40, Mehdi Amini wrote: >> Hi, >> >> What are the ways to avoid global variables in C > > The first question you should be asking yourself is "what do I mean by > global variables" ? From this link: https://www.codingunit.com/c-tutorial-functions-and-global-local-variables "A global variable is a variable that is declared outside all functions. " I would say without /static/ keyword. > The second question you should be asking yourself is /why/ you think it > is a good idea to avoid global variables in C? Is this just because you > heard someone say it as a rule, or is it because you see it causing real > problems? > > I think this is not standard practice to use global variables. Just like it is not OK to use goto. I have been coding XBoard (a chess GUI) , it has lot's of global variables. Unfortunately I added some more to it. -- www.my-c-codes.com/ Farewell.
[toc] | [prev] | [next] | [standalone]
| From | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| Date | 2020-04-06 09:25 +0000 |
| Message-ID | <ch88ItrMgKg0uu64vp@bongo-ra.co> |
| In reply to | #151117 |
On Mon, 6 Apr 2020 13:30:38 +0430 Mehdi Amini <atorrses@gmail.com> wrote: > On 4/6/20 12:33 AM, David Brown wrote: > > On 05/04/2020 10:40, Mehdi Amini wrote: > >> Hi, > >> > >> What are the ways to avoid global variables in C > > > > The first question you should be asking yourself is "what do I mean by > > global variables" ? > > From this link: > https://www.codingunit.com/c-tutorial-functions-and-global-local-variables > > "A global variable is a variable that is declared outside all functions. " > > I would say without /static/ keyword. Seems like a reasonable definition to me and the kind of thing I would understand intuitively as a global variable. > > The second question you should be asking yourself is /why/ you think it > > is a good idea to avoid global variables in C? Is this just because you > > heard someone say it as a rule, or is it because you see it causing real > > problems? > > I think this is not standard practice to use global variables. Terms like "standard practice" are too vague to form the basis for useful (technical) discussion. They are suggestive without making any concrete claims. > Just like it is not OK to use goto. We already have one big issue in this thread , let's not start another. > I have been coding XBoard (a chess GUI) , it has lot's of global variables. Great , we now have something concrete to talk about. Can you mention some specific problems the global variables in the XBoard code caused for you ? > Unfortunately I added some more to it. Then perhaps you can give a specific example and people here can tell you if they consider some alternative preferable. Saying "Unfortunately" unnecessarily prejudices the discussion. -- Time for everyone to be socially responsible or be made to be PCC Marc Jones https://www.bbc.co.uk/news/uk-england-51988877
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2020-04-06 03:03 -0700 |
| Message-ID | <e46183e0-cbd4-4ec0-a2b0-495584dd3a6b@googlegroups.com> |
| In reply to | #151118 |
On Monday, 6 April 2020 10:25:24 UTC+1, Spiros Bousbouras wrote:
>
> > I would say without /static/ keyword.
>
> Seems like a reasonable definition to me and the kind of thing I would
> understand intuitively as a global variable.
>
Say we've got this
static int numberbase = 10;
void setnumberbase(int base)
{
if(base < 2)
numberbase = 2;
else if(base > 16)
numberbase = 16;
else
numberbase = base;
}
int getnumberbase(void)
{
return numberbase;
}
Our variable is protected - it can't go out of range. But it's
globally visible. Anyone who includes our header can set the
numberbase for the whole program.
[toc] | [prev] | [next] | [standalone]
| From | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| Date | 2020-04-06 10:16 +0000 |
| Message-ID | <hai46oRQo9Gu4hMXqH@bongo-ra.co> |
| In reply to | #151121 |
On Mon, 6 Apr 2020 03:03:02 -0700 (PDT)
Malcolm McLean <malcolm.arthur.mclean@gmail.com> wrote:
> On Monday, 6 April 2020 10:25:24 UTC+1, Spiros Bousbouras wrote:
> >
> > > I would say without /static/ keyword.
> >
> > Seems like a reasonable definition to me and the kind of thing I would
> > understand intuitively as a global variable.
> >
> Say we've got this
>
> static int numberbase = 10;
>
> void setnumberbase(int base)
> {
> if(base < 2)
> numberbase = 2;
> else if(base > 16)
> numberbase = 16;
> else
> numberbase = base;
> }
>
> int getnumberbase(void)
> {
> return numberbase;
> }
>
> Our variable is protected - it can't go out of range. But it's
> globally visible. Anyone who includes our header can set the
> numberbase for the whole program.
Function definitions should not go into headers. So you would put
in a header
void setnumberbase(int) ;
int getnumberbase(void) ;
and #include this in files which need to access numberbase .So
what's the problem , what point were you trying to make ?
--
vlaho.ninja/prog
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web