Reputation: 7846
I recently asked this question about compiling multiple files in C so that a file main.c
can reference a file modules.c
. The answer ended up being to make the modules file into a header file and having main import it.
I have now been told that this is an incorrect way to do it, as C supports modular compilation. My Makefile is below, and this is supposedly supposed to be correct, but I receive errors for each function call in main.c
-- warning: implicit declaration of function X
.
What do I need to do to compile this correctly, with two .c
files rather than a .c
and .h
file? The main.c
file has a main()
function that needs to be able to call the functions in modules.c
.
Makefile:
#################################################################
# Variables
# -- allows C-source and assembly-source files mix. Again, the
# -- indented lines start with a TAB(^I) and not spaces..
#################################################################
CFLAGS = -g -Wall -Werror
LDFLAGS =
CC = gcc
LD = gcc
TARG = driver
OBJS = modules.o main.o
#################################################################
# Rules for make
#################################################################
$(TARG): $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) -o $(TARG)
%.o: %.c %.s
$(CC) $(CFLAGS) -c $<
clean:
rm -f *.o *˜ $(TARG)
print:
pr -l60 Makefile modules.c main.c | lpr
#################################################################
# Dependencies -- none in this program
#################################################################
Upvotes: 1
Views: 11655
Reputation: 11536
You can do this a few ways, but regardless of which you choose, if main.c calls functions from module.c, then main.c must #include
a header which declares prototypes for those functions.
The first and simplest way is to just do this:
gcc -Wall -g main.c module.c -o myprogram
The second and more ornate way is to build module.c first as an object file. The primary purpose of this method is to save time when developing/debugging/compiling large programs with multiple parts -- rather than having to recompile the whole thing, you can just recompile the parts the have changed. It also allows you to easily mix and match parts. This is easiest to do with a makefile:
myprogram: main.c module.o
CC $(CFLAGS) main.c module.o -o myprogram
module.o:
CC $(CFLAGS) -c module.c
Notice the "myprogram" target from the makefile works with (prereq) module.o whereas the plain gcc method works with module.c.
If, as per your assignment, you can't use a header or global declarations, you can declare prototypes inside functions:
void somefunc () {
char *whatever (int x); // prototype
printf("%s\n", whatever(12));
}
Is fine, and presuming whatever()
is defined somewhere, will work when you compile and run it.
Upvotes: 0
Reputation: 1215
You've already gotten feedback about using GCC and Makefiles, and it's been noted that the typical way to accomplish your task would be two .c files and one .h file. But it's not required to have a .h file if you use function declarations (which is arguably simpler, just less maintainable and useful), as demonstrated by the following below example.
main.c:
void moduleFunc1(int); // extern keyword required for vars, not for functions
int main()
{
moduleFunc1(100);
return 0;
}
module.c:
#include <stdio.h>
void moduleFunc1(int value)
{
printf("%d\n", value);
}
To compile:
gcc main.c module.c
Edit: After having looked at the assignment you linked, my best guess is actually still that function declarations are what you are looking for. To quote from the assignment, under "Others", #7:
A function should be declared in the module/function where
it is called and not in global scope. Say A calls B and C does
not call it then B should be declared in A only.
In my example, the function declaration is in the module where it's called and seems to meet the A-B-C example. (The confusing part is the global scope comment, but I wouldn't say that the function declaration's scope is global. Observe that if you move the declaration below main(), for example, it messes things up. I haven't found something strictly authoritative for this point, though.)
Upvotes: 2
Reputation: 1902
Having read the assignment, could your instructor possibly mean the following?
main.c:
#include <stdio.h>
int main() {
int plus(int a, int b); /* declaration */
printf("%d ", plus(4, 5));
exit(0);
}
module.c:
int plus(int a, int b) {
return a + b;
}
gcc -Wall -Wextra main.c module.c
The thing is though, that plus() is available in the global namespace. So I am a bit lost.
Just an aside:
3. int next = 234;
printf("%6d ", next);
will print value of next, right justified in 6 columns
6. Use separate statements for declaration and initialization
of a variable as:
int xval;
xval = 100;
Do as I say, not as I do!
Upvotes: 0