PostgreSQL C Extensions without -Wdeclaration-after-statement - c

Currently, when I compile my extension I get,
warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
57 | uint32 n = fctx->n;
PostgreSQL currently uses -Wdeclaration-after-statement during compilation. They set this option specifically in their pgxs global make file on my machine that's at,
/usr/lib/postgresql/13/lib/pgxs/src/Makefile.global
It is set with their CFLAGS,
CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer
Is there anyway to disable -Wdeclaration-after-statement or does every PostgreSQL extension author have to adopt this same convention? Can I override CFLAGS in my extension?

Probably you can override it by the instructions described in the link
The variable PG_CFLAGS will be appended to CFLAGS, so just add -Wno-declaration-after-statement

I was able to squelch these warnings by ending my extension's Makefile like,
PG_CFLAGS += $(PERMIT_DECLARATION_AFTER_STATEMENT)
include $(PGXS)
RhodiumToad provided an alternative way after include $(PGXS)
include $(PGXS)
$(OBJS): CFLAGS += $(PERMIT_DECLARATION_AFTER_STATEMENT)
Thanks goes out RhodiumToad on ircs://irc.libera.chat:6697/#postgresql, he goes on to say
configure tests whether -Wno-declaration-after-statement works and sets up that variable accordingly well actually I think it checks for -Wdeclaration-after-statement and if that works, assumes -Wno-... works too you can put that rule after including $(PGXS), so you can make it conditional on $(MAJORVERSION) if need be or conditional on PERMIT_DECLARATION_AFTER_STATEMENT being defined

Related

Clang libFuzzer Undefined Reference to `__sanitizer_cov_trace_const_cmp8'

I can successfully compile Nginx with the following variables in the makefile
CC = clang-6.0
CFLAGS = -pipe -O -Wall -Wextra -Wpointer-arith -Wconditional-uninitialized -Wno-unused-parameter -Werror -g
When attempting to use -fsanitize=fuzzer or -fsanitize=fuzzer-no-link and changing my Makefile to:
CFLAGS = -pipe -fsantizer=fuzzer-no-link -O -Wall -Wextra -Wpointer-arith -Wconditional-uninitialized -Wno-unused-parameter -Werror -g
I get numerous undefined references to __sancov_lowest_stack and to __sanitizer_cov_trace_const_cmp8
How would I fix this? Which libraries am I missing?
You have to add sanitizer flags like -fsanitize=fuzzer to your CFLAGS and your LDFLAGS.
If they aren't passed to the linker but just to the compiler you get tons of undefined symbol errors for sanitizer runtime library functions (like the one you quoted in your question).
Note that when using -fsanitizer=fuzzer it makes sense to combine it with the Adress Sanitizer (i.e. -fsanitizer=fuzzer,address).
Also, with libFuzzer, you have to provide your own fuzzer callback function LLVMFuzzerTestOneInput() and omit a main() function.
You need to link against honggfuzz/libhfuzz/libhfuzz.a.

gcc linking object files with warning/optimization flags

We are compiling a piece of software using generics where files are first made into object files, they are built like so:
arm-unknown-linux-gnu-gcc -c -O2 -Wstrict-prototypes -Wdeclaration-after-statement -fsigned-char -I/opt/tm-sdk/include -mlittle-endian -Wno-trigraphs -fno-strict-aliasing -fno-omit-frame-pointer -march=armv4 -mtune=arm9tdmi -Wall -Wextra -o src/flex.o src/flex.c
...
arm-unknown-linux-gnu-gcc -c -O2 -Wstrict-prototypes -Wdeclaration-after-statement -fsigned-char -I/opt/tm-sdk/include -mlittle-endian -Wno-trigraphs -fno-strict-aliasing -fno-omit-frame-pointer -march=armv4 -mtune=arm9tdmi -Wall -Wextra -o src/flexdb.o src/flexdb.c
Then they are linked with:
arm-unknown-linux-gnu-gcc -o flex src/flex.o src/flexdb.o src/flexio.o src/flexprotocol.o src/flexsettings.o src/flexstate.o -L/opt/tm-sdk/lib -ltag -lrt -ltmreader -lsqlite3 -lsha1
My questions is:
Do we need to include optimization and warning flags during linking? Would it do anything if -Wall, -Wextra, and -O2 were included when creating the flex binary from the object files?
Edit: Clarifying meaning based on feedback.
Do we need to include optimization and warning flags during this final stage of compilation?
Of course you don't need to include them for the link stage. You already know that, because you don't include them. But I think what you really want to know is ...
Would it do anything if -Wall, -Wextra, and -O2 were included when building the flex binary from object files.
All or almost all warnings are generated during the compilation stage. I don't off-hand know any exceptions, but it's conceivable that there are some. Thus, it's possible that passing warning-related flags during linking would trigger warnings that otherwise you would not receive. But that shouldn't affect the compiled binary in any way.
Optimization is different. There are optimizations that can be performed at link time, but that might not be performed at the default optimization level. Omitting optimization flags from the link command should not break your build, but including them may result in a binary that is faster and / or smaller.
Overall, I see no good reason to avoid passing the same warning and optimization flags during the link step that you do during the compilation steps. If you wish, it's not harmful to pass preprocessor-specific flags (e.g. -D) as well, as they'll just be ignored during linking. I presume that all this is managed by make, so it's not like you actually need to type out the options every time.
NO You're just calling the linker with the final call to gcc and -W and -O flags are for the compiler.
-Wall is primarily a preprocessor option, but there is also a reference for the libraries. See here
-Wextra appears to be strictly a c++ preprocessor option. See here
-O2 is a compiler optimization level setting. See here
So to answer your precise question, only -Wall would possibly help during your link step. The other two would not. You could test this by building with and without these options, seeing if any additional output is created in the case of warnings and if the code size or execution time differed between builds.

MinGW GCC does not emit a warning for undefined functions

For some reason, when calling certain functions for which I have not included the appropriate header file, I do not always get a compile-time "function is not declared / defined" error. It's a real source of headaches. Most recently, calling glfwGetTime() returned zero when the header was not included, but correct values when it was, wasting a lot of debugging time.
I've noticed that when compiling same code under Linux / native GCC, these tend to be caught.
Here are my compiler options:
CFLAGS = -I$(LIBDIR) $(INCLUDES) -std=c11 -m$(BITS) -fms-extensions -fopenmp -Wall -Wextra -Wimplicit-function-declaration -Werror -Wmissing-prototypes -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -w -O0 -MMD
Any ideas why these aren't being caught at compile? P.S. This is NOT related to printf().

FLAG=-DNDEBUG is not disabling assert() in C

I have a bunch of assert() functions I used throughout my C files and from reading I have done I should be able to disable the assertions by passing in a command line parameter like so:
make
Doing this does not disable the assertions. However, adding into the code, #define NDEBUG does disable the assertions. I want to disable them from the command line though. Is there a reason why this flag is not working correctly?
I am on a Windows machine.
Here is the makefile:
OPTIONS = -B CFLAGS=-DNDEBUG -ansi -pedantic -Wall -Werror
a.out: myProgram.o StudentImplementation.o ListImplementation.o
gcc $(OPTIONS) myProgram.o StudentImplementation.o ListImplementation.o
myProgram.o: myProgram.c StudentInterface.h StudentType.h ListInterface.h ListType.h
gcc $(OPTIONS) -c myProgram.c
StudentImplementation.o: StudentImplementation.c StudentInterface.h StudentType.h
gcc $(OPTIONS) -c StudentImplementation.c
ListImplementation.o: ListImplementation.c ListInterface.h ListType.h StudentInterface.h StudentType.h
gcc $(OPTIONS) -c ListImplementation.c
clean:
rm *.o a.out
If you have a normal makefile or no makefile, then the command you want is
make -B CFLAGS=-DNDEBUG
There is no FLAG variable in the standard make recipes; each component has its own variable, so CFLAGS is for C, CXXFLAGS is for C++, LDFLAGS is for the linker, and so on.
With the Makefile you provide in the question, you cannot change flags on the make command line. You could use
OPTIONS = -DNDEBUG -ansi -pedantic -Wall -Werror
but that means editing your Makefile every time you want to change the debug setting.
You simply need
OPTIONS = -DNDEBUG -ansi -pedantic...
However a simpler Makefile would look like this
CFLAGS = -DNDEBUG -ansi -pedantic -Wall -Werror -I.
a.out: myProgram.o StudentImplementation.o ListImplementation.o
clean:
rm *.o a.out
According to my Unix makefile experience, the default flag should be CFLAGS, unless of course FLAG is explicitly used in your makefile. However, defining CFLAGS on the command line is not recommended since it is overriding a make variable.
Are there any -DNDEBUG in the compiler call invocations? If not, perhaps the problem lies in the Makefile itself, and you will have to provide its relevant data.

How enable c99 mode in gcc with terminal

I want to activate c99 mode in gcc compiler to i read in other post in this forum that -std should be equal to -std=c99 but i don't know how to set it to this value using command line so please help.
Compile using:
gcc -std=c99 -o outputfile sourcefile.c
gcc --help lists some options, for a full list of options refer to the manuals. The different options for C dialect can be found the section "Options Controlling C Dialect" in any gcc version's manual (e.g., here).
As you are using make you can set the command line options for gcc using CFLAGS:
# sample makefile
CC = gcc
CFLAGS = -Wall -std=c99
OUTFILE = outputfile
OBJS = source.o
SRCS = source.c
$(OUTFILE): $(OBJS)
$(CC) $(CFLAGS) -o $(OUTFILE) $(OBJS)
$(OBJS): $(SRCS)
$(CC) $(CFLAGS) -c $(SRCS)
Addendum (added late 2016): C99 is getting kind of old by now, people looking at this answer might want to explore C11 instead.
You may try to use the -std=c99 flag.
Try to complile like this:
gcc -Wall -std=c99 -g myProgram.c
Also note that -g is for debugging option(Thanks Alter Mann for pointing that).
Based on the comments under another answer, perhaps you are using the implicit make rules and don't have a Makefile. If this, then you are just runing make tst to generate tst binary from tst.c. In that case you can specify the flags by setting the environment variable CFLAGS. You can set it for the current shell, or add it to your ~/.bashrc to have it always, with this:
export CFLAGS='-Wall -Wextra -std=c99'
Or specifying it just for the single command:
CFLAGS='-Wall -Wextra -std=c99' make tst
(Note: I added warning flags too, you should really use them, they will detect a lot of potential bugs or just bad code you should write differently.)

Resources