extern pointers.

P

pereges

/* a.h */

#include <stdio.h>
#include <stdlib.h>

extern int *a;

/*a.c */

#include "a.h"
#include "b.h"

int *a = NULL;

int main(void)
{
call(a);
print(a);
return 0;
}

void call(int *);
void print(int *);


/* b.h */

void call(int *);
void print(int *);


/* b.c */

#include "a.h"
#include "b.h"

int n = 5;

void call(a)
{
a = calloc(sizeof(int), n);

a[0] = 0;
a[1] = 2;
a[2] = 7;
a[3] = 9;
a[4] = 90;

}

void print(a)
{
int i;
for(i=0; i<n; i++)
printf("%d\n",a);
}


I'm getting an error saying "Conflicting argument declarations for
function 'call'. " in b.c

Why am I getting an error if a was declared as extern and defined in
a.c ?
 
P

Philip Potter

pereges said:
/* a.h */

#include <stdio.h>
#include <stdlib.h>

Why are these lines here? I'm not saying you shouldn't have them, I just
can't see why you do.
extern int *a;

This makes a visible to any file which #includes a.h.
/*a.c */

#include "a.h"
#include "b.h"

int *a = NULL;

int main(void)
{
call(a);
print(a);
return 0;
}

void call(int *);
void print(int *);

These declarations achieve nothing. They are after main, so code in main
can't see them. main can only see call() and print() because of the
declarations in b.h.
/* b.h */

void call(int *);
void print(int *);

These make call() and print() visible to anything which #includes b.h.
/* b.c */

#include "a.h"
#include "b.h"

int n = 5;

void call(a)

The a in the parenthesis here has nothing to do with the a declared in
a.h and defined in a.c. This just says "call is a function taking one
argument of unspecified type and returning void." But because you
declared call() in b.h as void call(int *), the compiler is rightly
complaining that you've changed your mind about call's type.
{
a = calloc(sizeof(int), n);

a[0] = 0;
a[1] = 2;
a[2] = 7;
a[3] = 9;
a[4] = 90;

}

void print(a)
Ditto.
{
int i;
for(i=0; i<n; i++)
printf("%d\n",a);
}


I'm getting an error saying "Conflicting argument declarations for
function 'call'. " in b.c

Why am I getting an error if a was declared as extern and defined in
a.c ?


The whole point of function parameters is that you can pass whatever you
like into them. b.c doesn't need to know about functions which would
like to use call() and print(), or variables which might be passed in.
So get rid of #include "a.h" from b.c, it's unnecessary.

When you say void call(int *) in b.h, you're saying that you can pass an
int * into call(). That way, main() knows that a is the correct type to
be passed into call(). If another function in another module (say,
myfunc() in myfile.c) also wanted to use call() and print(), all it
would have to do is #include "b.h". b.c wouldn't have to know that
myfile.c even existed.

With this in mind, it's probably a bad idea to name the function
parameters "a".

To solve your problem, start by giving call its correct type in b.c:
void call(int *arg)
and rename every a after that to arg.

Philip
 
P

pereges

pereges wrote:
The a in the parenthesis here has nothing to do with the a declared in
a.h and defined in a.c. This just says "call is a function taking one
argument of unspecified type and returning void." But because you
declared call() in b.h as void call(int *), the compiler is rightly
complaining that you've changed your mind about call's type.

How so ? Isn't the whole purpose of including a.h in b.c is making a
visible to b.c ? Why can't it see a ?
The whole point of function parameters is that you can pass whatever you
like into them. b.c doesn't need to know about functions which would
like to use call() and print(), or variables which might be passed in.
So get rid of #include "a.h" from b.c, it's unnecessary.

When you say void call(int *) in b.h, you're saying that you can pass an
int * into call(). That way, main() knows that a is the correct type to
be passed into call(). If another function in another module (say,
myfunc() in myfile.c) also wanted to use call() and print(), all it
would have to do is #include "b.h". b.c wouldn't have to know that
myfile.c even existed.

With this in mind, it's probably a bad idea to name the function
parameters "a".

To solve your problem, start by giving call its correct type in b.c:
void call(int *arg)
and rename every a after that to arg.

What if I don't pass any pointer and directly use a inside the code ?
I tried it and i got proper out put.
 
P

pereges

I think using extern keyword can be very helpful while writing a
modular program for a binary tree or link list without having to deal
with double pointers or returning pointers. Just declare the root node
as extern.

also, one question i have is: why must we always define an extern
variable outside the scope of a function ? Is it wrong to define it
within a function ?
 
B

Ben Bacarisse

pereges said:
I think using extern keyword can be very helpful while writing a
modular program for a binary tree or link list without having to deal
with double pointers or returning pointers. Just declare the root node
as extern.

You've hit one of the problems: "the" root node. It gets very messy
building three trees if they all use a "global" for the root. Please,
don't go down that road. The sooner you learn the other ways (even
though they will seem overly complex for you current needs) the better.
also, one question i have is: why must we always define an extern
variable outside the scope of a function ? Is it wrong to define it
within a function ?

Words matter here. You can declare it there but you can't define it
there. Many people object to the style (local declarations of
external objects) but doing so does accord with previous advice you
were given about minimising the scope your names. I am in two minds.
I've seen (and used) both styles and I can't decide between them!
 
D

David Thompson

pereges wrote:

The a in the parenthesis here has nothing to do with the a declared in
a.h and defined in a.c.

Right.
This just says "call is a function taking one
argument of unspecified type and returning void."

Not unspecified; this is oldstyle/K&R1 format using implicit int (no
longer allowed in C99).
But because you
declared call() in b.h as void call(int *), the compiler is rightly
complaining that you've changed your mind about call's type.
Right.

<snip rest>
- formerly david.thompson1 || achar(64) || worldnet.att.net
 

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,774
Messages
2,569,599
Members
45,177
Latest member
OrderGlucea
Top