Primary Purpose : Make it possible for the compiler to perform optimization.
a) Functions :
The keyword is assigned to a function in declaration of function prototype.
eg : void func() __attribute__((
void func()
{
.......
.......
}
b) Data declarations
Attributes can also be assigned to variables, and also to members of struct.
I have explained a few attributes which i found might be more of use, others are just mentioned. For detailed explanation, u can refer to the source mentioned at the end.
- Attributes in Function Declaration:
Function becomes a weak alias of another function.
(ii) always_inline
Function will always be expanded as inline, even if no optimization is specified.
(iii) const
Function does not read/write global memory. Optimizer need not make certain that global values are updated before the function is called. Helps in exploiting parallelism.
(iv) constructor
Function will be called before main is called.
(v) deprecated
Gives warning on use.
(v1) destructor
Function will be called after main has returned or exit is called.
(vii) format
(viii) format_arg
(ix) malloc
(x) no_instrument_function
(xi) noinline
Function will never be expanded as inline code.
(xii) noreturn
Function will not return to its caller. Thus, the optimizer can neglect any code that would be normally executed on the functions return.
(xiii) pure
Function does not write to global memory. Allows optimizer to perform common subexpression optimization, since global data wont change in the function.
(xiv) section
The assembly code of the function is kept in the named section instead of the default text section.
Example :
Consider a C program try.c
void try(void) __attribute__((section("mysection")));
void try()
{
int a = 0;
a = a + 10;
}
int main()
{
printf("\nIn main\n");
return 0;
}
Compile it with -S option to get the equivalent assembly code for the program.
gcc -S try.c
A try.s file will be created. You can see the new section there.
.file "try.c"
.section mysection,"ax",@progbits
.globl try
.type try, @function
try:
pushl %ebp
....
leave
ret
.size try, .-try
.section .rodata
.LC0:
.string "\nIn main\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
.....
ret
.size main, .-main
....
As you see in the above example, the function try is kept in a separate section and not in the .text section as main is.
Also the section can be viewed by readelf i.e. reading the Executable and Linkable format(ELF)
gcc try.c
readelf -a a.out | less
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
.........
[10] .init PROGBITS 08048278 000278 000017 00 AX 0 0 4
[11] .plt PROGBITS 08048290 000290 000030 04 AX 0 0 4
[12] .text PROGBITS 080482c0 0002c0 0001e0 00 AX 0 0 16
[13] mysection PROGBITS 080484a0 0004a0 000015 00 AX 0 0 1
[14] .fini PROGBITS 080484b8 0004b8 00001b 00 AX 0 0 4
[15] .rodata PROGBITS 080484d4 0004d4 000012 00 A 0 0 4
[16] .data PROGBITS 080494e8 0004e8 00000c 00 WA 0 0 4
..........
(xv) used
Compiler will generate code for the function, even if it finds that the function is not used.
(xvi) weak
- Attributes in Data Declaration:
Variable with this attribute will be aligned on amemory address that is an even multiple of the number specified for alignment.
Also default alignment can be set by using the keyword align which has no parameter, instead of aligned. It aligns the variable to largest alignment for any data item supported by hardware.
(ii) deprecated
(iii) mode
Variable with this attribute is sized to match the size of specified mode.
Now u can even declare integer of one byte :) :).. But pointer arithmetic leads to unusual results. :(
modes are : word, byte, pointer.
#include
int main()
{
int iTemp __attribute__((mode(byte)));
printf("\nSize of iTemp = %d \n",sizeof(iTemp));
}
$ gcc trymode.c
$ ./a.out
Size of iTemp = 1
(iv) nocommon
(v) packed
Variable with this attribute has the smallest alignment possible. In struct, a field with this attribute will be allocated with no space between it and the field before it.
ex :
struct record {
char id;
int var[32] __attribute__((packed));
};
The member var of struct record will start 1 byte from the start of the structure.
A struct or union with this attribute takes minimum amount of space possible. It is equivalent to the attribute being apploed to each member of it.
(vi) section
Same as for function
(vii) unused
Tells the complier that the variable may not be used and hence do not issue warnings. :D
(viii) vector_size
A variable with this size is allocated a space equal to the value specified as an argument.
ex : float try __attribute__((vector_size(32)));
Assuming float takes 4 bytes, a block of 8 float variables is created.
IMP!!!! Many things here are very architecture-specific.
Source : GCC : Complete Reference
Page No. 80
0 comments:
Post a Comment