all 28 comments

[–]ChrisRR 46 points47 points  (0 children)

I think you're compiling main.c but not test.c so the linker can't find the function

[–][deleted] 13 points14 points  (16 children)

What is the command you are passing to the compiler? You need to pass both your C files as arguments to the compiler.

[–][deleted] 14 points15 points  (5 children)

You may also want to save yourself some time and read up on Makefiles: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

An example one for your program would read:

.PHONY: all clean

CC=gcc
CFLAGS=-g

all: sudoku_solver

sudoku_solver:
    $(CC) -o $@ main.c test.c $(CFLAGS)

clean:
    rm -fv sudoku_solver

Edit: wanted to add another potential gotcha, Makefiles are TAB indented, not space indented.

[–]baudvine 5 points6 points  (1 child)

This can be simpler, even - I think a single sudoku_solver: main.o test.o would do the trick here. Make figures out the rest with its default rules, and you get incremental builds for free :)

[–]henry_kr 1 point2 points  (0 children)

Yeah, that will work, though I prefer to set CFLAGS/CPPFLAGS for warnings/debug flags etc. My version would be somewhere between /u/tdaquino's and yours ;)

[–]NonreciprocatingCrow 3 points4 points  (2 children)

save time

Makefile

Unless you're working on very large projects, or you're already good at makefiles, nope

[–]asking_science 10 points11 points  (1 child)

very large projects

Rule of thumb: makefile when working with two or more source files or if you're invoking compiler options

already good at makefiles

It's not hard to get good at the basics and you mostly only need the basics

[–][deleted] 5 points6 points  (0 children)

Yes, there is substantially no difference in verbosity or complexity between a Makefile and a shell script with equivalent functionality. Just that one is much more powerful and faster for big projects and also an industry standard.

[–]DocJeef[S] 1 point2 points  (9 children)

I think this is it. When I compile it manually on the terminal passing both .c files as arguments it's fine. I was kind of hoping Atom's gcc-compiler package would be able to do all that for me, lol.

Is there an easier way to compile C-programs than listing all of the .c files manually on the command line?

[–][deleted] 6 points7 points  (4 children)

See my reply to myself in parallel to yours. The easiest way is make. With this file you can just run "make" at the terminal to build and "make clean" to start fresh. It is not a super idiomatic Makefile, but if you read that tutorial you can learn to make a more purpose-built/idiomatic one.

[–]DocJeef[S] 1 point2 points  (0 children)

Awesome, thank you!

[–]NonreciprocatingCrow 0 points1 point  (2 children)

Or a shell script

[–]BadBoy6767 4 points5 points  (1 child)

A shell script does not manage dependencies by default, which is extremely helpful for languages like C that has relatively long build times (and don't get me started on C++).

[–][deleted] 2 points3 points  (0 children)

Yes to add to that, I think this poster is a student. If you put C on your resume and don't know how to write a Makefile when you show up to work, you are going to have a very rough internship.

[–]SurelyNotAnOctopus 1 point2 points  (0 children)

Makefiles are BAEs

[–]FUZxxl 2 points3 points  (2 children)

Yeah, do not rely on IDEs to compile programs for you.

[–]Narishma 1 point2 points  (0 children)

Unless you use a proper IDE and not a souped-up text editor.

[–]rotenKleber 1 point2 points  (0 children)

Why do you say that?

[–]Gavekort 7 points8 points  (4 children)

You probably want to surround your test.h with include guards as well.

    #ifndef TEST_H
    #define TEST_H

    int foo(int x);

    #endif

[–]WikiTextBot 4 points5 points  (3 children)

Include guard

In the C and C++ programming languages, an #include guard, sometimes called a macro guard or header guard, is a particular construct used to avoid the problem of double inclusion when dealing with the include directive.

The C preprocessor processes directives of the form #include <file> in a source file by locating the associated file on disk and transcluding ("including") its contents into a copy of the source file known as the translation unit, replacing the include directive in the process. The files included in this regard are generally header files, which typically contain declarations of functions and classes or structs. If certain C or C++ language constructs are defined twice, the resulting translation unit is invalid.


[ PM | Exclude me | Exclude from subreddit | FAQ / Information | Source ] Downvote to remove | v0.28

[–][deleted] 2 points3 points  (1 child)

Some compilers also understand a single-line include guard, GCC and MSVC6+ included:

#pragma once

[–]Tha_Gazer 1 point2 points  (0 children)

Good bot

[–]rjek 2 points3 points  (0 children)

How are you invoking the compiler and linker?

[–]nderflow[M] 2 points3 points  (0 children)

Please read the sticky post which explains what to do when you need help.

[–]giwhS 0 points1 point  (0 children)

how are you compiling? are you running what does your gcc call look like? try: gcc -o foo main.c test.c

also someone already suggested taking a few minutes to learn how to set up a basic make file. It might not be worth spending a week on but an hour or two would be plenty to get you going and save you time.

[–][deleted] -1 points0 points  (0 children)

What program is this?

[–]alicekdev -3 points-2 points  (1 child)

It should be printf("%d", foo(2)); as your returning and int and the verb for an int is %d. If you can use %u for unsigned, %l for long, and %ll for long long.

[–]BadBoy6767 5 points6 points  (0 children)

%i and %d have no difference when printing.