Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
nothings opened this issue Jan 6, 2025 Discussed in #1734 · 2 comments
Open

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

nothings opened this issue Jan 6, 2025 Discussed in #1734 · 2 comments

Comments

@nothings
Copy link
Owner

nothings commented Jan 6, 2025

Discussed in #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
Copy link
Owner Author

nothings commented Jan 6, 2025

Originally posted by sroccaserra January 6, 2025

This is not my field of expertise, so if someone has a better view on this please help. What I found could work for GCC (I tested versions 13 and 14) and clang (I tested version 18.1.3).

Either this small change, that should not impact clang users (because the condition was always true and is still true in all cases for clang):

  #if __clang__ || __STDC_VERSION__ <= 201710L

Or this bigger change, tested on the same clang and gcc versions, that is more logical but this one could have an effect on clang users (because now for stdc > 18 clang users will use the new c23 standard typeof):

  #if __STDC_VERSION__ <= 201710L

Also: I tested for g++ and clang++, it works before and after the change for standards c++11 and c++20 (C++ should not use this code anyway, as __STDC_VERSION__ is not defined by C++ preprocessors AFAIK).

@N-R-K
Copy link

N-R-K commented Jan 6, 2025

I personally don't know any compiler which supports typeof() but not __typeof__() (the latter is required due to namespace concerns on pre C23 standards).

So, unless there's an actual reason for it (maybe some C++ reason I'm not aware of??), I think the typeof() branch can just be eliminated entirely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants