Discussion:
Basic, basic, C question!
(too old to reply)
Robby
2009-09-15 21:01:02 UTC
Permalink
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
Giovanni Dicanio
2009-09-15 21:20:37 UTC
Permalink
Post by Robby
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
[...]
Post by Robby
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.
Post by Robby
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
==================================.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
Robby
2009-09-15 22:40:02 UTC
Permalink
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!
Post by Giovanni Dicanio
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
Post by Giovanni Dicanio
Post by Robby
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
[...]
Post by Robby
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.
Post by Robby
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
==================================.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
/* in .h */
extern SOMEDATA g_SomeData;
extern PSOMEDATA g_pSomeData;
Then you can *define* the variable in some .c file.
Giovanni
Igor Tandetnik
2009-09-15 23:13:37 UTC
Permalink
Post by Robby
=====================
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.
Post by Robby
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.
Post by Robby
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.
Post by Robby
We have to give a better
argument as to why this is so unacceptable...
Compiler errors aren't a good enough argument?
Post by Robby
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
Robby
2009-09-16 16:05:02 UTC
Permalink
Hello Igor,
Post by Igor Tandetnik
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!
Post by Igor Tandetnik
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
Post by Igor Tandetnik
Post by Robby
=====================
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.
Post by Robby
All my other structures are typedefed
Typedef is a red herring. You'll have the same problem if you put this
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.
Post by Robby
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.
Post by Robby
We have to give a better
argument as to why this is so unacceptable...
Compiler errors aren't a good enough argument?
Post by Robby
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
Igor Tandetnik
2009-09-16 16:56:43 UTC
Permalink
Post by Robby
Hello Igor,
Post by Igor Tandetnik
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.
How do you know what I would or wouldn't rather see?
Post by Robby
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.
Post by Robby
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.
Post by Robby
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".
Post by Robby
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.
Post by Robby
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
Robby
2009-09-16 18:22:02 UTC
Permalink
Hello Igor,
Post by Igor Tandetnik
You mean - a global variable whose type happens to be a struct type.
Yes, sorry if I have caused confusion.
Post by Igor Tandetnik
The term "global structure" is meaningless.
So this can't be considered as a *global structure* ???? .... I am just
asking!
==========================main.h
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;
=========================
Post by Igor Tandetnik
This question makes no sense to me, sorry. I don't know what you mean by
"extern type".
I am sorry too, bad question. :-)
Post by Igor Tandetnik
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.
Okay, so here I declare 2 global variables bywhich the first one is called
ts which is of tag_ts type and the second one is p_ts of type pointer to
tag_ts, and I am okay doing it this way?
==================================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;
}
====================================
Post by Igor Tandetnik
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?
No, no, no, this fragment defines two global variables of type struct tag_ts
where one being a var and the other being a pointer to a struct tag_ts. When
I said "or simply create global variables which I am not crazy about!" I
meant creating these globally like this in the main.h header file and totally
forgetting about the structure:

int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;

I never said I was crazy about *two global variables* ! I guess I should of
been more specific.
--
Best regards
Roberto
Post by Igor Tandetnik
Post by Robby
Hello Igor,
Post by Igor Tandetnik
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.
How do you know what I would or wouldn't rather see?
Post by Robby
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.
Post by Robby
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.
Post by Robby
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".
Post by Robby
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.
Post by Robby
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!
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
Igor Tandetnik
2009-09-16 18:45:40 UTC
Permalink
Post by Robby
Post by Igor Tandetnik
You mean - a global variable whose type happens to be a struct type.
Yes, sorry if I have caused confusion.
Post by Igor Tandetnik
The term "global structure" is meaningless.
So this can't be considered as a *global structure* ????
Since I don't know the meaning of this term, I can't tell you what can
or cannot be properly described by it.
Post by Robby
.... I am
just asking!
==========================main.h
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;
=========================
This fragment of code defines a structure named tag_ts, and two
variables: ts of type struct tag_ts, and p_ts of type struct tag_ts*.
These two variables are global variables: more precisely, their names
have external linkage. Type names don't have linkage.
Post by Robby
Okay, so here I declare 2 global variables bywhich the first one is
called ts which is of tag_ts type and the second one is p_ts of type
pointer to tag_ts, and I am okay doing it this way?
==================================main.h
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;
I would question your decision to put these definitions into a header
file. Otherwise, I don't see anything immediately wrong with this.
Post by Robby
I guess I
should of been more specific.
Quite.
--
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
Robby
2009-09-16 20:38:01 UTC
Permalink
Thanks Igor and the rest of you for being there to answer my questions!
--
Best regards
Roberto
Post by Igor Tandetnik
Post by Robby
Post by Igor Tandetnik
You mean - a global variable whose type happens to be a struct type.
Yes, sorry if I have caused confusion.
Post by Igor Tandetnik
The term "global structure" is meaningless.
So this can't be considered as a *global structure* ????
Since I don't know the meaning of this term, I can't tell you what can
or cannot be properly described by it.
Post by Robby
.... I am
just asking!
==========================main.h
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;
=========================
This fragment of code defines a structure named tag_ts, and two
variables: ts of type struct tag_ts, and p_ts of type struct tag_ts*.
These two variables are global variables: more precisely, their names
have external linkage. Type names don't have linkage.
Post by Robby
Okay, so here I declare 2 global variables bywhich the first one is
called ts which is of tag_ts type and the second one is p_ts of type
pointer to tag_ts, and I am okay doing it this way?
==================================main.h
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;
I would question your decision to put these definitions into a header
file. Otherwise, I don't see anything immediately wrong with this.
Post by Robby
I guess I
should of been more specific.
Quite.
--
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
jayachandran kamaraj
2009-09-16 13:09:39 UTC
Permalink
Post by Robby
Hello Giovanni!
"'pts' is NULL, so the above line (pts->on_...) should give an error at
run-time."
========================================.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!
Post by Giovanni Dicanio
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
=====================
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
Post by Giovanni Dicanio
Post by Robby
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
[...]
Post by Robby
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.
Post by Robby
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
==================================.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
   /* 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
Robby
2009-09-16 14:44:01 UTC
Permalink
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
Post by Robby
Hello Giovanni!
"'pts' is NULL, so the above line (pts->on_...) should give an error at
run-time."
========================================.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!
Post by Giovanni Dicanio
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
=====================
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
Post by Giovanni Dicanio
Post by Robby
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
[...]
Post by Robby
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.
Post by Robby
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
==================================.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
/* 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
Ulrich Eckhardt
2009-09-17 07:11:18 UTC
Permalink
Post by Robby
struct tag_ts
{
int on_activation_state_1;
long ts_area_1;
long relevant_ctrl_msg_1;
}ts, *p_ts;
[...]
Post by Robby
p_ts = &ts; // created here once and only once!
p_ts->on_activation_state_1 = 11;
This is asinine, you could just write this:

ts.on_activation_state_1 = 42;

There is no need to create a global and then create another global pointer
to that global.
Post by Robby
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.
Two choices:
1. The struct is also only used in a single translation unit
You can then simply use an anonymous structure, no need for any type names:
struct { ... } foo;

2. The struct is used in multiple translation units
This means you have to split into a declaration and definition, which in
turn requires that the type has a name.
// foo.h
struct foo_type
{ ... };
extern foo_type foo;
// foo.cpp
foo_type foo;


Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
Ben Voigt [C++ MVP]
2009-09-17 21:43:14 UTC
Permalink
Post by Ulrich Eckhardt
2. The struct is used in multiple translation units
This means you have to split into a declaration and definition, which in
turn requires that the type has a name.
// foo.h
struct foo_type
{ ... };
extern foo_type foo;
extern struct foo_type foo; // works in both C and C++
Post by Ulrich Eckhardt
// foo.cpp
foo_type foo;
struct foo_type foo; // works in both C and C++
Post by Ulrich Eckhardt
Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
David Webber
2009-09-15 22:49:13 UTC
Permalink
Post by Robby
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
Igor Tandetnik
2009-09-15 23:03:23 UTC
Permalink
Post by David Webber
Post by Robby
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.
Post by David Webber
Then to access the data, you simply use
MyStruct.element;
Surely you mean MyStruct::element
Post by David Webber
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
Scot T Brennecke
2009-09-16 04:22:01 UTC
Permalink
Post by Igor Tandetnik
Post by David Webber
Post by Robby
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.
Post by David Webber
Then to access the data, you simply use
MyStruct.element;
Surely you mean MyStruct::element
Post by David Webber
It's a poor man's namespace really - always a good idea for global data!
Why not just use an actual namespace?
Because scope resolution and namespaces don't exist in C?
Igor Tandetnik
2009-09-16 04:30:13 UTC
Permalink
Post by Scot T Brennecke
Post by Igor Tandetnik
Post by David Webber
Post by Robby
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.
Post by David Webber
Then to access the data, you simply use
MyStruct.element;
Surely you mean MyStruct::element
Post by David Webber
It's a poor man's namespace really - always a good idea for global data!
Why not just use an actual namespace?
Because scope resolution and namespaces don't exist in C?
Neither do static struct members, so David must have been talking about
C++.
--
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
Scot T Brennecke
2009-09-16 04:39:22 UTC
Permalink
Post by Igor Tandetnik
Post by Scot T Brennecke
Post by Igor Tandetnik
Post by David Webber
Post by Robby
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.
Post by David Webber
Then to access the data, you simply use
MyStruct.element;
Surely you mean MyStruct::element
Post by David Webber
It's a poor man's namespace really - always a good idea for global data!
Why not just use an actual namespace?
Because scope resolution and namespaces don't exist in C?
Neither do static struct members, so David must have been talking about
C++.
OK, so you were just carrying on a side conversation with David. I mistook those to be suggestions as better advice for Robby.
David Webber
2009-09-16 07:11:25 UTC
Permalink
Post by Igor Tandetnik
Post by David Webber
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 :-(
Post by Igor Tandetnik
Post by David Webber
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.
Post by Igor Tandetnik
Post by David Webber
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
Ben Voigt [C++ MVP]
2009-09-17 21:46:21 UTC
Permalink
Post by David Webber
Post by Igor Tandetnik
Post by David Webber
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 :-(
Post by Igor Tandetnik
Post by David Webber
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;
It's considered very poor practice to use an object instance to refer to a
static member because anyone reading that will automatically think element
is an instance member variable.

(The exceptions would be when the data type isn't known, is very hard to
name, or the member may be either static or per-instance depending on
template parameters.)
David Webber
2009-09-18 21:30:47 UTC
Permalink
Post by Ben Voigt [C++ MVP]
Post by David Webber
MYSTRUCT MyStruct; // (as it would be in C++)
Mystruct.element;
It's considered very poor practice to use an object instance to refer to a
static member because anyone reading that will automatically think element
is an instance member variable...
I was trying to keep somewhere in line with C - in fact I don't think I ever
do this. What I *do* do is use instances to call static member functions
(and hang the purists <g>.).

In the example I gave, MyClass stores the HINSTANCE of a language resource
DLL statically.

MyClass.DoACertainDialogueBox( ... );

is not static, but

MyClass.LoadString( ... );

is, and if I have an instance, I have no qualms about using it with the
latter.

In fact even the first of these doesn't actually use any non-static data.
But it does require that the constructor has been called, because the
constructor calls AfxSetResourceHandle() and stores the old one, which is
restored by the destructor.

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
Ulrich Eckhardt
2009-09-16 07:04:53 UTC
Permalink
Post by Robby
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.
This doesn't make sense. You typically define structs (or enumerations,
unions and even typedefs) globally. What you don't do regularly is to
define objects (i.e. instances of structs, unions, enumerations or builtin
types).

Using a typedef with a struct allows you to leave out the "struct" from an
object declaration:

struct foo { ... };
foo f; // wrong

typedef struct whatever { ... } bar;
bar b; // correct


Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
Continue reading on narkive:
Loading...