简体   繁体   中英

Compiling multiple files in C

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
#################################################################

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 ABC 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.)

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.

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM