I have an inline function like this:
inline void func_1 (int a)
{
if(a==1)
{
other_func1();
}
else
{
other_func2();
}
}
and I use in the Main like this:
int main()
{
func1(1);
func1(42);
return 0;
}
I use GCC, I think, the compiled code look like this (in “source level”):
int main()
{
other_func1()
other_func2();
return 0;
}
Is it true or am I wrong?
Yes, in general gcc will optimise away dead code in inline functions when it can evaluate branches at compile-time. I use this construct a lot to allow optimised code to be generated for different use cases - somewhat like template instantiation in C++.
Related
With gcc, is it possible to compile with -fstack-protector, but omit for a specific function.
For example, say i have two functions.
void a() {
...
}
void b() {
...
}
Can I tell the compiler to compile a program that will use a canary before the saved return address of a, but no canary for b?
You'd have to test if it works (inspect the generated code at Godbolt) but it looks like you can do, for example:
__attribute__ ((no_stack_protector)) void foo () { ... }
no_sanitize looks like an intriguing option, I wonder who uses that.
Does it analysis the lifecycle of the variable and simply insert the cleanup function call at the right place? Does it have any overhead cost?
I've written two pieces of simple code to compare the performance, and compiled them without optimization.
code1:
#include <stdio.h>
#include <stdlib.h>
void clean_up(int **final_value)
{
free(*final_value);
}
int main(int argc, char **argv)
{
for (int i = 0; i < 10000000; i++) {
int *avar = malloc(sizeof(int));
clean_up(&avar);
}
return 0;
}
code2:
#include <stdio.h>
#include <stdlib.h>
void clean_up(int **final_value)
{
free(*final_value);
}
int main(int argc, char **argv)
{
for (int i = 0; i < 10000000; i++) {
int *avar __attribute__ ((__cleanup__(clean_up))) = malloc(sizeof(int));
}
return 0;
}
And their performance are quite similar.
You'll better compile with some optimization, in particular if you want to look into the generated assembler code (compile with gcc -S -fverbose-asm -O)
The intuition behind __attribute__((cleanup)) is that GCC is in fact a compiler for all of C, C++, Ada, Fortran, Go.... That attribute is forcing the same internal representation than for C++ destructors of local variables. The cleanup happens at end of current block scope (e.g. at closing brace } of the block). So the compiler is transforming your code2 with cleanup into the equivalent of code1.
The thing for destructors of global or static variables (which are run after main has returned) is __attribute__((destructor)) on functions (which are also run at dlclose time for plugins).
So to understand these attributes, you'll better think in C++ terms.
My opinion is that if you need these cleanup attributes, you should code your thing in C++ not in C. Your code would be much more readable and less compiler dependent. I feel that cleanup is in practice only useful in generated C code. I never used it (and feel that when I need it, I should switch to C++).
The cleanup function is called when the variable goes out of scope. It doesn't care, whether this would leave other pointers dangling.
I'm trying to port some GCC nested function to clang. As gcc nested function is not supported in clang, i need to use c-block instead.
But i want to have the block definition after the call to it. (I need this order because code is generated from MACRO and i can not arrange this order)
So in gcc i have this pseudo code :
foo(){
auto void bar (void);
...
bar()
...
void bar(void) {
...some stuff
}
}
You i can do this in C-block clang function ?
This code works fine
int main() {
void (^hello)(void);
hello = ^(void){
printf("Hello, block!\n");
};
hello();
return 0;
}
But the following code
int main() {
void (^hello)(void);
hello();
hello = ^(void){
printf("Hello, block!\n");
};
return 0;
}
failed with an segfault.
In your second example, hello has not been defined before you call it, so it is an undefined symbol. You have to tell the compiler what something is before you can use it.
In your pseudocode, a function prototype preceeds everything, which gets around the error by telling the compiler "this will be defined later on."
What I would like is a tool to be able to tell me which functions call a particular function A() (in a C project), and which functions call those functions etc so that I can have a list of functions which i know that when they are called, there is a possibility that function A() will be called.
For example we have the following functions scattered in a project:
void A()
{ /*does something*/ }
void B()
{
A();
/*and more stuff*/
}
void C()
{
if(unlikely_to_be_false)
A()
/* moar stoff */
}
void D()
{
/* code that does not refer to A() at all */
}
void E()
{
C()
}
When the awesome tool is run with parameter A, It will return somehow a the functions B C and E.
Close to this but not exactly i would like to accomplish this:
Given a variable somewhere in a project find all read/write operations(direct or indirect) to it.
For example:
void A()
{
char* c; // this is our little variable
B(c); // this is in the resulting list
}
void B(char* x)
{
printf("%c", x); // this is definately in the list
*x='d' // this is also in the list
C(x); // also in the list
}
void C(void* ptr)
{
ptr = something; // also in the list
}
If the above could play well with emacs i would be most delighted!
You could have a look on cscope tool (http://cscope.sourceforge.net/). It supports very large projects and a lot of different queries type :
Find this C symbol
Find this global definition
Find functions called by this function
Find functions calling this function
...
First, there is the issue of calls between different compilation units, e.g. foo.c defining function foo1 calling function bar2 defined in bar.c (and that bar2 might call a foobar defined in foo.c or in another file foofoo.c)
Then, you might consider perhaps developing a GCC plugin or a MELT extension to suit your needs.
You could also buy a costly static analyzer tool.
Emacs has cedet which might interest you.
Will this code:
inline int funcA(int a) __attribute__((always_inline))
{
return a + 1;
}
inline int funcB(int b) __attribute__((always_inline))
{
return funcA(b + 2);
}
int main()
{
return funcB(3);
}
transformed to code like this?:
int main()
{
return ((3) + 2) + 1;
}
GCC, ARM (iPhone)
Inlining function calls is not something the language requires compilers to do. It's a quality of implementation issue (QoI). But any of GCC, MSVC and clang will do it. Of course, you have to enable optimization.
For instance
# clang++ -cc1 -emit-llvm -O2 -o - main.cpp
define i32 #main() nounwind readnone {
entry:
ret i32 6
}
There are no guarantees when using inline. It serves merely as a hint to the compiler (which in many (not all) cases have more heuristics and better understanding of the impact of inlining than the programmer).
Not necessarily. It depend's on the compiler and settings I guess. In fact in C++ for example it's not even guaranteed that this
inline int funcA(int a)
{
return a + 1;
}
int main()
{
return funcA(3);
}
will get transformed into this
int main()
{
return 3 + 1;
}
inline is just the hint for the compiler. The compiler can ignore it.