Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #151128
| 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> |
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
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