From: Robby on
Hello,

Okay, I know that defining structures globally is not a good programming
habit and boy did I learn that one from you guys. So we should always typedef
the structs so that we are able to reuse them whereever we need them.

Simply put... so doing stuff like this is okay! right?
====================================.h
typedef struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;

======================================.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
ts t;
p_ts pts;

pts = NULL;

t.on_activation_state_1 = 10;
pts->on_activation_state_1 = 11;

return 0;
}
===================================

But suppose I just need a structure to hold some data globally and I know I
will never ever need more than one instance. It will simply reside globally
and will be accessed whenever required by other functions. Now in my sample I
did not show functions accessing the data, but you know what I mean.

Is it acceptable to just keep a structure holding specific reusable
informations like this:

==================================.h
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;

====================================.c
int main()
{
p_ts = &ts;
p_ts->on_activation_state_1 = 11;
return 0;
}
====================================

The reason I am asking is I know we went through alot of this but always
within the typedefing of structures concept....Now, I find it sort wastefull
to typedef a structure that its only purpose is to hold one set of
informations which will be read and written too so its information are
globally available from *all* functions without the necessity of passing its
pointer around from one function to another.

I could use global variables, but prefer a structure.

Thanks for all your feedback!

--
Best regards
Roberto
From: Giovanni Dicanio on
Robby ha scritto:

> Simply put... so doing stuff like this is okay! right?
> ====================================.h
> typedef struct tag_ts
> {
> int on_activation_state_1;
> long ts_area_1;
> long relevant_ctrl_msg_1;
> }ts, *p_ts;
>
> ======================================.c
[...]
> int main()
> {
> ts t;
> p_ts pts;
>
> pts = NULL;
>
> t.on_activation_state_1 = 10;
> pts->on_activation_state_1 = 11;

'pts' is NULL, so the above line (pts->on_...) should give an error at
run-time.

> But suppose I just need a structure to hold some data globally and I know I
> will never ever need more than one instance. It will simply reside globally
> and will be accessed whenever required by other functions. Now in my sample I
> did not show functions accessing the data, but you know what I mean.
>
> Is it acceptable to just keep a structure holding specific reusable
> informations like this:
>
> ==================================.h
> struct tag_ts
> {
> int on_activation_state_1;
> long ts_area_1;
> long relevant_ctrl_msg_1;
> }ts, *p_ts;

The problem with this code is that 'ts' and 'p_ts' are *global*
variables *defined* in a header file.
Instead, you should put *declarations* (not definitions) of variables in
the header files.

I would just use the typedef with a proper naming convention (e.g. all
uppercase, like Win32 SDK does) for the structures (and use meaningful
names, instead of 'ts'), e.g.

typedef struct tagSomeData
{
...

} SOMEDATA, *PSOMEDATA;

If you really want to use a global variable, I would use a prefix for
that (like 'g_' from *g*lobal), and *declare* it extern in the header file:

/* in .h */

extern SOMEDATA g_SomeData;
extern PSOMEDATA g_pSomeData;

Then you can *define* the variable in some .c file.


Giovanni
From: Robby on
Hello Giovanni!

"'pts' is NULL, so the above line (pts->on_...) should give an error at
run-time."

Sorry Giovanni, it should of been :
========================================.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;

int main()
{
ts t;
p_ts pts;

pts = &t;

t.on_activation_state_1 = 10;
pts->on_activation_state_1 = 11;

return 0;
}
=======================================
Sometimes I post with compilation but without trying the program!

>Instead, you should put *declarations* (not definitions) of variables in
>the header files.

Yes, I know, but is it possible that we are that picky, that we shouldn't
accept this as a global object:

=====================
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;
=====================

I don't get what it would change if we leave it like this.... there really
isn't any confusion here, we know what it does, we know where it is, we have
access to it from anywhere we want and we do it for very very specific and
special situation(s)... in my case it would be only this once. All my other
structures are typedefed and are defined in their respective functions as you
say.... but to refuse a special one time declaration of one structure
globally, do we really sincerely believe that it is that critical. We have to
give a better argument as to why this is so unacceptable...I say *we* here
because I am convinced that it should be frowned upon.... but in this
particular situation, I frown upon it because this community says so. So its
like I am listening to you guys, but don't really know why. I know it breaks
the golden rule of not defining strucutres globally, but in special
conditions... why not!

I have always listened to everyone here about this and the best answer I got
was that it is important for the reusability of the structures. And I
realized this as I continued programming that it made sence and I have this
community to thank for that. I tell ya, most MCU programmers don't even look
at this, they just do everything global and I agree, after a while its a
mess.

But in this particular case, I will not be re-using it ! and it wouldn't
even effect the program's runtime efficiency nor would it create confusion.
What I am trying to say, is following a golden rule prevents kaos... that I
understand, but this time it doesn't. I need a better explanation that would
really convince me that declaring and defining several structures holding
*special* data globally is a nono. I am not contemplating to do dozens of
structures this way... but one or two very specific ones in the whole
program... why not? In other words give me one good reason that would
convince me to use extern or typedef for *every* structure and pass its
pointer around even though the structure requires its definition only once in
the whole program as opposed to just declaring it and defining it once
globally as done in the innitial post.

In all due respect Giovanni, my post is not geared towards you ... you know
that right! Its geared towards the search of the true intent behind the rule
blessed and following by so many C programmers.

PS simply curious!

--
Best regards
Roberto


"Giovanni Dicanio" wrote:

> Robby ha scritto:
>
> > Simply put... so doing stuff like this is okay! right?
> > ====================================.h
> > typedef struct tag_ts
> > {
> > int on_activation_state_1;
> > long ts_area_1;
> > long relevant_ctrl_msg_1;
> > }ts, *p_ts;
> >
> > ======================================.c
> [...]
> > int main()
> > {
> > ts t;
> > p_ts pts;
> >
> > pts = NULL;
> >
> > t.on_activation_state_1 = 10;
> > pts->on_activation_state_1 = 11;
>
> 'pts' is NULL, so the above line (pts->on_...) should give an error at
> run-time.
>
> > But suppose I just need a structure to hold some data globally and I know I
> > will never ever need more than one instance. It will simply reside globally
> > and will be accessed whenever required by other functions. Now in my sample I
> > did not show functions accessing the data, but you know what I mean.
> >
> > Is it acceptable to just keep a structure holding specific reusable
> > informations like this:
> >
> > ==================================.h
> > struct tag_ts
> > {
> > int on_activation_state_1;
> > long ts_area_1;
> > long relevant_ctrl_msg_1;
> > }ts, *p_ts;
>
> The problem with this code is that 'ts' and 'p_ts' are *global*
> variables *defined* in a header file.
> Instead, you should put *declarations* (not definitions) of variables in
> the header files.
>
> I would just use the typedef with a proper naming convention (e.g. all
> uppercase, like Win32 SDK does) for the structures (and use meaningful
> names, instead of 'ts'), e.g.
>
> typedef struct tagSomeData
> {
> ...
>
> } SOMEDATA, *PSOMEDATA;
>
> If you really want to use a global variable, I would use a prefix for
> that (like 'g_' from *g*lobal), and *declare* it extern in the header file:
>
> /* in .h */
>
> extern SOMEDATA g_SomeData;
> extern PSOMEDATA g_pSomeData;
>
> Then you can *define* the variable in some .c file.
>
>
> Giovanni
>
From: David Webber on

"Robby" <Robby(a)discussions.microsoft.com> wrote in message
news:1BE3A450-F943-45B0-A25D-7D13980D761B(a)microsoft.com...

> But suppose I just need a structure to hold some data globally and I know
> I
> will never ever need more than one instance. It will simply reside
> globally
> and will be accessed whenever required by other functions....

In circumstances like that I tend to declare structures with all members
"static".

Then to access the data, you simply use

MyStruct.element;

It's a poor man's namespace really - always a good idea for global data!

Dave

--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm

From: Igor Tandetnik on
David Webber <dave(a)musical-dot-demon-dot-co.uk> wrote:
> "Robby" <Robby(a)discussions.microsoft.com> wrote in message
> news:1BE3A450-F943-45B0-A25D-7D13980D761B(a)microsoft.com...
>
>> But suppose I just need a structure to hold some data globally and I
>> know I
>> will never ever need more than one instance. It will simply reside
>> globally
>> and will be accessed whenever required by other functions....
>
> In circumstances like that I tend to declare structures with all
> members "static".

No such thing exists in C.

> Then to access the data, you simply use
>
> MyStruct.element;

Surely you mean MyStruct::element

> It's a poor man's namespace really - always a good idea for global
> data!

Why not just use an actual namespace?
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925