Skip to content

Compilation fails when using multiple files #2

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions