From: David Webber on

"Igor Tandetnik" <itandetnik(a)mvps.org> wrote in message
news:%23BGF7ilNKHA.5488(a)TK2MSFTNGP02.phx.gbl...

> David Webber <dave(a)musical-dot-demon-dot-co.uk> wrote:

>> In circumstances like that I tend to declare structures with all
>> members "static".
>
> No such thing exists in C.

Ah sorry - my memory of what subset of C++ exists in C is obviously getting
rather vague :-(

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

I'm definitely having a bad day expressing myself too. I had in mind

MYSTRUCT MyStruct; // (as it would be in C++)
Mystruct.element;

but

MYSTRUCT::element

would do of course.

>> It's a poor man's namespace really - always a good idea for global
>> data!
>
> Why not just use an actual namespace?

Three reasons, only one appropriate to my erroneous reply:

namespaces (i did remember) do not exist in C.

<Irrelevant to C>
The others are

I've been doing it IIRC since before Microsoft C++ supported namespaces
properly (and I've been maintaining/developing the same code since the mid
1980s) and continued on the "ain't broke; don't fix it" principle.

Also:

(In my C++ code) I have a number of such structures which have entirely
static elements, but also many with lots of static elements and one or two
others. The static functionality can be used independently of the
non-static.

[One useful example carries a static hInstance of a languge resource only
DLL and static data for mapping colours when images are loaded. It can be
used (statically) to load individual resources from the DLL (with static
member functions wrapping the usual methods for loading strings, menus,
images). However it also has a non-static hInstance member. Its
constructor wraps AfxSetResourceHandle() to the language module DLL, but
remembers the current resource handle in the non-static member. The
destructor wraps AfxSetResourceHandle() back to the resource hInstance you
had originally. So it can be used non-statically to wrap dialogue box
operations, ensuring that the dialogue template is loaded from the correct
DLL.]

But that is more information that you need in response to my simple error.
:-)
</Irrelevant to C>

Again, apologies for the error - the brain cells which used to do C on
regular basis must be dying off at an alarming rate.

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: jayachandran kamaraj on
On Sep 15, 5:40 pm, Robby <Ro...(a)discussions.microsoft.com> wrote:
> 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

i really have no idea what the confusion is. you declare a struct
(typdef it so that you don't have to type struct every time, you want
to use it)
for example

typedef struct _stMyStruct {
int nCount;
long llength;
} _stMyStruct_t;

since i used the typedef, now if i want declare a variable of this
struct

_stMyStruct_t myvar;

otherwise

struct _stMyStruct myvar;

the typedef lets me avoid the use of struct wherever i need to use it.

if you declare a variable of struct(pay attention to the language),
then you can define within a source file, then it will be local to the
source file, unless otherwise you want to export it using "extern".
if you declare the same variable in a header file and include that
header file in multiple source files, then you make it global between
all the source files and you have to be very very careful.
just my 2 cents
jc
From: Robby on
Hello jc,

>since i used the typedef, now if i want declare a variable of this struct

>_stMyStruct_t myvar;

Yes, but if I do this in a function and I need to use it in many other
functions, I have to pass it around from function to function!

why not just do this once... and only for this special structure!
==================================main.h
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;
====================================main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h" // main.h included once only!
void f1()
{
p_ts->on_activation_state_1 = 12;
}
int main()
{
p_ts = &ts; // created here once and only once!
p_ts->on_activation_state_1 = 11;
return 0;
}
====================================

>the typedef lets me avoid the use of struct wherever i need to use it.

struct tag_ts will only be required once in the whole program! So for this
special structure, there will never be another creation of struct tag_ts.

--
Best regards
Roberto


"jayachandran kamaraj" wrote:

> On Sep 15, 5:40 pm, Robby <Ro...(a)discussions.microsoft.com> wrote:
> > 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
>
> i really have no idea what the confusion is. you declare a struct
> (typdef it so that you don't have to type struct every time, you want
> to use it)
> for example
>
> typedef struct _stMyStruct {
> int nCount;
> long llength;
> } _stMyStruct_t;
>
> since i used the typedef, now if i want declare a variable of this
> struct
>
> _stMyStruct_t myvar;
>
> otherwise
>
> struct _stMyStruct myvar;
>
> the typedef lets me avoid the use of struct wherever i need to use it.
>
> if you declare a variable of struct(pay attention to the language),
> then you can define within a source file, then it will be local to the
> source file, unless otherwise you want to export it using "extern".
> if you declare the same variable in a header file and include that
> header file in multiple source files, then you make it global between
> all the source files and you have to be very very careful.
> just my 2 cents
> jc
>
From: Robby on
Hello Igor,

>If you put this into a header file, and #include it into more than one
>source file, you'll get linker errors.

No, that's the thing you see, I willl never include it again, like this:
==================================main.h
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;
====================================main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h" // main.h included once only here! never included
elsewhere!
void f1()
{
p_ts->on_activation_state_1 = 12;
}
int main()
{
p_ts = &ts; // created here once and only once!
p_ts->on_activation_state_1 = 11;
f1();
return 0;
}
====================================

But, you would rather see something like this:
====================================main.h
typedef struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}t_s, *p_ts;

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

void f1(struct tag_ts *p)
{
p->on_activation_state_1 = 12;
}

void f2(struct tag_ts *p)
{
p->on_activation_state_1 = 13;
}

int main()
{
t_s tss;
p_ts ts;

ts = &tss;

ts->on_activation_state_1 = 11;
f1(ts);
f2(ts);
return 0;
}
======================================

But now I have to pass ts to every function. In reality, the thing is that
in my application, when I go from window Procedure to window Procedure and I
need this data in the procedures and outside of all procedures, this requires
global scope and for this particular information I though we could do an
exception and do a global structure... that's all! But I would not include
the structure more than once if thats what you are afraid of.

Can we make a structure of extern type?

I don't know....... not convinced! But I will accept that you are right and
I am wrong simply because I may be missing something here!

>Your program will fail to compile.

Maybe I am rushing when reading the posts, but I don't know why you say it
will fail to compile... anyways the above snipits compile and work fine, I
double checked it!
Leaving a structure global as I did in the first sample doesn't cause any
errors and works fine.

So if I have to typedef the structure in the above code samples, I either
have to extern it (which I am not that used to using extern) or simply create
global variables which I am not crazy about!

--
Best regards
Roberto


"Igor Tandetnik" wrote:

> Robby <Robby(a)discussions.microsoft.com> wrote:
> > =====================
> > 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....
>
> If you put this into a header file, and #include it into more than one
> source file, you'll get linker errors.
>
> > All my other structures are typedefed
>
> Typedef is a red herring. You'll have the same problem if you put this
> into a header file:
>
> int ts, *p_ts;
>
> then include it into several sources. The important part is that you
> should only _declare_ variables in a header file, then _define_ them in
> exactly one source file.
>
> > but to refuse a special
> > one time declaration of one structure globally, do we really
> > sincerely believe that it is that critical.
>
> It's not the declaration of a structure that causes the problem - it's
> the definition of a variable.
>
> As to believing - this is not a matter of belief. Your program will fail
> to compile. Try convincing the compiler that its belief system is
> unreasonable.
>
> > We have to give a better
> > argument as to why this is so unacceptable...
>
> Compiler errors aren't a good enough argument?
>
> > I
> > know it breaks the golden rule of not defining strucutres globally
>
> You misstate the rule. This may be the source of your confusion.
> --
> 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
>
>
>
From: Igor Tandetnik on
Robby <Robby(a)discussions.microsoft.com> wrote:
> Hello Igor,
>
>> If you put this into a header file, and #include it into more than
>> one source file, you'll get linker errors.
>
> No, that's the thing you see, I willl never include it again

Then why have a separate header file at all? Just put the code directly
in your C file. Then it's obvious that the variables are only intended
for use in that one source. Mark them static for good measure.

> But, you would rather see something like this:

How do you know what I would or wouldn't rather see?

> But now I have to pass ts to every function. In reality, the thing is
> that in my application, when I go from window Procedure to window
> Procedure and I need this data in the procedures and outside of all
> procedures, this requires global scope and for this particular
> information I though we could do an exception and do a global
> structure... that's all!

You mean - a global variable whose type happens to be a struct type. The
term "global structure" is meaningless. Further, you made the word
"typedef" a central part of your exposition - but typedefs have
absolutely nothing to do with your actual question. This is why, I
suspect, everybody seems to have difficulty understanding what you are
trying to say.

So, your real question seems to be - is it ever valid to use global
variables? Yes, sometimes global variables are justifiable - otherwise
they wouldn't be in the language in the first place.

> But I would not include the structure more
> than once if thats what you are afraid of.

Why should I be afraid of anything in your code? You are the one who'll
have to live with it.

Again - if you don't intend to include it more than once, don't break it
into a separate include file in the first place.

> Can we make a structure of extern type?

This question makes no sense to me, sorry. I don't know what you mean by
"extern type".

> So if I have to typedef the structure in the above code samples

Forget about typedefs. Again - they have nothing to do with the
substance of your question.

> I
> either have to extern it (which I am not that used to using extern)
> or simply create global variables which I am not crazy about!

Wait a minute. You keep showing this:

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

You say this is the code you like and want to use. However, this
fragment defines two global variables. Which you now say you are "not
crazy about" (which I interpret as meaning that you don't particularly
like the idea). How do you reconcile these two contradictory sentiments?
--
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