Why is gcc not complaining about missing symbol? - c

I have defined the following in a c file:
#ifdef __clang__
// clang definition here
#elif defined _GNULINUX
#define _ALIGNED_FREE(pMempointer) _free((pMempointer))
#elif defined _MSC_VER
// VS definition here
#else
// default definition
#endif
void * pMemory = 0L;
if(pMemory) {
_ALIGNED_FREE(pMemory);
}
gcc flags are:
-Wall -Wno-long-long -fexpensive-optimizations -fomit-frame-pointer -funroll-loops -pipe -fexceptions -Wpointer-arith -Wcast-align -Wsign-compare -pedantic -mmmx -msse
After compiling (in a Ubuntu 14.04 machine) with gcc version 4.8.2 successfully the program exits at runtime with undefined symbol: _free
Obviously the symbol _free is unknown, but why does gcc not complain about this? I would expect it to throw an error at linking time like the VS linker does.

free does not have a leading underscore in Linux nor by the C Standard.

Related

compilation error for avx512, is it a GCC issue?

I am trying to compile the following code with AVX512 intrinsic, but gives me the compile error.
#include <immintrin.h>
static inline __attribute__((always_inline)) void
mov64(uint8_t *dst, const uint8_t *src)
{
__m512i zmm0;
zmm0 = _mm512_load_si512((const void *)src);
_mm512_store_si512((void *)dst, zmm0);
}
The compilation error:
gcc -D_GNU_SOURCE -DINFO_LOG_DEBUG --std=c99 -march=native -O3 -DNDEBUG -m64 -mtune=native -Werror -Wall -Wundef -Wpointer-arith -Wstrict-prototypes -Wnested-externs -fomit-frame-pointer -DTRANSPORT_CONFIG_OPT_HDR='<ci/internal/transport_config_opt_extra.h>' -c src/main.c -o obj/main.o
src/main.c: In function ‘mov64’:
src/main.c:15:9: error: unknown type name ‘__m512i’
__m512i zmm0;
^
src/main.c:17:9: error: implicit declaration of function ‘_mm512_load_si512’ [-Werror=implicit-function-declaration]
zmm0 = _mm512_load_si512((const void *)src);
^
src/main.c:17:9: error: nested extern declaration of ‘_mm512_load_si512’ [-Werror=nested-externs]
src/main.c:18:9: error: implicit declaration of function ‘_mm512_store_si512’ [-Werror=implicit-function-declaration]
_mm512_store_si512((void *)dst, zmm0);
^
src/main.c:18:9: error: nested extern declaration of ‘_mm512_store_si512’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
In addition, if I add -march=native,avx512f or -mavx512f or -march=skylake-avx512, it gives the following error:
src/main.c:1:0: error: bad value (skylake-avx512) for -march= switch
My GCC version is 4.8.5 20150623 and CPU is "Intel(R) Xeon(R) Gold 6154". What should I do to overcome this problem? Thanks in advance..
GCC 4.8 does not support any of the AVX-512 variants. If this is the system compiler from Red Hat Enterprise Linux 7, you can use a new GCC version from Red Hat Developer Toolset, which provides support for later CPU features. (DTS is also available for CentOS.)

Macro wrongly defined in Makefile of Openwrt package

In the openwrt package that I'm working on, I defined a new config flag by adding following bloc to the Config.in file:
config VENDOR_PREFIX
string "Vendor Prefix"
default "X_Custom_SE_"
The flag is well added in the menuconfig:
I want that the value of this config flag is viewed in my C code as a macro. So I defined a macro CUSTOM_PREFIX in the Makefile of the package and assigned to it the value of the defined flag with this way:
TARGET_CFLAGS += -DCUSTOM_PREFIX=\"$(CONFIG_VENDOR_PREFIX)\"
and then I tried to use my macro in my C code by calling it in a structure variable initiation like that:
struct parameter_struct param1= {CUSTOM_PREFIX"param1", 4};
After that I tried to compile it. But I got this compilation error:
/home/user/openwrt//staging_dir/toolchain-mips_mips32_gcc-5.5.0_musl/usr/include -I/home/user/openwrt/staging_dir/toolchain-mips_mips32_gcc-5.5.0_musl/include/fortify -I/home/user/openwrt/staging_dir/toolchain-mips_mips32_gcc-5.5.0_musl/include -I/home/user/openwrt/staging_dir/target-mips_mips32_musl/usr/include -I/home/user/openwrt/staging_dir/target-mips_mips32_musl/usr/include -I/home/user/openwrt/staging_dir/target-mips_mips32_musl/usr/include -DCWMP_VERSION=\"3.0.0\" -I../inc/ -I../dm/ -I../dm/dmtree/ -I../dm/dmtree/common -I../dm/dmtree/tr098 -I../dm/dmtree/tr181 -I../dm/dmtree/upnp -Os -pipe -mips32 -mtune=mips32 -fno-caller-saves -DCONFIG_TARGET_iopsys_brcm63xx_mips -g3 -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -iremap/home/user/openwrt/build_dir/target-mips_mips32_musl/icwmp-curl/icwmp-4.0-2018-03-21:icwmp-4.0-2018-03-21 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -DCUSTOM_PREFIX=X_CUSTOM1_SE_ -D_GNU_SOURCE -D_AADJ -MT ../dm/dmtree/common/libdatamodel_la-deviceinfo.lo -MD -MP -MF ../dm/dmtree/common/.deps/libdatamodel_la-deviceinfo.Tpo -c ../dm/dmtree/common/deviceinfo.c -fPIC -DPIC -o ../dm/dmtree/common/.libs/libdatamodel_la-deviceinfo.o
^
../dm/dmtree/common/deviceinfo.c: At top level:
<command-line>:0:15: error: 'X_CUSTOM1_SE_' undeclared here (not in a function)
../dm/dmtree/common/deviceinfo.c:28:2: note: in expansion of macro 'CUSTOM_PREFIX'
{CUSTOM_PREFIX"param1", 4}
struct parameter_struct param1= {CUSTOM_PREFIX"param1", 4};
seems like that the c program doesn't accept it as a string.
Is there something wrong in my macro definition?
As I expected and I noted in the my post title the mistake is in the definition of the macro in the Makefile. In Openwrt Makefile the definition of the Macro should be like that:
TARGET_CFLAGS += -DCUSTOM_PREFIX=\\\"$(CONFIG_VENDOR_PREFIX)\\\"

Enforcing ANSI C89 with clang

I'm trying to make the C compiler clang go into ANSI C89 mode but without success.
Here is an example session:
$ cat t.c
#include <stdio.h>
int main(void)
{
puts(__FUNCTION__);
return 0;
}
$ gcc -pedantic -std=c89 -Wall t.c
t.c: In function ‘main’:
t.c:5:7: warning: ISO C does not support ‘__FUNCTION__’ predefined identifier [-Wpedantic]
puts(__FUNCTION__);
^~~~~~~~~~~~
$ clang -pedantic -std=c89 -Wall t.c
$ clang --version
clang version 3.8.1-24 (tags/RELEASE_381/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
As you can see, the clang command completes with no warning. Is there a command option that I'm missing here?
It seems as if this specific warning is not emitted by clang, but apparently -std=c89 does toggle ANSI C89 syntax checking.
For example:
inline int foo(int* restrict p)
{
return *p;
}
Will refuse to compile with -std=c89 -pedantic -Wall:
t.c:1:1: error: unknown type name 'inline'
t.c:1:23: error: expected ')'
int foo(int* restrict p)
But will compile without errors using -std=c99.
The non-standard predefined identifiers warning was introduced with GCC 5 (https://gcc.gnu.org/gcc-5/porting_to.html), and apparently clang did not adapt with it.

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.

Identifier not loaded in c

I am trying to run a example on handling signals, and it fails compiling on a unfound identifier.
Here is how the header is loaded :
#define __USE_GNU
#include <ucontext.h>
And the error when compiling (with gcc):
$ gcc -o sa_siginfo sa_siginfo.c
sa_siginfo.c: In function ‘bt_sighandler’:
sa_siginfo.c:25:28: error: ‘REG_RIP’ undeclared (first use in this function)
uc->uc_mcontext.gregs[REG_RIP]);
GCC info:
$ gcc --version
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
/usr/include/ucontext.h does include /usr/include/sys/ucontext.h which has:
#ifdef __x86_64__
[...]
#ifdef __USE_GNU
/* Number of each register in the `gregset_t' array. */
enum
{
[...]
REG_RIP,
(My system is 64 bits)
So I don't understand why it doesn't find it ?
Try compiling your program like this
gcc -D_GNU_SOURCE -o sa_siginfo sa_siginfo.c
That __USE_GNU is defined only if you defined _GNU_SOURCE, and gcc will not define it by default.

Resources