Pieter
Pieter

Reputation: 32765

Clear tutorial explaining modular programming in C?

I'm just getting started with modular programming in C. I think I'm doing something wrong with the inclusions, because I'm getting a lot of conflicting types for 'functionName' and previous declaration of 'functionName' was here errors. I did put inclusion guards in place.

Do you know a clear tutorial that explains modular programming in C, especially how the inclusions work?


Update: I have tried to isolate my issue. Here's some code, as requested.

Update 2: updated code is below. The errors have been updated, too.

/*
 * main.c
 */
#include <stdio.h>
#include "aStruct.h"

int main() {
    aStruct asTest = createStruct();

    return 0;
}

/*
 * aStruct.h
 */
#ifndef ASTRUCT_H_
#define ASTRUCT_H_

struct aStruct {
    int value1;
    int value2;
    struct smallerStruct ssTest;
};
typedef struct aStruct aStruct;

aStruct createStruct();

#endif /* ASTRUCT_H_ */

/*
 * smallerStruct.h
 */
#ifndef SMALLERSTRUCT_H_
#define SMALLERSTRUCT_H_

struct smallerStruct {
    int value3;
};
typedef struct smallerStruct smallerStruct;

smallerStruct createSmallerStruct();

#endif /* SMALLERSTRUCT_H_ */

/*
 * aStruct.c
 */
#include <stdio.h>
#include "smallerStruct.h"
#include "aStruct.h"

aStruct createStruct() {
    aStruct asOutput;

    printf("This makes sure that this code depends on stdio.h, just to make sure I know where the inclusion directive should go (main.c or aStruct.c).\n");

    asOutput.value1 = 5;
    asOutput.value2 = 5;
    asOutput.ssTest = createSmallerStruct();

    return asOutput;
}

/*
 * smallerStruct.c
 */
#include <stdio.h>
#include "smallerStruct.h"

smallerStruct createSmallerStruct() {
    smallerStruct ssOutput;
    ssOutput.value3 = 41;
    return ssOutput;
}

This generates the following error messages:

At aStruct.h:10

  • field 'ssTest' has incomplete type

At main.c:8

  • unused variable `asTest' (this one makes sense)

Upvotes: 2

Views: 4147

Answers (3)

mouviciel
mouviciel

Reputation: 67829

The base of inclusion is to make sure that your headers are included only once. This is usually performed with a sequence like this one:

/* header.h */
#ifndef header_h_
#define header_h_

/* Your code here ... */

#endif /* header_h_ */

The second point is to take care of possible name conflicts by handling manually pseudo namespaces with prefixes.

Then put in your headers only function declarations of public API. This may imply to add typedefs and enums. Avoid as much as possible to include constant and variable declarations: prefer accessor functions.

Another rule is to never include .c files, only .h. This is the very point of modularity: a given module dependant of another module needs only to know its interface, not its implementation.

A for your specific problem, aStruct.h uses struct smallerStruct but knows nothing about it, in particular its size for being able to allocate an aStruct variable. aStruct.h needs to include smallerStruct.h. Including smallerStruct.h before aStruct.h in main.c doesn't solve the issue when compiling aStruct.c.

Upvotes: 3

Jason L.
Jason L.

Reputation: 36

The multiple definition problem is most likely coming from the way you're including the code. You are using #include "aStruct.c" as opposed to #include "aStruct.h". I suspect you are also compiling the .c files into your project in addition to the #include. This causes the compiler to become confused due to the multiple definitions of the same function.

If you change the #include to #include "aStruct.h" and make sure the three source files are compiled and linked together, the error should go away.

Upvotes: 2

qrdl
qrdl

Reputation: 34968

Such errors mean that function declaration (return type or parameter count/types) differs from other function declarations or function definition.

previous declaration message points you to the conflicting declaration.

Upvotes: 0

Related Questions