Error building project with make command, use of undeclared identifier '__compar_fn_t' - c

I'm trying to build RedisBloom and after running the make command I get the following error.
clang -dynamic -fcommon -g -ggdb -Wall -Wno-unused-function -g -ggdb -O2 -fPIC -std=gnu99 -D_GNU_SOURCE -I/Users/john/workspace/RedisBloom/contrib -I/Users/john/workspace/RedisBloom -I/Users/john/workspace/RedisBloom/src -I/Users/john/workspace/RedisBloom/deps/t-digest-c/src -c -o /Users/john/workspace/RedisBloom/src/topk.o /Users/john/workspace/RedisBloom/src/topk.c
/Users/john/workspace/RedisBloom/src/topk.c:223:50: error: use of undeclared identifier '__compar_fn_t'
qsort(heapList, topk->k, sizeof(*heapList), (__compar_fn_t)cmpHeapBucket);
^
1 error generated.
make: *** [/Users/dsesma/eclipse-workspace/RedisBloom/src/topk.o] Error 1
I'm using macOS Big Sur

The RedisBloom project uses an implementation detail (__compar_fn_t) to cast the function signature of cmpHeapBucket from a shortcut-signature to the proper signature. Relying on such implementation details is bad and tends to not be very portable.
I recommend that you download the newest version of RedisBloom. I made a patch to it that has now been merged to master which does the following:
Fix in src/topk.c:
// make the compare function have the correct signature:
int cmpHeapBucket(const void *tmp1, const void *tmp2) {
const HeapBucket *res1 = tmp1;
const HeapBucket *res2 = tmp2;
return res1->count < res2->count ? 1 : res1->count > res2->count ? -1 : 0;
}
HeapBucket *TopK_List(TopK *topk) {
HeapBucket *heapList = TOPK_CALLOC(topk->k, (sizeof(*heapList)));
memcpy(heapList, topk->heap, topk->k * sizeof(HeapBucket));
// now, no cast is needed below:
qsort(heapList, topk->k, sizeof(*heapList), cmpHeapBucket);
return heapList;
}

Related

Pedantic warning in use of G_DEFINE_BOXED_TYPE

I recently came across the following warning in one of my applications that uses the GLib:
warning: ISO C prohibits argument conversion to union type [-Wpedantic]
note: in definition of macro '_G_DEFINE_BOXED_TYPE_BEGIN'
2147 | _g_register_boxed (g_intern_static_string (#TypeName), copy_func, free_func);
I usually compile with -wpedantic and it was the first time for me to get a warning that couldn't be traced down to my code, but seems to be caused by the internals of the _G_DEFINE_BOXED_TYPE_BEGIN-macro. The warning seems to appear whenever G_DEFINE_BOXED_TYPE is used with a dedicated free or copy function.
An example application may look as the following:
/* boxed_warning.c
* Produces warning, when compiled with:
* $ cc `pkg-config --cflags glib-2.0` -Wextra -Wpedantic -Wall -std=gnu11 -O0 -g -o 'boxed_warning.c.o' -c boxed_warning.c
*/
#include <glib.h>
#include <gio/gio.h>
struct _FooBoxed { gdouble x; };
typedef struct _FooBoxed FooBoxed;
static FooBoxed *
foo_boxed_copy (const FooBoxed *boxed)
{
FooBoxed *result = g_new (FooBoxed, 1);
*result = *boxed;
return result;
}
G_DEFINE_BOXED_TYPE (FooBoxed, foo_boxed, (GBoxedCopyFunc) foo_boxed_copy, (GBoxedFreeFunc) g_free)
I'm using glib 2.62.4, but I can reproduce the warning even when compiling with the latest version from git.gnome.org.
Has anyone else experienced this warning when working with the GLib2.0 and found a work-around? Or is the warning indeed related to a wrong usage of the mentioned macro by my code?

How to enable initialized but not used error in GCC

I'm compiling with a command:
gcc grep.c -std=c99 -g -Winit-self -pedantic -w -o main2 && ./main2 lib text.txt
and I wish to receive warnings for initialized but not used variables and functions.
If you use -Wunused-variable it will warn for unused variables. But I recommend using -Wall -Wextra. Then you will get that for free with a bunch of other stuff.
When it comes to unused functions I refer to this: GCC -Wunused-function not working (but other warnings are working)
You can use the -Wunused-but-set-variable option to warn for these.
test.c:
int main(void)
{
int c = 0;
c = 3;
}
Example:
$ gcc test.c -Wunused-but-set-variable -o test
test.c: In function ‘main’:
test.c:3:9: warning: variable ‘c’ set but not used [-Wunused-but-set-variable]
int c = 0;
^

I'm running into errors when patching DWM, something about function definition is not allowed here

I am trying to get a systray in dwm. DWM is suckless's dynamic window manager for X: https://dwm.suckless.org/. To configure dwm you need to manually add in the patches yourself. I made a git repo containing all the files, located at https://github.com/domianter34/dwm/tree/master/dwm, but the issue only seems to be with the dwm.c file. Also in the git repo I added I included all the patches I have ever added, so I did not patch it against stock dwm. Also I am compiling this on FreeBSD, but I think the OS is irrelevant in the context of this question. Thank you in advance.
I do not know the first thing about C programming, hence why I am asking here. From what I have read about the error it seems to indicate that I am missing a bracket somewhere, but at the line it points me too everything seems to be in order.
Here is the exact error:
rm -f dwm drw.o dwm.o util.o dwm-6.2.tar.gz
dwm build options:
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os -g -I/usr/local/include -I/usr/local/include/freetype2 -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION="6.2" -DXINERAMA
LDFLAGS = -L/usr/local/lib -lX11 -lXinerama -lfontconfig -lXft -lXrender
CC = cc
cc -c -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os -g -I/usr/local/include -I/usr/local/include/freetype2 -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"6.2\" -DXINERAMA drw.c
cc -c -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os -g -I/usr/local/include -I/usr/local/include/freetype2 -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"6.2\" -DXINERAMA dwm.c
dwm.c:796:10: warning: implicitly declaring library function 'snprintf' with type 'int (char *, unsigned long, const char *, ...)' [-Wimplicit-function-declaration]
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n - m->nmaster);
^
dwm.c:796:10: note: include the header <stdio.h> or explicitly provide a declaration for 'snprintf'
dwm.c:975:1: error: function definition is not allowed here
{
^
dwm.c:1001:1: error: function definition is not allowed here
{
^
dwm.c:1010:1: error: function definition is not allowed here
{
^
dwm.c:1025:1: error: function definition is not allowed here
{
^
dwm.c:1051:1: error: function definition is not allowed here
{
^
dwm.c:1075:1: error: function definition is not allowed here
{
^
dwm.c:1085:1: error: function definition is not allowed here
{
^
dwm.c:1103:1: error: function definition is not allowed here
{
^
dwm.c:1113:1: error: function definition is not allowed here
{
^
dwm.c:1138:1: error: function definition is not allowed here
{
^
dwm.c:1159:1: error: function definition is not allowed here
{
^
dwm.c:1177:1: error: function definition is not allowed here
{
^
dwm.c:1185:1: error: function definition is not allowed here
{
^
dwm.c:1196:1: error: function definition is not allowed here
{
^
dwm.c:1212:1: error: function definition is not allowed here
{
^
dwm.c:1228:1: error: function definition is not allowed here
{
^
dwm.c:1298:1: error: function definition is not allowed here
{
^
dwm.c:1308:1: error: function definition is not allowed here
{
^
dwm.c:1329:1: error: function definition is not allowed here
{
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
1 warning and 20 errors generated.
*** Error code 1
Stop.
make: stopped in /usr/home/dominic/Source/dwm
What I want is for it to compile successfully with the patches applied so I can use the systray.
The first error I see:
Regarding:
void
expose(XEvent *e)
{
Monitor *m;
XExposeEvent *ev = &e->xexpose;
if (ev->count == 0 && (m = wintomon(ev->window))) {
drawbar(m);
if (m == selmon)
updatesystray();
}
sightly rewritten to expose the problems:
void
expose(XEvent *e)
{
Monitor *m;
XExposeEvent *ev = &e->xexpose;
if (ev->count == 0 && (m = wintomon(ev->window)))
{
drawbar(m);
if (m == selmon)
updatesystray();
}
// this is missing, right here, the final closing brace '}'

compiler isn't issue error/warning in mismatch function parameter

I have the next code :
test.c
#include "a1.h"
int main() {
int a = 8;
foo(a);
return a;
}
a1.h
void foo (int a);
a1.c
int f = 0;
void foo (int a, int b){
f=5+a+b;
return;
}
Pay attention that in a1.c foo has 1 more parameter than the prototype defined in a1.h.
The compiler isn't issue a warning or an error and so as coverity :
make all
Building file: ../src/a1.c
Invoking: GCC C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/a1.d" -MT"src/a1.d" -o "src/a1.o" "../src/a1.c"
Finished building: ../src/a1.c
Building file: ../src/test.c
Invoking: GCC C++ Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/test.d" -MT"src/test.d" -o "src/test.o" "../src/test.c"
Finished building: ../src/test.c
Building target: test
Invoking: GCC C++ Linker
gcc -o "test" ./src/a1.o ./src/test.o
Finished building target: test
How can I defend myself in those cases ? I know that if I will add #include "a1.h" in the a1.c file I will get an error but is there a way to get an error without the "include " ?
Compiler isn't issuing a warning because it does not know that foo(int) from a1.h header and foo(int,int) from a1.c file is the same function. C++ allows functions to be overloaded, so both functions could potentially coexist. That is why C++ compiler cannot detect this problem, so you need to wait until the linking stage.
If you were compiling using C, not C++, you could have the compiler detect this condition simply by including a1.h at the top of a1.c file.
You're overloading foo. The version with only one parameter is never defined, hence you should get a linker error when using it.
How can I defend myself in those cases ?
You can't defend yourself from function overloading. Just make sure that you've got the same signature in both the header as the source file.

ANSI-C pow function and type casting

This simple program below does not build for some reason. It says "undefined reference to pow" but the math module is included and I'm building it with -lm flag. It builds if I use the pow like pow(2.0, 4.0), so I suspect there is something wrong with my type casting.
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int i;
for (i = 0; i < 10; i++) {
printf("2 to the power of %d = %f\n", i, pow(2.0, (double)i));
}
return EXIT_SUCCESS;
}
Here is the bulid log:
**** Build of configuration Debug for project hello ****
make all
Building file: ../src/hello.c
Invoking: GCC C Compiler
gcc -O0 -g -pedantic -Wall -c -lm -ansi -MMD -MP -MF"src/hello.d" -MT"src/hello.d" -o "src/hello.o" "../src/hello.c"
Finished building: ../src/hello.c
Building target: hello
Invoking: GCC C Linker
gcc -o "hello" ./src/hello.o
./src/hello.o: In function `main':
/home/my/workspace/hello/Debug/../src/hello.c:19: undefined reference to `pow'
collect2: ld returned 1 exit status
make: *** [hello] Error 1
**** Build Finished ****
You've told it to use the math library in the wrong place -- you're specifying the math library when you compile (where it won't help) but leaving it out when you link (where it's actually needed). You need to specify it when you link:
gcc -o "hello" ./src/hello.o -lm

Resources