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;
}
This question already has answers here:
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Why does the order of '-l' option in gcc matter? [duplicate]
(3 answers)
Closed 1 year ago.
Why I am getting the following error
/tmp/ccuWdVB3.o: In function `test':
MyCode.c:(.text+0x1c): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
MyCode.c
#include<stdio.h>
#include<math.h>
int test(int input1)
{
int x = 8;
int z = sqrt(x);
}
int main(int argc, char * a[]) {
}
when running with command:
gcc -o a.out -lm MyCode.c
But when I am running the command
gcc MyCode.c -o a.out -lm
everything works fine. Why the order of "MyCode.c" cli option is important here ?
Or Am i doing something wrong?
Libraries are searched only once during the linking (they may contain millions of symbols and objects) and that is the reason why they should be specified as the last ones when all objects linker has to search for are already known. Searching the giant library for the symbols after every object file in the project would be extremely inefficient.
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 '}'
source.c ::
int source=0;
int desti=0;
char str[50]="";
source.h::
extern int source;
extern int desti;
extern char str[50];
station1.c
#include"source.h"
#include<stdio.h>
main()
{
printf("%d %d",source,desti);
}
When I compile station1.c I get the following error:
undefined reference to 'desti'
undefined reference to 'source'
Could anyone please tell me where I have gone wrong?
What did your compile command line look like?
Try:
cc -c station1.c -o station1.o
cc -c source.c -o source.o
cc -o a.out station1.o source.o
The first two compile the files by themselves and puts the result in a .o file.
The last line combines the .o files into an executable named 'a.out'.
When we use extern modifier with any variables it is only declaration i.e. memory is not allocated for these variable. Hence in your casecompiler is showing error unknown symbol source & desti. To define a variable i.e. allocate the memory for extern variables it is necessary to initialize the variables.
initialize the variables in source.c
or another way is to compile with combining the object file
gcc -c source.c station1.c -Isource.h
I have been stuck on this all afternoon, and even tried the following search: "c++ passing pointer to array via function", and can't find a working answer, so here is my question.
Before I begin, please, this is NOT an OpenGL question, this is an array pointer passing question.
Also, don't get '....' (4 dot) mixed up with '...' (3 dot). There is a lot of code I am skipping over with '....' (4 dot), the ... (3 dots) are the ellipse parameter for variable number of paramters passed to a function.
These are the snippets from the four files involed:
OpenGL.h
class OpenGL {
.... (other unrelated stuff)
public:
int * iPixelFormatAttribList[]; <----------
....
utilities.h
template <typename T> void LoadArray (T * [], int, ...); <--------
utilities.cpp
// Dynamically Load Array.
template <typename T>
void LoadArray (T * Dest [], int count, ...) { <-------
va_list list;
va_start(list,count);
T * temp [] = new T [count];
for (int cnt = 0; cnt < count; cnt++)
* Dest[cnt] = va_arg(list, T);
va_end(list);
Dest = temp;
delete [] temp;
}
OpenGL.cpp
void OpenGL::V3_SetupPixelFormat() {
.....
LoadArray (
iPixelFormatAttribList, 15, <---------
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
0
// End of attributes list
);
Ok, So, here what I am trying to do. I know that in a class definition, (OpenGL.h, the OpenGL class), that space is not allocated for any members, and because when I create it, I do not know how many paramters I am going need for an array, I need to find a way to dynamically allocate and setup the list so I can pass it into later OpenGL calls.
(Another reason I decided to setup a dynamic loading list like this was because there are several arrays involved like this, loading arrays, and I may also need this same type of functionality later with doubles and what not for vector data. Creating this utility template seems a forward thinking way to go.)
This all LOOKS Ok, and in fact, it compiles clean, but it does not link. I get the following:
**** Internal Builder is used for build ****
windres --use-temp-file -i..\res\resource.rc -o..\res\resource_rc.o
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\OpenGL.o ..\src\OpenGL.cpp
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\main.o ..\src\main.cpp
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\Utilities.o ..\src\Utilities.cpp
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\App.o ..\src\App.cpp
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\Win.o ..\src\Win.cpp
g++ -o OpenGL3.exe src\main.o src\Win.o src\Utilities.o src\OpenGL.o src\App.o ..\res\resource_rc.o -lopengl32 -lglew32 -lglu32 -lkernel32 -lgdi32 -lcomdlg32 -luser32
src\OpenGL.o: In function `ZN6OpenGL19V3_SetupPixelFormatEv':
D:\Dev\Projects\Eclipse\OpenGL3\Debug/../src/OpenGL.cpp:54: undefined reference to `void LoadArray<int>(int**, int, ...)'
collect2: ld returned 1 exit status
Build error occurred, build is stopped
Time consumed: 3000 ms.
The key line to me looks like:
undefined reference to `void LoadArray<int>(int**, int, ...)'
What this seems to tell is the way I am calling the function:
LoadArray (
iPixelFormatAttribList, 15,
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
....
And the way I am defining the template function:
template <typename T> void LoadArray (T * [], int, ...);
and:
template <typename T>
void LoadArray (T * Dest [], int count, ...) {
don't match. I get that much.
What I don't get is how to adjust the template (Or the call) so that they match so it can link (i.e. I got my function signatures all screwed up.)
The basic idea to this is, I call LoadArray with an array pointer, the element count, and the list of elements, and it modifies the pointer so that it points to a new list containing the array elements.
I am sure there are fancy C++ ways to do this, but I want to understand how to make this work as it seems it should here. (i.e. it would help me to learn if I know what exactily I was doing wrong here, rather then a redirect solution that won't teach me what I did wrong, I know enough to know I am missing something in the syntax of passing an array pointer like this, I just can't figure out the right black magic to get it right.)
Thanks.
Move your all your template code to the header file. That makes straight forward for the compiler to instantiate instances of your template class for different template parameters. If you don't do this then you need to force instantiation of the template for the types you need.
Why don't you just define your template as
template <typename T>
void LoadArray(T **Dest, int count, ...) {
And be done with it?