Re: Newbie question
- From: Flash Gordon <spam@xxxxxxxxxxxxxxxxxx>
- Date: Sun, 18 Dec 2005 10:14:59 +0000
Longfellow wrote:
After further review:
On 2005-12-17, Flash Gordon <spam@xxxxxxxxxxxxxxxxxx> wrote:Longfellow wrote:
<snip>Declaring structs, typedefs, function prototypes etc yes, defining objects and function no.What I've done is declare a struct in a header file, which is included in the files for both ends. For example:
Here you are not merely defining the struct, you are also defining an object called calc which is an array of structs.------- /* --- data.h --- */ struct data { char question[80]; char answer[80]; } calc[80]; -------
Not defining, just initializing.
No, it is NOT initialising, it is defining.
> This declaration is made only once in
the header file and not again referenced in the code.
It IS a definition of calc.
> It is assumed
that every file that has that header included should know what it needs to know about that array of structs.
That is true, and that is the reason for providing an extern declaration.
This works fine. My question is this: Is this legal and conforming?No, absolutely not. Any object that you use must be defined EXACTLY once, and because data.h is included in more than one source file any objects it defines are defined multiple times.
Prohibition is against declaring an object more than once, I think.
It is, and by including the above header in more than one translation unit that is *exactly* what you are doing.
> H&S
says on page 79 that one of the two exceptions to this rule is when an object is declared as the same type every time, as in a header file that can be shared with all code files.
You can declare an object (with the same time, or an incomplete declaration that is compatible) as often as you want, but that is NOT what the header does, the header defines the object.
> You are correct that an inclusion of
the header file in each code file is a duplicate declaration,
No, it is a definition, not a declaration.
> but this
exception exists because otherwise the standard C library would be illegal.
No, because the standard headers declares, they do not define.
Note that for functions you don't need the extern keyword to provide declarations (but you can), but with object types you do.
You want something like: /* --- data.h --- */ #define CALC_SIZE 80
struct data { char question[80]; char answer[80]; }; extern struct data calc[CALC_SIZE];
This does not compile.
It compiles perfectly when I try it. Have you put it through a compiler and what error do you get?
Then, in EXACTLY one C source file (not header) which includes data.h you have
struct data calc[CALC_SIZE];
See above.
Incorrect. It compiles perfectly cleanly. I just pasted it in to a C file I had, so I know this to be true.
Yes, but only if you understand the difference between a declaration (which says basically this thing exists somewhere, but I'm not defining it here) and a definition (which says OK, this is the actual object/function right here so allocate the space/put the code here).I get from K&R2, page 82, that functions can indeed be declared in header files. Do I understand this correctly?
Apparently an initialized declaration at the top level is considered a legal defining declaration [H&S pp113-116].
There is no such thing as a "initialised declaration" in C. There are declarations, definitions, and definitions with initialisers. What you provided was a definition, what I provided was a declaration. I don't have H&S so I can't comment on what it says, but either it is wrong or you are misunderstanding it.
For my purposes, having this array of structs globally available via a
header file serves my purpose. Where I don't need it, the header file
will not be included, and I'm going to make the variable names unique
enough so that they will not be duplicated elsewhere.
It should be declared in the header and defined in exactly one C file. Exactly as I stated.
In any case, it compiles cleanly with -Wall -ansi -pedantic.
As does what I provided, however those options do *NOT* generate a diagnostic for multiple definitions.
<OT>
If you want gcc to catch your error, and your version supports it, compile *all* of your code with the -fno-common option and it will then generate an error at link time.
> I've no
idea how this setup will fare as I flesh it all out, but I think I'll drag out lclint and use it continuously. That way, I'll know that I'm staying out of trouble.
Without fixing the *serious* problem I have tried to tell you about it may well work today with your current options, but it will *not* work in all environments.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
.
- Follow-Ups:
- Re: Newbie question
- From: Longfellow
- Re: Newbie question
- References:
- Newbie question
- From: Longfellow
- Re: Newbie question
- From: Flash Gordon
- Re: Newbie question
- From: Longfellow
- Newbie question
- Prev by Date: Re: Measuring time differences
- Next by Date: Re: Measuring time differences
- Previous by thread: Re: Newbie question
- Next by thread: Re: Newbie question
- Index(es):
Relevant Pages
|