Why does this not work?:
prog.c file
#include <stdio.h>
int main(void)
{
int i, j;
printf("\n%d\n%d\n", i, j);
return 0;
}
debug file:
#!/bin/bash
g++ -Wall -Wextra -Wpedantic -O0 -g3 -fsanitize=address -o temp/debug.out src/prog.c
./temp/debug.out
running:
./debug
prog.c: In function ‘main’:
prog.c:6:9: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
printf("\n%d\n%d\n", i, j);
^~~~~~~~~~~~~~~~~~~~~~~~~~
prog.c:6:9: warning: ‘j’ is used uninitialized in this function [-Wuninitialized]
0
0
==90==LeakSanitizer has encountered a fatal error
==90==HINT: For debugging, try setting environment variable LSAN_OPTION=verbosity=1:log_threads=1
==90==LeakSanitizer does not work under ptrace (strace, gdb, etc)
I'm new to using debuging tools but there isn't much to read on this topic except man pages of compilers. So please can someone help me?
This was executed on Windows 10 subsystem for linux (Ubuntu) on freshly openned terminal.
I'd like to use -fno-sanitize=all option I found in man pages of gcc but it doesn't seem to say a word on any mistake I came up with.
I found out it was problem of WSL i used (I didn't think it was important to say i use one)
Turns out i need to write LSAN_OPTION=verbosity=1:log_threads=1; g++ -Wall...
Related
I have a large codebase of C code which part of it is generated code from the Oracle Pro*C precompiler.
We use the GNU gcc compiler.
The Pro*C precompiler generates code that contains unused variables that emits many warnings related to -Wunused-variable which I'd like to ignore.
I've tried the following which I found in other questions but it doesn't see to work for C code (cut down to a minimal example).
int main(void)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
int a=0;
#pragma GCC diagnostic pop
int b=0;
return 0;
}
I still get the -Wunused-variable error for variable a.
aa.c: In function 'main':
aa.c:8:13: warning: unused variable 'b' [-Wunused-variable]
int b=0;
^
aa.c:6:14: warning: unused variable 'a' [-Wunused-variable]
int a=0;
^
GCC command:
gcc-8 -Wall -Wextra -pedantic aa.c -o a
Incase you are wondering, if I remove the pop pragma, no warnings are issued.
The solution I found was to add __attribute__((unused)) before the generated variables that were problematic. In this situation there are always only 4 relevant variables so it was possible.
I wrote a bash command in the make file right after the Pro*C precompiler:
for var in varA varB varC varD; do sed -i "0,/${var}/{s/\(${var}\)/__attribute__((unused))\1/}" $file_name; done
Hope it can be helpful for someone.
Here is the content of source file get.c :
#include <stdio.h>
int main(){
//int i = 0;
char b[10];
gets(b);
puts(b);
return 0;
}
When I compile it with these command
gcc -o get get.c -Wall -Werror
The output is
/tmp/ccYEWZvx.o: In function `main':
get.c:(.text+0x10): warning: the `gets' function is dangerous and should not be used.
But when change the code to
#include <stdio.h>
int main(){
int i = 0; // **this line just be uncommented**
char b[10];
gets(b);
puts(b);
return 0;
}
Using the same command, the output is
cc1: warnings being treated as errors
get.c: In function 'main':
get.c:4: error: unused variable 'i'
So, why this unused variable warning be treated as error, while the use of gets() not?
The gets() warning is being issued by the linker not the compiler, so the compiler settings do not apply.
Only the linker is able to determine that the symbol is resolved with the standard library gets() rather than some other implementation with the same name.
To instruct the linker to treat warnings as errors you need to pass it the --fatal-warnings option. In turn when not invoking the linker directly, options are passed to the linker by gcc using the -Wl option in a comma separated list:
gcc -o get get.c -Wall -Werror -Wl,--fatal-warnings
Note that the GNU linker is documented separately from the compiler, as part of binutils. The linker options are described here.
If you look at the output from the first example, it says the "error" is in an object file, which means it is generated by the linker.
The second error is generated by the compiler, which means there is no object file being generated and so the linker will not be invoked.
-Werror make all warnings as errors, to print only security warnings you can use: -Wformat -Wformat-security
You can read warnings options here https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
The compiler abort the compilation if an error is occurred, instead it continue the compilation if there are one or more warnings.
I compile this code main.c in CentOS7 with gcc:
#include <pthread.h>
void* mystart(void* arg)
{
pthread_yield();
return(0);
}
int main(void)
{
pthread_t pid;
pthread_create(&pid, 0, mystart, 0);
return(0);
}
1st compile: gcc -Wall -g main.c -pthread -o a.out
It's all OK.
2nd compile: gcc -Wall -g main.c -lpthread -o a.out
Gives
warning: implicit declaration of function 'pthread_yield' [-Wimplicit-function-declaration]
Can the 2nd a.out still run correctly ?
How to fix the warning without -pthread? Is sched_yield another way to yield a pthread ?
pthread_yield() is a non-standard function which is typically enabled by defining
#define _GNU_SOURCE
While you should use -pthread for compiling, I would expect you to get the same warning with both compilations (unless -pthread defines _GNU_SOURCE which may be the case).
The correct way to fix is to not use the non-standard function pthread_yield() and use the POSIX function sched_yield() instead by including #include <sched.h>.
You should use -pthread for compile and link. It not only links the library, it also sets preprocessor defines and sometimes selects a different runtime library (on Windows for example).
I created a basic C project in Xcode and modified the starter code in main.c slightly. I also went into the build settings and told it to use ANSI-C. Here's the code I have:
int main(int argc, const char * argv[])
{
// a statement!
printf("Hello, World!\n");
// shouldn't this cause a compiler error?
// the variable isn't declared at the top of the scope.
int x;
x += 10;
return 0;
}
Obviously, it doesn't do much, but I expected the variable declaration to produce a compiler error (since older versions of C require variable declarations at the beginning of the scope, before other statements). However, Xcode happily compiles it and runs it with neither an error or warning.
I might be making a dumb mistake somewhere, but I'm trying to understand why this code compiles. I've read that C99 and C11 allow you to declare variables anywhere, so this would work, but I explicitly set the project to use ANSI-C. Is this just the way Apple's LLVM compiler works? Or am I missing something elsewhere?
TL;DR You need to add -pedantic (or -Wdeclaration-after-statement) to -ansi to get the warning you want.
Somewhat to my surprise, both clang (from Apple XCode 7.2) and gcc (from GCC 5.3.0, which I built), accept the code when compiled with either -std=c90 or -ansi even though it is not strictly compliant with C90.
However, both complain when told to be -pedantic.
$ clang -ansi -c xyz.c
$ clang -std=c90 -c xyz.c
$ gcc -std=c90 -c xyz.c
$ which gcc
/opt/gcc/v5.3.0/bin/gcc
$ gcc -std=c90 -pedantic -c xyz.c
xyz.c: In function ‘main’:
xyz.c:7:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
int x;
^
$ clang -pedantic -std=c90 -c xyz.c
xyz.c:7:9: warning: ISO C90 forbids mixing declarations and code [-Wdeclaration-after-statement]
int x;
^
1 warning generated.
$ clang -pedantic -ansi -c xyz.c
xyz.c:7:9: warning: ISO C90 forbids mixing declarations and code [-Wdeclaration-after-statement]
int x;
^
1 warning generated.
$
The file xyz.c is your source code with the comments stripped, #include <stdio.h> added at the top, and int main(void) in place of int main(int argc, char **argv) since the code doesn't use the arguments.
Note that your code has undefined behaviour; incrementing an uninitialized variable is a bad idea.
I was reading C programming from a book that says all variables have to be declared in the beginning of the function. I tried following code but didn't issue any error. I am using mingw and codeblocks. The code is as follows:
#include <stdio.h>
int main()
{
int i=10;
printf("%d\n",i);
int j=20;
printf("%d\n",j);
return 0;
}
Do I have to change any compiler setting or something to make it compatible with the standard given in the book?
I am using -std=c89 compiler option. See the compilation messages below:
-------------- Clean: Debug in HelloWorld (compiler: GNU GCC Compiler)---------------
Cleaned "HelloWorld - Debug"
-------------- Build: Debug in HelloWorld (compiler: GNU GCC Compiler)---------------
mingw32-gcc.exe -Wall -std=c89 -g -c D:\MyCodeBlocksProjects\HelloWorld\main.c -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\HelloWorld.exe obj\Debug\main.o
Output size is 68.53 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 0 warnings (0 minutes, 0 seconds)
all variables have to be declared in the beginning of the function.
To be precise, they have to be declared in the beginning of a block. And this is only true in C89. C99 has removed this limit. So you can change your compiler to strict C89 mode. For example, for GCC, it's -std=c89 option. To obtain all the diagnostics required by the standard, you should also specify the option -pedantic.
To demonstrate what I mean by in the beginning of a block, this is legal C89 syntax:
void foo()
{
int x = 1;
x = x + 1;
{
int y = 42; /**OK: declaration in the beginning of a block*/
}
}