Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #151048 > unrolled thread

Ways to avoid global variables

Started byMehdi Amini <atorrses@gmail.com>
First post2020-04-05 13:10 +0430
Last post2020-04-06 20:37 +0100
Articles 20 on this page of 25 — 10 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#151048 — Ways to avoid global variables

FromMehdi Amini <atorrses@gmail.com>
Date2020-04-05 13:10 +0430
SubjectWays 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]


#151049

FromMehdi Amini <atorrses@gmail.com>
Date2020-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]


#151052

Fromfelix@palmen-it.de (Felix Palmen)
Date2020-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]


#151056

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-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]


#151074

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-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]


#151077

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-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]


#151099

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-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]


#151106

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2020-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]


#151078

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-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]


#151120

FromMehdi Amini <atorrses@gmail.com>
Date2020-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]


#151128

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-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]


#151096

FromDavid Brown <david.brown@hesbynett.no>
Date2020-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]


#151100

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-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]


#151102

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-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]


#151111 — Ice cream (Was: Ways to avoid global variables)

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2020-04-06 06:45 +0000
SubjectIce 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]


#151114

FromDavid Brown <david.brown@hesbynett.no>
Date2020-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]


#151117

FromMehdi Amini <atorrses@gmail.com>
Date2020-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]


#151118

FromSpiros Bousbouras <spibou@gmail.com>
Date2020-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]


#151121

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-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]


#151122

FromSpiros Bousbouras <spibou@gmail.com>
Date2020-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