1

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
#################################################################
Community
  • 1
  • 1
vaindil
  • 7,536
  • 21
  • 68
  • 127

3 Answers3

2

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

David Duncan
  • 1,225
  • 8
  • 14
  • My apologies: I posted as a comment to goldilocks's answer, but I am not allowed to declare anything globally, only within functions, and I believe this method would violate that rule. I'm apparently supposed to edit the Makefile to make the two see each other, nothing in the files can point to each other. – vaindil Sep 15 '13 at 18:11
  • `extern` is implicit with function declarations. You don't have to put it there. – CodeClown42 Sep 15 '13 at 18:34
  • @goldilocks: Thanks, good point; I edited to just say function declarations. – David Duncan Sep 15 '13 at 18:42
0

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.

CodeClown42
  • 11,194
  • 1
  • 32
  • 67
  • When I looked it up initially, that is exactly what I found -- there's no way around the .h file. I have been told, however, that I will not get credit if a .h file is included, as that's the incorrect way to do it. I just found [this question](http://stackoverflow.com/questions/8728728/compiling-multiple-c-files-in-a-program), however. Is that the same thing as calling a header? Assignment says that functions cannot be declared in the global scope though, so this method apparently isn't allowed either. Basically, this assignment is ridiculous. – vaindil Sep 15 '13 at 18:01
  • @StevenH, it does sound ridiculous. Is it available on-line somewhere so we can see it? – Adam Burry Sep 15 '13 at 18:03
  • @AdamBurry [Here it is](https://www.dropbox.com/s/aee9pq2i2bh81ne/a2.pdf) (quick Dropbox upload). [This](http://pastebin.com/qvU03esA) is the referenced Makefile from a1. – vaindil Sep 15 '13 at 18:06
  • 1
    @StevenH : You can put the prototypes of functions from module.c into main.c and skip the header, yes. – CodeClown42 Sep 15 '13 at 18:11
  • @goldilocks That would be considered declaring the function globally though, wouldn't it? I cannot do that according to the assignment. – vaindil Sep 15 '13 at 18:17
  • @StevenH *"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."* You can declare a prototype inside a function, it does not have to be global. You do not have to use `extern` explicitly, btw. It's there implicitly by default (for function prototypes). – CodeClown42 Sep 15 '13 at 18:30
  • I added an example of this at the end in case there is any confusion. – CodeClown42 Sep 15 '13 at 18:53
0

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!

Adam Burry
  • 1,904
  • 13
  • 20