Skip to content

Compilation fails when using multiple files #2

@gstaaij

Description

@gstaaij

When using multiple C files, or when using the library as a separate translation unit ht.o, linking fails because the ht__* functions are static.

Example (multiple C files)

foo.h

#include "ht.h"

typedef Ht(const char*, int) Ht_Str_Int;

void foo(Ht_Str_Int* ht);

foo.c

#include "foo.h"

void foo(Ht_Str_Int* ht) {
    *ht_put(ht, "foo") = 69;
    *ht_put(ht, "bar") = 420;
    *ht_put(ht, "baz") = 1337;
}

main.c

#include <stdio.h>
#include "foo.h"

#define HT_IMPLEMENTATION
#include "ht.h"

int main() {
    Ht_Str_Int ht = {.hasheq = ht_cstr_hasheq};
    foo(&ht);
    *ht_put(&ht, "hello") = 37;
    ht_foreach(value, &ht) {
        printf("%s => %d\n", ht_key(&ht, value), *value);
    }
    ht_free(&ht);
    return 0;
}

When building the above files, I get:

$ cc -ggdb -o main main.c foo.c
In file included from foo.h:1,
                 from foo.c:1:
ht.h:512:14: warning: ‘ht__put’ used but never defined
  512 | static void *ht__put(Ht__Abstract *ht, void *key, Ht__Layout l);
      |              ^~~~~~~
/usr/bin/ld: /tmp/cc7sFE07.o: in function `foo':
/tmp/ht-test/foo.c:4:(.text+0xb4): undefined reference to `ht__put'
/usr/bin/ld: /tmp/ht-test/foo.c:5:(.text+0x142): undefined reference to `ht__put'
/usr/bin/ld: /tmp/ht-test/foo.c:6:(.text+0x1c4): undefined reference to `ht__put'
collect2: error: ld returned 1 exit status

Example (with ht.o)

Building the library beforehand using cc -DHT_IMPLEMENTATION -x c -c ht.h -o ht.o does not work at all.

main.c

(this is the example from the readme)

#include <stdio.h>
#include "ht.h"

int main(void) {
    Ht(const char *, int) ht = {
        .hasheq = ht_cstr_hasheq,
    };
    *ht_put(&ht, "foo") = 69;
    *ht_put(&ht, "bar") = 420;
    *ht_put(&ht, "baz") = 1337;
    ht_foreach(value, &ht) {
        printf("%s => %d\n", ht_key(&ht, value), *value);
    }
    ht_free(&ht);
    return 0;
}
$ cc -ggdb -o main main.c ht.o
In file included from main.c:2:
ht.h:512:14: warning: ‘ht__put’ used but never defined
  512 | static void *ht__put(Ht__Abstract *ht, void *key, Ht__Layout l);
      |              ^~~~~~~
ht.h:517:14: warning: ‘ht__key’ used but never defined
  517 | static void *ht__key(void *slot, Ht__Layout l);
      |              ^~~~~~~
ht.h:518:13: warning: ‘ht__next’ used but never defined
  518 | static bool ht__next(Ht__Abstract *ht, void **slot, Ht__Layout l);
      |             ^~~~~~~~
ht.h:520:13: warning: ‘ht__free’ used but never defined
  520 | static void ht__free(Ht__Abstract *ht);
      |             ^~~~~~~~
/usr/bin/ld: /tmp/ccJ394r5.o: in function `main':
/tmp/ht-test/separate/main.c:8:(.text+0xc7): undefined reference to `ht__put'
/usr/bin/ld: /tmp/ht-test/separate/main.c:9:(.text+0x164): undefined reference to `ht__put'
/usr/bin/ld: /tmp/ht-test/separate/main.c:10:(.text+0x201): undefined reference to `ht__put'
/usr/bin/ld: /tmp/ht-test/separate/main.c:12:(.text+0x29a): undefined reference to `ht__key'
/usr/bin/ld: /tmp/ht-test/separate/main.c:11:(.text+0x346): undefined reference to `ht__next'
/usr/bin/ld: /tmp/ht-test/separate/main.c:14:(.text+0x35e): undefined reference to `ht__free'
collect2: error: ld returned 1 exit status

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions