gcc produces warning for qsort - c

We have some code in spatialite that looks like:
static int cmp_pt_coords (const void *p1, const void *p2)
{
....
}
static gaiaGeomCollPtr auxPolygNodes (gaiaGeomCollPtr geom)
{
....
/* sorting points by coords */
qsort (sorted, count, sizeof (gaiaPointPtr), cmp_pt_coords);
....
}
This is obviously simplified - the real code can be seen at
https://www.gaia-gis.it/fossil/libspatialite/artifact/fe1d6e12c2f98dff23f9df9372afc23f745b50df
The error that I'm getting from gcc (gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)) is
/bin/bash ../../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I../.. -g -Wall -Werror -fprofile-arcs -ftest-coverage -g -I../../src/headers -fvisibility=hidden -g -Wall -Werror -fprofile-arcs -ftest-coverage -g -MT libsplite_la-spatialite.lo -MD -MP -MF .deps/libsplite_la-spatialite.Tpo -c -o libsplite_la-spatialite.lo `test -f 'spatialite.c' || echo './'`spatialite.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I../.. -g -Wall -Werror -fprofile-arcs -ftest-coverage -g -I../../src/headers -fvisibility=hidden -g -Wall -Werror -fprofile-arcs -ftest-coverage -g -MT libsplite_la-spatialite.lo -MD -MP -MF .deps/libsplite_la-spatialite.Tpo -c spatialite.c -fPIC -DPIC -o .libs/libsplite_la-spatialite.o
spatialite.c: In function 'auxPolygNodes':
spatialite.c:17843:5: error: passing argument 4 of 'qsort' from incompatible pointer type [-Werror]
/usr/include/stdlib.h:761:13: note: expected '__compar_fn_t' but argument is of type 'int (*)(void *, void *)'
cc1: all warnings being treated as errors
I've looked at some previous postings:
What are the parameters in this C qsort function call?
Warning when using qsort in C
However they don't really seem the same (or at least, the way I read the suggestions in those postings is what I think we're already doing here).
I can cast around this, using:
qsort (sorted, count, sizeof (gaiaPointPtr), (__compar_fn_t)cmp_pt_coords);
However I don't see why that should be necessary, and I'm worried about portability to other systems. It seems like the compiler is omitting the const-s from the arguments.

That cast is perfectly fine. GCC isn't smart enough to know that __compar_fn_t is
int (*)(const void *, const void *)
so it issues a warning.
However, __compar_fn_t is not portable -- so if you don't want to use it for casting, you should probably make GCC not warn about this using an appropriate compiler flag.
Or you can see whether __compar_fn_t is defined, and if not, define it yourself:
#ifndef __GNUC__
typedef int (*__compar_fn_t)(const void *, const void *);
#endif

The error probably comes from the visibility flag that you pass to the compiler. Your are saying that all functions in that compilation unit should be hidden. For gcc this changes the function API so your comparison function is then incompatible with the one expected by qsort.
You might want to deal with
#pragma visibility
or
__attribute__((__visibility(default)))
or similar for your comparison function.

The reason for the warning/error is that the GCC prototype of __compar_fn_t is:
typedef int (*__compar_fn_t)(__const void *, __const void );
and not:
typedef int (__compar_fn_t)(const void *, const void *);
Therefore, in order to solve the problem, simply define your function as:
static int cmp_pt_coords (__const void *p1, __const void *p2)

Related

UNDERFLOW keyword with gcc on MSYS2

I ran into some really weird problem with the compilation of a very simple code
typedef volatile struct _underflow_test
{
unsigned int OPERATION_MODE;
unsigned int UNDERFLOW;
} underflow_test;
This code fails to compile in MSYS2 using gcc12.2. Using the -E option I have checked that the code about is converted to this:
typedef volatile struct _underflow_test
{
unsigned int OPERATION_MODE;
unsigned int
# 4137 "C:/Users/work/eec_control/TC367_project/Libraries/Infra/Sfr/TC36A/_Reg/IfxGeth_regdef.h" 3
4
# 4137 "C:/Users/work/eec_control/TC367_project/Libraries/Infra/Sfr/TC36A/_Reg/IfxGeth_regdef.h"
;
} underflow_test;
So preprocessor converted UNDERFLOW into just 4. Then this conversion fails to compile.
Using the gcc11 doesn't do this - it doesn't convert UNDERFLOW field into 4.
The command line is the same in both cases:
cd C:/Users/work/build-eec-gnu/core_files/bsp && C:/msys64/mingw64/bin/gcc.exe
-DROOT_INSTALL_DIR="\"C:/Program Files (x86)/eec-control\""
#CMakeFiles/bsp-core-tc367-a1.dir/includes_C.rsp
-Wall -Wextra -Wno-unknown-pragmas -Wfloat-equal -Wconversion -Wparentheses -Wunused-parameter -Wunused-variable -Wstrict-prototypes
-DMAJOR_RELEASE_NUMBER=1 -DMINOR_RELEASE_NUMBER=0 -DPATCH_RELEASE_NUMBER=42 -E -O0 -DNDEBUG -g
-fdiagnostics-color=always -std=gnu99 -MD -MT core_files/bsp/CMakeFiles/bsp-core-tc367-a1.dir/hal.c.obj
-MF CMakeFiles/bsp-core-tc367-a1.dir/hal.c.obj.d -o CMakeFiles/bsp-core-tc367-a1.dir/hal.c.obj
-c C:/Users/work/eec_control/core_files/bsp/hal.c
Anyone know what could be causing this and how to solve this strange effect? Perhaps I'm missing something.

clang: warning: argument unused during compilation: '-always-inline' [-Wunused-command-line-argument]

I want to force the clang compiler to inline the code.
I have already use the inline __attribute__((always_inline)) while realizing the function:
inline __attribute__((always_inline)) void func() {
// ...
}
I tried to compile the code by using:
clang sort.c -O3 -DNDEBUG -g -Wall -std=gnu99 -gdwarf-3 -always-inline -lrt -lm -o sort
However I got the warning when compiling:
clang: warning: argument unused during compilation: '-always-inline' [-Wunused-command-line-argument]
And my function is not inlined.
What did I miss?

GCC how to suppress " discards 'volatile' qualifier from pointer target type"

How can i suppress this warning?
maybe some #pragma GCC diagnostic ignored in code or CFLAG in makefile?
If you had posted the full warning message it should show the specific warning [-Wdiscarded-qualifiers]. Like other warnings, just prefix with no- to suppress it.
From the gcc manual
-Wno-discarded-qualifiers (C and Objective-C only)
Do not warn if type qualifiers on pointers are being discarded. Typically, the compiler warns if a const char * variable is passed to a function that takes a char * parameter. This option can be used to suppress such a warning.
$ cat test.c
#include <stdio.h>
int a;
volatile int *p = &a;
int main (void)
{
int *q = p;
return 0;
}
$ gcc test.c
test.c: In function ‘main’:
test.c:8:11: warning: initialization discards ‘volatile’ qualifier from pointer target type [-Wdiscarded-qualifiers]
int *q = p;
^
$ gcc -Wno-discarded-qualifiers test.c
$
Although you probably already know it is a bad programming tactic, you can disable warnings in general when compiling and not only the one that bugs you.
Add -w option when compiling
I also attach you the documentation on Warnings Options.
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Hope i helped!
ok thanks guys. -Wdiscarded-qualifiers not really helped me.
actually ive tried to find it in gcc docs, but i am not good at this.
here`s my cflags in project
CFLAGS ?= -g0 -O3 -Wno-discarded-qualifiers -Wshadow -Wmaybe-uninitialized -Wall -Wextra -Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith -fno-strict-aliasing -Wno-error=cpp -Wuninitialized -Wmaybe-uninitialized -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wno-switch-enum -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-error=pedantic -Wno-sign-compare -Wno-error=missing-prototypes -Wdouble-promotion -Wclobbered -Wdeprecated -Wempty-body -Wtype-limits -Wno-unused-value -Wno-unused-parameter -Wno-missing-field-initializers -Wuninitialized -Wmaybe-uninitialized -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wpointer-arith -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-sign-compare
LDFLAGS ?= -lm
and the reason that i am using discard volatile qualifiers is that i dont want to add volatile in function prototypes and dont want to cast it in function call, because some of variables works fine without volatile key, and others - not.
(its some common variables and also thread_t types)
so code works fine, also when ive tried to cast volatile types in function call - there some glitches happened, and now all works fine. Thanks for help i appreciate that!
now with that key i have
"discards 'volatile' qualifier from pointer target type"
its pointers that sometimes get optimizated by compiler.

Linking multiple .c files

I have a C file named first.c in which I define an array and call a function which is defined in a C file named second.c. This is how first.c looks:
int main(void)
{
int array[100];
myFunc(*array);
}
second.c on the other hand looks like this:
void myFunc(int array)
{
...
}
But anytime I try to compile these, second.c gives me errors as if it had no idea about the array I passed to its function as an argument. I guess the function doesn't know that at the linking stage. I compile these like this:
gcc -O2 -std=c99 -Wall -pedantic -lm second.c -c
gcc -O2 -std=c99 -Wall -pedantic first.c -c
gcc second.o first.o -o finished
But that's just what I came up with and of course it doesn't work. I guess a Makefile would be in place, but I'm not sure how to implement it.
Your issue may lie in that the received value is not a pointer- so change void myFunc(int array) to void myFunc(int* array).

c gcc compiler options for pointer arithmetic warning

I’m using the following flags, but still I m not able to get this warning:
pointer of type void * used in arithmetic
Flags used:
-O2 -Werror -Wall -Wno-main -Wno-format-zero-length -Wpointer-arith -Wmissing-prototypes -Wstrict-prototypes -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -Wno-sign-compare -Wno-pointer-sign -Wno-attributes -fno-strict-aliasing
-Wpointer-arith should catch this type of warning, but I’m not able to get this warning:
pointer of type void * used in arithmetic
Which specific cflag should be used to get this warning?
Edit: my mistake, it is there as part of a macro check which is not defined. :( By defining that macro, I’m able to get that error.
You're right. -Wpointer-arith should give you a warning as per the documentation.
I have just tried the following program (with intentional error):
~/code/samples$ cat foo.c
#include <stdio.h>
int main (int argc, char **argv)
{
void * bar;
void * foo;
foo = bar + 1;
return 0;
}
I have compiled the program with just the -Wpointer-arith option, and all your options as listed above. Both attempts threw up the desired warning. I am using gcc version 4.3.4 (Debian 4.3.4-6).:
~/code/samples$ gcc -Wpointer-arith foo.c
foo.c: In function ‘main’:
foo.c:6: warning: pointer of type ‘void *’ used in arithmetic
and
~/code/samples$ gcc -O2 -Werror -Wall -Wno-main -Wno-format-zero-length -Wpointer-arith -Wmissing-prototypes -Wstrict-prototypes -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -Wno-sign-compare -Wno-pointer-sign -Wno-attributes -fno-strict-aliasing foo.c
cc1: warnings being treated as errors
foo.c: In function ‘main’:
foo.c:6: error: pointer of type ‘void *’ used in arithmetic
The compiler does throw up the warning if you give it the 'right' code. So, I would recommend you examine why it is you expect this warning. Maybe the code you're compiling has changed?
One possible clue I can give you: foo = bar + 1; in the code above triggers the warning. But foo = bar ++; will not (You get a different warning). So if your code uses increment (or decrement) operators on pointers, it will probably not trigger the warning.
I know this is not a direct answer, but I hope this helps you focus your investigation.
With gcc 4.2.1 on OS X, I get this warning:
p.c:7: warning: wrong type argument to increment
for the following program:
#include <stdio.h>
int main(void)
{
int i[] = { 42 };
void *p = i;
printf("%p\n", p++);
return 0;
}
I am compiling it as:
$ gcc -Wpointer-arith p.c
Can you post your program, or post the result of compiling the above?

Resources