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.
Related
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.
This question already has answers here:
Is it a good idea to typedef pointers?
(15 answers)
Closed 6 years ago.
I have this line in a header file:
typedef struct mystruct *mystruct;
And the corresponding struct definition in a .c file. Pretty standard practices.
I am getting this compilation error:
fatal error: typedef redefinition with different types ('struct mystruct *' vs mystruct')
This is using the Hexagon Tools Compiler (7.2.12) from Hexagon 3.0 SDK. It is officially QuIC LLVM Hexagon Clang version 7.2.12. Building for Snapdragon Flight. This should work as far as I know. It works with Ubuntu clang version 3.5.0-4ubuntu2~trusty2 (based on LLVM 3.5.0) for x86_64-pc-linux-gnu.
What is wrong here? Is this type of typedef a newer feature of C that is not implemented in the compiler, or rather are compiler differences like these common?
Edit: Actually struct is defined in a .c, not .cpp, file. Added the Makefile and make output showing compilation with Ubuntu clang, as well as the top of the header file with the troublesome typedef statment. A test is run at the end, and all 105 tests pass.
Edit2: See Jonathan Leffler's answer for cases where this works vs doesn't work.
ringbuf.h:
#include <stddef.h>
#include <sys/types.h>
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
typedef struct ringbuf_t *ringbuf_t;
Makefile:
CC=clang
CFLAGS=-O0 -g -Wall -Wpointer-arith -ftrapv -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error
# or, for gcc...
#CC=gcc
#CFLAGS=-O0 -g -Wall
LD=$(CC)
LDFLAGS=-g
test: ringbuf-test
./ringbuf-test
coverage: ringbuf-test-gcov
./ringbuf-test-gcov
gcov -o ringbuf-gcov.o ringbuf.c
valgrind: ringbuf-test
valgrind ./ringbuf-test
help:
#echo "Targets:"
#echo
#echo "test - build and run ringbuf unit tests."
#echo "coverage - use gcov to check test coverage of ringbuf.c."
#echo "valgrind - use valgrind to check for memory leaks."
#echo "clean - remove all targets."
#echo "help - this message."
ringbuf-test-gcov: ringbuf-test-gcov.o ringbuf-gcov.o
gcc -o ringbuf-test-gcov --coverage $^
ringbuf-test-gcov.o: ringbuf-test.c ringbuf.h
gcc -c $< -o $#
ringbuf-gcov.o: ringbuf.c ringbuf.h
gcc --coverage -c $< -o $#
ringbuf-test: ringbuf-test.o libringbuf.so
$(LD) -o ringbuf-test $(LDFLAGS) $^ -L$(MY_LIBS_PATH) -lringbuf
ringbuf-test.o: ringbuf-test.c ringbuf.h
$(CC) $(CFLAGS) -c $< -o $#
libringbuf.so: ringbuf.o
$(CC) -shared -o libringbuf.so ringbuf.o
cp ./libringbuf.so $(MY_LIBS_PATH)/
ringbuf.o: ringbuf.c ringbuf.h
$(CC) $(CFLAGS) -fPIC -c $< -o $#
cp ./ringbuf.h $(MY_INCLUDES_PATH)/
clean:
rm -f ringbuf-test ringbuf-test-gcov *.o *.so *.gcov *.gcda *.gcno
.PHONY: clean
make output:
clang -O0 -g -Wall -Wpointer-arith -ftrapv -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -c ringbuf-test.c -o ringbuf-test.o
clang -O0 -g -Wall -Wpointer-arith -ftrapv -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -fPIC -c ringbuf.c -o ringbuf.o
cp ./ringbuf.h /home/eric/Includes/
clang -shared -o libringbuf.so ringbuf.o
cp ./libringbuf.so /home/eric/Libs/
clang -o ringbuf-test -g ringbuf-test.o libringbuf.so -L/home/eric/Libs -lringbuf
./ringbuf-test
Edit3: This actually works fine with just the Hexagon-clang compiler. It is the compilation process of the larger program that this module exists in that is being problematic. I think that it is attempting to compile this code as C++.
Your code would be fine, in C and C++, if you did not try to Use typedef for a pointer type.
The header (hdr.h for instance) could/should contain:
typedef struct mystruct mystruct;
The source (hdr.cpp for instance) could contain:
#include "hdr.h"
struct mystruct
{
const char *a;
int b;
int c;
};
#include <iostream>
int main()
{
mystruct *ap = new mystruct;
ap->a = "collywobbles";
ap->b = 1;
ap->c = 2;
std::cout << "a: " << ap->a << ", b = " << ap->b << ", c = " << ap->c << "\n";
return 0;
}
This will compile in C++, even under stringent warnings. An equivalent C main() using <stdio.h> would work in C.
Why does this code generates a warning :
niko: snippets $ cat leftshift.c
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint32_t var1;
uint32_t var2;
var1=55;
var2=var1 << (sizeof(uint32_t)-8);
printf("%d\n",var2);
}
niko: snippets $ gcc -g -Wl,--warn-common -ffunction-sections -fshort-enums -fdata-sections -Wall -Wextra -Wunreachable-code -Wmissing-prototypes -Wmissing-declarations -Wunused -Winline -Wstrict-prototypes -Wimplicit-function-declaration -Wformat -D_GNU_SOURCE -fshort-enums -std=c99 -c leftshift.c
leftshift.c: In function ‘main’:
leftshift.c:10:12: warning: left shift count >= width of type [-Wshift-count-overflow]
var2=var1 << (sizeof(uint32_t)-8);
^
niko: snippets $
While this same code does not:
niko: snippets $ cat leftshift.c
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint32_t var1;
uint32_t var2;
var1=55;
var2=var1 << (32-8);
printf("%d\n",var2);
}
niko: snippets $ gcc -g -Wl,--warn-common -ffunction-sections -fshort-enums -fdata-sections -Wall -Wextra -Wunreachable-code -Wmissing-prototypes -Wmissing-declarations -Wunused -Winline -Wstrict-prototypes -Wimplicit-function-declaration -Wformat -D_GNU_SOURCE -fshort-enums -std=c99 -c leftshift.c
niko: snippets $
Is there something wrong with GCC ? Because size of uint32_t is 32 bits or isn't it?
Sizeof returns the size in bytes. You should try this:
printf("%d\n", sizeof(uint32_t));
You'll probably find that it's 4, not 32. If you want the size in bits, you can multiply by 8: sizeof(uint32_t) * 8
sizeof(uint32_t) is 4 in your system, so the first code gets the right operand as (4-8) which is a negative number, hence the warning.
In the second code it is a positive number, so no warning.
Suddenly started getting this error at link time on some older code. I managed to replicate the problem with a very simple snippet of code:
#include <poll.h>
#include <stdio.h>
typedef struct
{
struct pollfd m_fds[6000];
nfds_t m_count;
} PollWrapper;
static PollWrapper g_pollWrapper;
int main()
{
return poll(g_pollWrapper.m_fds, g_pollWrapper.m_count, 0);
}
Compiling without -flto is fine.
gcc -Wall -O3 -o poll.exe poll.c # gcc 4.8.1-10ubuntu9
# successful
But adding -flto causes an error when linking:
gcc -Wall -O3 -flto -o poll.exe poll.c # gcc 4.8.1-10ubuntu9
# error
gcc -Wall -O3 -flto -o poll.o -o poll.c
# compilation is fine
gcc -Wall -O3 -flto -o poll.exe poll.o
# linking fails
/usr/include/x86_64-linux-gnu/bits/poll2.h: In function `main`:
/usr/include/x86_64-linux-gnu/bits/poll2.h:41:2: warning: call to `__poll_chk_warn` > declared with attribute warning: poll called with fds buffer too small file nfds entries [enabled by default]
return __poll_chk (__fds, __nfds, __timeout, __bos (__fds));
^
Having read related questions, I tried explicitly enabling and disabling the linker plugin, neither had any effect.
This only appears to happen with an array, none of the following have the same problem:
struct pollfd f;
int numfds = poll(&f, g_pollWrapper.m_size, duration);
or
struct pollfd fds[6000];
int numfds = poll(&f, g_pollWrapper.m_size, duration);
etc.
Am I either missing something obvious or is this an LTO defect in my GCC, and if so is there a way I can work around it?
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)