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


Groups > comp.lang.c > #151128

Re: Ways to avoid global variables

From Ben Bacarisse <ben.usenet@bsb.me.uk>
Newsgroups comp.lang.c
Subject Re: Ways to avoid global variables
Date 2020-04-06 12:08 +0100
Organization A noiseless patient Spider
Message-ID <87k12sc1n9.fsf@bsb.me.uk> (permalink)
References <r6c5ie$5b9$1@dont-email.me> <r6cr3a$bt1$1@dont-email.me> <r6cum5$4hs$1@dont-email.me> <r6etft$m7r$1@dont-email.me>

Show all headers | View raw


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.

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

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

csiph-web