simple question about inter modular acces

F

fir

I was always trouble to memorise it,
lets say jou have two modules (separate c
files compiled to separate .obj files)

one:

void a1()
{
b1();
}

void a2()
{
b2();
}
void a3()
{
b3();
}

void a4()
{
main();
}

two:

void b1()
{
a1();
}

void b2()
{
a2();
}
void b3()
{
a3();
}

void main()
{

}

what in minimal I should add to the files
to make it compiling and linking ? Is it possible
to build?
 
F

fir

W dniu poniedziałek, 23 września 2013 13:07:12 UTC+2 użytkownik Richard Damon napisał:
At the begining of one.c add



extern void b1();

extern void b2();

extern void b3();

extern void main();



and at the beginning of two.c add



extern void a1();

extern void a2();

extern void a3();



This will provide the needed prototypes in each of the files.



Better would be to create a new file two.h and put in it what was added

to one.c and add an

#include "two.h"

to one.c instead, (and similarly to a new one.h included into two.c)





The one remaining problem that I see at first is that main really should

be defined as



int main() {

}



as void main() invokes undefined behavior (but probably does what you want).

alright, that was clear. but to be sure linker
recognizes the antry point to the program only by
the name main ? I do not need provide any way of other info that this two.cmodule is the main
module? Also to be sure, there is no trouble from
calling main from other modules ? (apart from void
int, this is no matter to me here)
 
F

fir

and yet to clarify things i have always trouble to
see clear - what is a way to prevent function f
from be called form outside (lets say that module
one has a function

f()
{

}

i do not wont to ba called from outside?
 
F

fir

and yet some doubt,

At the begining of one.c add

extern void b1();
extern void b2();
extern void b3();
extern void main();

need I words extern here or maybe some
declarations

At the begining of one.c add

void b1();
void b2();
void b3();
void main();

would be cufficient , or maybe nothing at all?
This was always a mess for me and I am never sure..
 
G

Geoff

and yet some doubt,

At the begining of one.c add

extern void b1();
extern void b2();
extern void b3();
extern void main();

need I words extern here or maybe some
declarations

At the begining of one.c add

void b1();
void b2();
void b3();
void main();

would be cufficient , or maybe nothing at all?
This was always a mess for me and I am never sure..

You include header files from the opposite (other) source file.
IOW, one.c includes two.h and two.c includes one.h. If three.c needed
to call functions in one.c and two.c it would include both one.h and
two.h.

Each header file declares the functions of its parent C file.
Complexity increases when one defines constants or variables in
headers, and there are techniques for dealing with that.

Function main is never prototyped in any header. It's prototype is
always int main(), it always returns int by definition. It is never
called by your program. It is established as the first function called
by the runtime startup for your target environment. There can be only
one main() in your program.
 
B

Ben Bacarisse

fir said:
... lets say that module
one has a function

f()
{

}

i do not wont to ba called from outside?

static int f()
{
}

I've added the int return -- implicit int is for very old C sources.
 
B

Ben Bacarisse

Geoff said:
You include header files from the opposite (other) source file.
IOW, one.c includes two.h and two.c includes one.h. If three.c needed
to call functions in one.c and two.c it would include both one.h and
two.h.

That's how you get the linkage right, but it's usually a good idea for a
translation unit also to include "its own" header, e.g. one.c would
include one.h. This give you some checks that the interface that you
are declaring in one.h is indeed implemented in one.c.

<snip>
 
F

Fred K

Geoff <[email protected]> writes: <snip> > You include header files from the opposite (other) source file. > IOW, one.c includes two.h and two.cincludes one.h. If three.c needed > to call functions in one.c and two.c it would include both one.h and > two.h. That's how you get the linkage right, but it's usually a good idea for a translation unit also to include "itsown" header, e.g. one.c would include one.h. This give you some checks that the interface that you are declaring in one.h is indeed implemented in one.c. <snip> -- Ben.

Once the proper prototypes are provided, the OP's program does nothing, since there are no executable statements in main(). If main were to call any of the functions in one.c or two.c, the program would rapidly crash with a stack overflow, due to the infinite recursions.
 
K

Keith Thompson

Geoff said:
Function main is never prototyped in any header. It's prototype is
always int main(), it always returns int by definition. It is never
called by your program. It is established as the first function called
by the runtime startup for your target environment. There can be only
one main() in your program.

The *implementation* doesn't provide a prototype for main. You're free
to do so yourself -- and in fact the usual definition of main:

int main(void) {
/* ... */
}

does provide a prototype.

It's legal to call main recursively, but it's hardly ever a good idea.

There are two correct and portable ways to define main:
int main(void) { /* ... */ }
and
int main(int argc, char *argv[]) { /* ... */ }
or equivalent.

The form without parentheses:
int main() { /* ... */ }
is at best questionable. As a non-prototype definition it uses an
*obsolescent* feature, and there's no advantage in omitting the void
keyword (which explicitly specifies that it takes no arguments).
The distinction is particularly significant if you're calling main
recursively, since the "int main(void)" form lets the compiler
diagnose calls with the wrong number of arguments.

An implementation may support other implementation-defined forms
of main. For example, I recently learned (to my dismay) that
Microsoft documents the "void main(void)" form. But there is no
good reason to use such forms; they make your program non-portable
with no real benefit. I've found that "void main(void)" is useful
mostly as an indicator that you're reading a book that was written
by someone who doesn't know C very well.

The above applies to "hosted implementations". For "freestanding
implementations" (mostly embedded systems), the program's entry
point is entirely implementation-defined; it might not even be called
"main".
 
B

Ben Bacarisse

fir said:
and yet some doubt,

At the begining of one.c add

extern void b1();
extern void b2();
extern void b3();
extern void main();

need I words extern here or maybe some
declarations

At the begining of one.c add

void b1();
void b2();
void b3();
void main();

These mean the same as the above.

No one has yet mentioned that the form

T function_name();

is not ideal. It does not give the compiler any information about the
function's arguments (technically, it is not a prototype -- simply a
declaration). It's better to write

T function_name(void)

in both the declaration and the defintion (if, it's true, of course).

<snip>
 
B

Ben Bacarisse

Something went wrong with the quoting!
Once the proper prototypes are provided, the OP's program does
nothing, since there are no executable statements in main(). If main
were to call any of the functions in one.c or two.c, the program would
rapidly crash with a stack overflow, due to the infinite recursions.

OK, I made main call b1(), compiled the thing with gcc and ran it. How
long will I need to wait on my Core i7 laptop? It's been running for
four minutes with no sign of a crash yet. I don't have *that* much
memory!
 
B

Ben Bacarisse

I believe you actually can call main from your hosted program in C
(not in C++), although I can't imagine a case where that would
actually be a good idea.

int main(int argc, char *argv[])
{
return argc > 1 ? !process(argv[1]) || main(argc-1, argv+1) : 0;
}

? <insert your smiley of choice here>
 
F

Fred K

Fred K <[email protected]> writes: > On Monday, September 23,2013 6:41:43 AM UTC-7, Ben Bacarisse wrote: >> Geoff <[email protected]> writes: <snip> > You include header >> files from the opposite (other) source file. > IOW, one.c includes >> two.h and two.c includes one.h. If three.c needed > to call functions >> in one.c and two.c it would include bothone.h and > two.h. That's >> how you get the linkage right, but it's usually a good idea for a >> translation unit also to include "its own" header, e.g. one.c would >> include one.h. This give you some checks that the interface that you >> are declaring in one.h is indeed implemented in one.c. <snip> -- Ben. Something went wrong with the quoting! > Once the proper prototypes are provided, the OP's program does > nothing, since there are no executable statements in main(). If main > were to call any of the functions inone.c or two.c, the program would > rapidly crash with a stack overflow, due to the infinite recursions. OK, I made main call b1(), compiled the thing with gcc and ran it. How long will I need to wait on my Core i7 laptop? It's been running for four minutes with no sign of a crash yet. I don't have*that* much memory! -- Ben.

b1 calls a1, which calls b1, which calls a1,...
Since all of them are empty, possibly your compiler optimizaztion has madethem noops. Try adding a print statement in them and see what happens.
 
J

James Kuyper

On 09/23/2013 09:21 AM, Geoff wrote:
....
Function main is never prototyped in any header. ...

It can be be prototyped, and in the unlikely event that your code
actually refers to main() in two or more different modules, it should be
prototyped in a header that is #included into each of those modules, to
ensure that the same prototype is used in all of them.
... It's prototype is ...
always int main(), ...

Standing alone as a declaration, that's not a prototype without the word
'void' in the argument list (there's been some debate as to whether it
counts a prototype when used in a declaration that also defines the
function - but that's a rather esoteric issue).

Even with the void, it isn't the only possible prototype. Any conforming
hosted implementation of C must also accept:

int main(int argc, char *argv[]);

as well as any equivalent declaration (such as one that renames the
parameters, or leaves them out entirely, or which uses char** rather
than char*[].

And of course, implementation-specific code can use any
implementation-defined alternative for main.
... it always returns int by definition. It is never
called by your program. ...

It can be called by your program, though the circumstances where it
makes sense to do so are rare. The most common reason for doing
something like that is to rearrange the argument list.
 
F

fir

W dniu poniedziałek, 23 września 2013 18:13:16 UTC+2 użytkownik Ben Bacarisse napisał:
Something went wrong with the quoting!









OK, I made main call b1(), compiled the thing with gcc and ran it. How

long will I need to wait on my Core i7 laptop? It's been running for

four minutes with no sign of a crash yet. I don't have *that* much

memory!
did you compile the both modules separatelly then linked together - or you throw a's and b's into the main module?
 
J

James Kuyper

rsions. OK, I made main call b1(), compiled the thing with gcc and ran it. How long will I need to wait on my Core i7 laptop? It's been running for four minutes with no sign of a crash yet. I don't have *that* much memory! -- Ben.
b1 calls a1, which calls b1, which calls a1,...
Since all of them are empty, possibly your compiler optimizaztion has made them noops. Try adding a print statement in them and see what happens.

If they were noops, then why did his program continue executing for four
minutes?
 
K

Keith Thompson

Robert Wessel said:
I believe you actually can call main from your hosted program in C
(not in C++), although I can't imagine a case where that would
actually be a good idea. And in a freestanding program, main isn't
special at all.

In a freestanding program, main *may or may not* be special. The
program entry point is implementation-defined; it may well be called
"main".

N1570 5.1.2.1:

In a freestanding environment (in which C program execution
may take place without any benefit of an operating system),
the name and type of the function called at program startup are
implementation-defined. Any library facilities available to a
freestanding program, other than the minimal set required by
clause 4, are implementation-defined.

The effect of program termination in a freestanding environment
is implementation-defined.
 
B

Ben Bacarisse

Something went wrong with the quoting again.
b1 calls a1, which calls b1, which calls a1,...

Yes, I saw that.
Since all of them are empty, possibly your compiler optimizaztion has
made them noops. Try adding a print statement in them and see what
happens.

I get the output from b1 and a1 repeated over and over. It's been going
on for several minutes now. When will my stack become exhausted?

(If this exchange goes on much longer my original point will get lost
entirely!)
 
R

Rosario1903

If they were noops, then why did his program continue executing for four
minutes?

for me
it is possible compiler 'optimize' recursion with a loop
so a never ending loop

i say that the compiler not have to optimize what the coder or the
programmer wrote
i'm not agree compiler optimizations...
this is because i think programmer has to see result
of his own routines
the result of each instruction he/her wrote and
not something different
 
B

Ben Bacarisse

Please consider using a real newsreader to post to comp.lang.c. Google
groups messes up the quoting.

fir said:
W dniu poniedziałek, 23 września 2013 18:13:16 UTC+2 użytkownik Ben Bacarisse napisał:
did you compile the both modules separatelly then linked together - or
you throw a's and b's into the main module?

I compiled them separately.
 

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,995
Messages
2,570,225
Members
46,815
Latest member
treekmostly22

Latest Threads

Top