Calculate g.c.d and l.c.m. in C I wrote a simple program to perform g.c.d and l.c.m., trying to follow the Linux kernel coding style. I know C for about one year, but I'm still a beginner.

Example:

user@compuer:~/projects/tmp$ ./tmp 21 45
G.C.D: 3
l.c.m: 315


Code:

#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;

/*
 * It returns the greatest common divisor between two numbers. The numbers
 * must not be negative (undefined behaviour).
 */
int gcd(int a, int b);

/*
 * It returns the least common multiple. The numbers must not be negative
 * (undefined behaviour).
 */
int lcm(int a, int b);

int main(int argc, char *argv[])
{
        int retval = -1, a, b;

        if (argc != 3) {
                fprintf(stderr, "Error: missing or too many arguments\n");
                goto err_exit;
        }

        a = strtol(argv[1], NULL, 0);
        b = strtol(argv[2], NULL, 0);

        if (a &lt; 0 || b &lt; 0) {
                fprintf(stderr, "Error: numbers must be postive\n");
                goto err_exit;
        }

        if (!a || !b)
                printf("Warning: one or both numbers are 0.\n");

        printf("G.C.D: %d\nl.c.m: %d\n", gcd(a, b), lcm(a, b));

        retval = 0;

        err_exit:
                return retval;
}

int gcd(int a, int b)
{
        int retval = b, r = a;

        if (!a)
                goto exit;

        // Euclidean alrgorithm.
        do {
                a = b;
                b = r;

                r = a % b;
        } while (r);

        retval = b;

        exit:
                return retval;
}

int lcm(int a, int b)
{
        int retval = 0;

        if (a &amp;&amp; b)
                retval = a / gcd(a, b) * b;

        return retval;
}


Makefile:

.PHONY = clean all

PROGNAME = tmp

SHELL = /bin/sh

CC ?= gcc

CFLAGS = -Wall -Wextra

all : main.o
    $(CC) -o $(PROGNAME) $^

clean :
    $(RM) *.o $(PROGNAME)
I don't see the point in using goto here. There's no resource clean up or any other strong reason to resort to it.  It just makes the control flow more complicated.
How to fix it? In the main function, you can just return the value immediately in case of an error. In the gcd function, you can run the while loop with a condition a != 0. It'll make the code easier to folloow and eliminate a corner case a = 0.
The error message fprintf(stderr, "Error: missing or too many arguments\n"); seems too generic to me. It would be more helpful if it were more detailed (too many and missing arguments are clearly different cases).
An LCM of two int's may not fit into int. I'd recommend to document that your program has undefined behavior if the LCM is too large or use a wider integer type.