stb icon indicating copy to clipboard operation
stb copied to clipboard

stb_ds: build error with gcc -std=c99 up to c18

Open nothings opened this issue 11 months ago • 3 comments

Discussed in https://github.com/nothings/stb/discussions/1734

Originally posted by sroccaserra January 5, 2025 Hi, thank you for stb_ds.

I have trouble building with gcc without gnu standards when using hmput() and hmget(), did I miss to set some configuration?

Problem

It works fine with -std=gnu99, up to gnu18, but I get the following error with -std=c99, up to c18:

$ gcc -std=c18 test_stb_ds.c
In file included from test_stb_ds.c:4:
test_stb_ds.c: In function ‘main’:
lib/stb_ds.h:526:49: warning: implicit declaration of function ‘typeof’ [-Wimplicit-function-declaration]
  526 | fine STBDS_ADDRESSOF(typevar, value)     ((typeof(typevar)[1]){value}) // literal array decays to pointer to value

Note: it works without error with -std=c2x with gcc 13, and -std=c23 with gcc 14 (tested with gcc 14.2.0).

Code

I use:

The code of test_stb_ds.c is from the documentation:

#include <stdio.h>

#define STB_DS_IMPLEMENTATION
#include "lib/stb_ds.h"

int main(void) {
    float f;
    struct { float key; char value; } *hash = NULL;
    f=10.5; hmput(hash, f, 'h');
    f=20.4; hmput(hash, f, 'e');
    f=50.3; hmput(hash, f, 'l');
    f=40.6; hmput(hash, f, 'X');
    f=30.9; hmput(hash, f, 'o');

    f=40.6; printf("%c - ", hmget(hash, f));

    f=40.6; hmput(hash, f, 'l');
    for (int i=0; i < hmlen(hash); ++i)
        printf("%c ", hash[i].value);
}

Ideas / what I tried

I noted that I have no issue with clang with c99+ standards, so I tried this diff and it seems to work:

diff --git a/stb_ds.h b/stb_ds.h
index d07bddb..1321ad4 100644
--- a/stb_ds.h
+++ b/stb_ds.h
@@ -520,7 +520,7 @@ extern void * stbds_shmode_func(size_t elemsize, int mode);

 // this macro takes the address of the argument, but on gcc/clang can accept rvalues
 #if defined(STBDS_HAS_LITERAL_ARRAY) && defined(STBDS_HAS_TYPEOF)
-  #if __clang__
+  #if defined(__GNUC__) || defined(__clang__)
   #define STBDS_ADDRESSOF(typevar, value)     ((__typeof__(typevar)[1]){value}) // literal array decays to pointer to value
   #else
   #define STBDS_ADDRESSOF(typevar, value)     ((typeof(typevar)[1]){value}) // literal array decays to pointer to value
```</div>

nothings avatar Jan 06 '25 17:01 nothings