using #ifndef

J

John Hanley

I have a program where both my main.c and program.c files use the program.h
file. So I #include "program.h" in both the .c files. The program.h file
has
#ifndef PROGRAM_H
#define PROGRAM_H
....
#endif

Yet when I build my program, the DJGPP compiler tells me there are multiple
definitions of each of my functions.

Any ideas as to what I doing wrong here?

Thanks!

John
 
R

Richard Tobin

Yet when I build my program, the DJGPP compiler tells me there are multiple
definitions of each of my functions.

What's *in* the .h file? It should just be function prototypes, not
complete function definitions.

-- Richard
 
G

Gordon Burditt

I have a program where both my main.c and program.c files use the program.h
file. So I #include "program.h" in both the .c files. The program.h file
has
#ifndef PROGRAM_H
#define PROGRAM_H
...
#endif

Yet when I build my program, the DJGPP compiler tells me there are multiple
definitions of each of my functions.

You put the functions in program.h? That's why. Header files are
generally used for function PROTOTYPES, type definitions, #defines,
and sometimes global variables (with "extern"). Defining a function
in a header file, then including it in more than one file which
will be linked together into the same program, is a problem. As
you observed, you get multiple definitions of functions.

#ifndef only works within the same compilation unit. For example,
it WILL protect you from including "program.h" twice, or from
including "program.h" and "foo.h" which includes "program.h". It
will NOT protect you from "program.h" already being included in
another compilation unit. The compiler is not psychic. It does
not know that you are going to link that compilation unit you already
did and the current one together into the same program. And even if
it was, that's not how #ifndef is supposed to work. You start with
a clean slate at the start of every compilation unit.

Gordon L. Burditt
 
K

Keith Thompson

John Hanley said:
I have a program where both my main.c and program.c files use the program.h
file. So I #include "program.h" in both the .c files. The program.h file
has
#ifndef PROGRAM_H
#define PROGRAM_H
...
#endif

Yet when I build my program, the DJGPP compiler tells me there are multiple
definitions of each of my functions.

Any ideas as to what I doing wrong here?

Yes, you've got a typo on line 137 of program.c.

Seriously, I don't see anything wrong in what you've posted. Try
narrowing your program down to a set of very small files (say 10-20
lines each) that still exhibits the problem. You just might discover
the problem while you're doing this; if not, post again.
 
J

John Hanley

You put the functions in program.h? That's why. Header files are

Actually, I didn't. That kind of confuses me too. I just have the
prototypes, 3 structs, and some extern global variables in the header file.
I define these in my program.c file.
#ifndef only works within the same compilation unit. For example,
it WILL protect you from including "program.h" twice, or from
including "program.h" and "foo.h" which includes "program.h". It
will NOT protect you from "program.h" already being included in
another compilation unit. The compiler is not psychic. It does

I see what you mean. The compiler compiles them each individually
and can't see in to the future to see the .o files will be linked.

I will try a different approach.

Thanks so much!

John
 
E

E. Robert Tisdale

John said:
I have a program where both my main.c and program.c files use the program.h
file. So I #include "program.h" in both the .c files. The program.h file
has
#ifndef PROGRAM_H
#define PROGRAM_H
...
#endif

Yet when I build my program, the DJGPP compiler tells me there are multiple
definitions of each of my functions.

Any ideas as to what I doing wrong here?
> cat program.h
#ifndef GUARD_PROGRAM_H
#define GUARD_PROGRAM_H 1
#include <stdio.h>
void my_function(void); // declaration
#endif//GUARD_PROGRAM_H
> cat program.c
#include "program.h"

void my_function(void) {// definition
fprintf(stdout, "Hello from my_function(void)!\n");
}
> cat main.c
#include <stdlib.h>
#include "program.h"

int main(int argc, char* argv[]) {
my_function();
return EXIT_SUCCESS;
}
 
J

John Hanley

cat program.h
#ifndef GUARD_PROGRAM_H
#define GUARD_PROGRAM_H 1
#include <stdio.h>
void my_function(void); // declaration
#endif//GUARD_PROGRAM_H
cat program.c
#include "program.h"

void my_function(void) {// definition
fprintf(stdout, "Hello from my_function(void)!\n");
}
cat main.c
#include <stdlib.h>
#include "program.h"

int main(int argc, char* argv[]) {
my_function();
return EXIT_SUCCESS;
}
gcc -Wall -std=c99 -pedantic -o main main.c program.c

This exactly what I did. But in Rhide, it tells me "multple definitions of
_function", and at the command line it tells me "undefined reference to
_function". Yet what you have above is just how I set it up. I am unsure
why it is doing that. Any other ideas?

Thanks!

John
 
E

E. Robert Tisdale

John said:
cat program.h
#ifndef GUARD_PROGRAM_H
#define GUARD_PROGRAM_H 1
#include <stdio.h>
void my_function(void); // declaration
#endif//GUARD_PROGRAM_H
cat program.c
#include "program.h"

void my_function(void) {// definition
fprintf(stdout, "Hello from my_function(void)!\n");
}
cat main.c
#include <stdlib.h>
#include "program.h"

int main(int argc, char* argv[]) {
my_function();
return EXIT_SUCCESS;
}
gcc -Wall -std=c99 -pedantic -o main main.c program.c


This exactly what I did.

No it isn't exactly what you did.
But in Rhide, it tells me "multple definitions of _function",
and at the command line it tells me "undefined reference to _function".
Yet what you have above is just how I set it up.
I am unsure why it is doing that.
Any other ideas?

Yes.

Stop being such a twit!

We can't read your mind.
Do as Keith Thompson asked:

"Try narrowing your program down to a set of very small files
(say 10-20 lines each) that still exhibits the problem."

Otherwise, stop bothering us.
 
K

Keith Thompson

John Hanley said:
cat program.h
#ifndef GUARD_PROGRAM_H
#define GUARD_PROGRAM_H 1
#include <stdio.h>
void my_function(void); // declaration
#endif//GUARD_PROGRAM_H
cat program.c
#include "program.h"

void my_function(void) {// definition
fprintf(stdout, "Hello from my_function(void)!\n");
}
cat main.c
#include <stdlib.h>
#include "program.h"

int main(int argc, char* argv[]) {
my_function();
return EXIT_SUCCESS;
}
gcc -Wall -std=c99 -pedantic -o main main.c program.c

This exactly what I did. But in Rhide, it tells me "multple definitions of
_function", and at the command line it tells me "undefined reference to
_function". Yet what you have above is just how I set it up. I am unsure
why it is doing that. Any other ideas?

It's *exactly* what you did?

Try compiling *exactly* the code above and see whether you get the
same error.

If not, as I suggested elsethread, trim your own code down to a short
example that exhibits the problem.
 
J

John Hanley

No it isn't exactly what you did.

Then perhaps you can point out what I did wrong. What I did was declare my
functions, global variables and structs in the .h file. I then #included
them in my .c files as you have done in the example program.
Yes.

Stop being such a twit!

We can't read your mind.

I thought perhaps there was some broader problem I was overlooking. I am
not an experienced
programmer that is why I am asking questions on the newsgroup.
Do as Keith Thompson asked:

"Try narrowing your program down to a set of very small files
(say 10-20 lines each) that still exhibits the problem."

That's fine. I was only replying to your email as you emailed me.
Otherwise, stop bothering us.

No one is forcing you to read my posts and nobody has a gun to your head
telling you
to answer them. If you don't like my questions, you leave ME alone. I
would really
not be a bit offended if you didn't answer my posts.

I was in no way being rude in asking any questions and I appreciated all the
responses I've received as I realize people take time to try and help. You,
however, were rude. You could've been polite about it, but you weren't. I
guess that's your choice...
 
A

Alan Balmer

I was in no way being rude in asking any questions and I appreciated all the
responses I've received as I realize people take time to try and help. You,
however, were rude. You could've been polite about it, but you weren't. I
guess that's your choice...

I had to look up the message ID to see who you were responding to,
since you didn't provide attributions. As it turns out, I couldn't
tell by the threading because I have ERT permanently killfiled. Ignore
him. Most everyone else does.
 
C

CBFalconer

E. Robert Tisdale said:
John Hanley wrote:
.... snipped ...

Stop being such a twit!
.... snip ...

Otherwise, stop bothering us.

Ignore Trollsdale. Its primary purpose is to annoy and give
misinformation. It is a well known troll around here.
 
E

E. Robert Tisdale

John said:
You, however, were rude.
You could've been polite about it, but you weren't.

I didn't mean to be rude.
I was trying to get your attention.
We can't help you unless you do as Keith suggested.
 
K

Keith Thompson

John Hanley said:
Then perhaps you can point out what I did wrong. What I did was declare my
functions, global variables and structs in the .h file. I then #included
them in my .c files as you have done in the example program.

We can't point out what you did wrong without knowing exactly what you
did. Sometimes we can figure out the problem from a brief
description; in this case, we can't.

I suspect the problem is in some detail that you're not telling us,
perhaps because you've assumed it's not significant. That's
understandable; if you were knowledgeable enough to know exactly
what's significant and what isn't, you probably wouldn't have to come
to us for help. Since you are coming to us for help, you really
should give us the information we're asking for. We need a verbatim
cut-and-paste *brief* example of the C code that's causing the
problem. Without that, we can't help you.

[...]
That's fine. I was only replying to your email as you emailed me.
[...]

This is Usenet, not email. The difference is significant; though your
remarks here might be aimed at one person, there are many more
listening in.

As for the problem you're actually asking about, we've now explained
several times what you need to tell us before we can help you. Your
description, quoted above, is not enough. ERT was unnecesarily rude
in my opinion, but he's absolutely right about at least one thing: we
can't read your mind.

You can continue describing what you're doing, and we can continue
telling you we don't know what the problem is. Or you can show us
what you're doing, and we can probably help. The choice is yours (but
one of the choices would be a collosal waste of time and, well, rude.)
 
E

E. Robert Tisdale

Alan said:
John Hanley wrote:

I had to look up the message ID to see who you were responding to,
since you didn't provide attributions. As it turns out,
I couldn't tell by the threading
because I have ERT permanently killfiled.

And I'm grateful for that.
Ignore him. Most everyone else does.

Do you intend to help John Hanley with the problem that he describes?
 
G

Gordon Burditt

cat program.h
#ifndef GUARD_PROGRAM_H
#define GUARD_PROGRAM_H 1
#include <stdio.h>
void my_function(void); // declaration
#endif//GUARD_PROGRAM_H
cat program.c
#include "program.h"

void my_function(void) {// definition
fprintf(stdout, "Hello from my_function(void)!\n");
}
cat main.c
#include <stdlib.h>
#include "program.h"

int main(int argc, char* argv[]) {
my_function();
return EXIT_SUCCESS;
}
gcc -Wall -std=c99 -pedantic -o main main.c program.c

This exactly what I did. But in Rhide, it tells me "multple definitions of
_function",

There are no references to _function in any of the code above.
What, EXACTLY, did the message say?
and at the command line it tells me "undefined reference to
_function".

Again, there are no references to _function in any of the code above.
WHERE did it say this reference was?

Yet what you have above is just how I set it up. I am unsure
why it is doing that. Any other ideas?

Gordon L. Burditt
 
R

Richard Tobin

This exactly what I did. But in Rhide, it tells me "multple definitions of
_function", and at the command line it tells me "undefined reference to
_function".

Are you *absolutely sure* that you only have prototypes in the .h file,
and not definitions? Please post the declaration of "function" from your
..h file.

-- Richard
 
J

John Hanley

Keith Thompson said:
We can't point out what you did wrong without knowing exactly what you
did. Sometimes we can figure out the problem from a brief
description; in this case, we can't.

I suspect the problem is in some detail that you're not telling us,
perhaps because you've assumed it's not significant. That's
understandable; if you were knowledgeable enough to know exactly
what's significant and what isn't, you probably wouldn't have to come
to us for help. Since you are coming to us for help, you really
should give us the information we're asking for. We need a verbatim
cut-and-paste *brief* example of the C code that's causing the
problem. Without that, we can't help you.

Sounds good. I'll post that at the bottom of this reply.
[...]
That's fine. I was only replying to your email as you emailed me.
[...]

This is Usenet, not email. The difference is significant; though your
remarks here might be aimed at one person, there are many more
listening in.

True. I actually was replying to an email. Mr. Tisdale had replied to my
post
over email and cc'd the newsgroup. I did a reply all and replied to both.
I
should've realized it probably shouldn't have gone to the newsgroup as well
(being more
of a personal reply). My apologies for breaking any Usenet etiquette.

You can continue describing what you're doing, and we can continue
telling you we don't know what the problem is. Or you can show us
what you're doing, and we can probably help. The choice is yours (but
one of the choices would be a collosal waste of time and, well, rude.)

Ok, here's my header file r_climat.h

struct data_record
{
...
};

struct data_list
{
struct data_record * head;
struct data_record * tail;
};

struct parameter_list
{
...
}parameters;

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>

/* Global variables */
extern int FORMAT_TYPE;
extern char PARAM_FILE[256];
extern char * IN_FILE;
extern char OUT_FILE[13];

extern void init(struct data_list * l);
extern struct data_record * new_node(long int sid, long int date, int year,
int month, int element, long int val[96], char f[32]);
extern void add_to_tail(struct data_list * l, long int sid, long int date,
int year, int month, int element, long int val[96], char f[32]);
extern int remove_record(struct data_list * ls, struct data_record * rec);
extern void get_filename(char * filename, char * outname);
extern int validate_format(char * f);
extern void print_list(struct data_list * dl);
extern int format_HLY(char * f);
extern int f_eat_spaces(FILE * f);
extern int get_parameters();
extern void empty_list(struct data_list * d);
extern int get_number_of_days(struct data_record * d);
extern int to_CSV_DLY(char * filename, struct data_list * list);
extern int format_DLY(char * f, struct data_list * dl);
extern int format_MLY(char * f);
extern int format_FIF(char * f);

I tried with and without the #ifndef/#define/#endif and as well with and
without the extern on the functions.

I was able to figure out what was wrong with the undefined references to my
global variables. I declared them here, but not in my .c file. So I don't
have that error anymore.

As for my "multiple declaration" problem, here's the snippet of my .c files:

#include "r_climat.h"

#define HLY 0
#define DLY 1
#define MLY 2
#define FIF 3

int FORMAT_TYPE;
char PARAM_FILE[256];
char * IN_FILE;
char OUT_FILE[13];

int main(int argv, char * argc[])
{
main program here
}

and here's r_climat.c

#include "r_climat.h"

#define HLY 0
#define DLY 1
#define MLY 2
#define FIF 3

/* initialize head and tail of data_list to NULL */
void init(struct data_list * l)
{
l->head=NULL;
l->tail=NULL;
}

and the rest of my functions that would take another 800 lines or so.

I only define them in my r_climat.c (I know I don't define any in main.c)
and I only prototype them
in r_climat.h. They all compile just fine with no errors or warnings. It
is during linking that I get this
"multiple definitions" error.

Let me know if there is anything else specific you would like.

Thanks again for all your help. I really do appreciate all of it.

Best regards,
John
 
D

Default User

E. Robert Tisdale said:
And I'm grateful for that.


Do you intend to help John Hanley with the problem that he describes?

What part of killfiled does Trollsdale not understand?

Then again, there are so many things he fails to understand.




Brian Rodenborn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,190
Latest member
ClayE7480

Latest Threads

Top