int check() __attribute__((warn_unused_result));
int check()
{
return 0;
}
int main()
{
check();
/*
compiler warns of not checking return value --
warning: ignoring return value of check,
declared with attribute warn_unused_result
*/
int k = check();//no warning
}
Trying to understand intricacies of Operating System and small things in C/C++ programming language & gcc. I write to learn
Monday, June 13, 2011
'warn_unused_result' attribute in gcc
Saturday, June 11, 2011
Achieivng memcpy and memmove in single function
As shown in figure there are three cases
Here:
s = source pointer
d = destination pointer
b = boundary
size = number of bytes to copy
1) d >= s+size
2) d < s
3) d < s+size
If d=s, we do not do anything. simply return
The cases 1 and 2 are trivial. In the sense, plain copying does not corrupt destination 'd' buffer. However in case '2', source 's' data will be modified.
The problem is with case 3. When we do plain copy, the source data buffer at the tail gets corrupted and destination 'd' will not have replica of source 's'. We can avoid this by copying from the last i.e. copy from 's+size' to 'd+size' and move towards 's' and 'd'.
Here is the program. The example may be trivial however I hope this works.
#include<stdio.h>
void my_memcpy(void* src, void* dst, size_t bytes);
void my_memcpy(void* src, void* dst, size_t bytes)
{
unsigned char* s = (unsigned char*)src;
unsigned char* d = (unsigned char*)dst;
if(s == d)
{
//same
return;
}
size_t k = 0;
if(s+bytes > d)
{
//Overlapping
k = bytes;
while(k > 0)
{
d[k-1] = s[k-1];
k--;
}
return;
}
//Other cases
while(k < bytes)
{
d[k] = s[k];
k++;
}
}
int main()
{
int i[10] = {0x1234, 0x2345, 0x3456, 0x4567};
my_memcpy(i, &i[2], sizeof(int) * 4);
int j = 0;
for(;j<6;j++)
printf("%x\n", i[j]);
}
When I browsed through glibc code, it used page copy technique in case of memcpy. It tries to get page boundary and copies data in pages. This technique is quite faster for huge data. For data which are not page aligned, it does plain copy. For i386, seems like it uses inline assembly.
Thursday, June 9, 2011
'weak' attribute in gcc
Recently I came to know about gcc attributes which can be used in code for specific purpose. One of them I understood early was 'weak' attribute. A 'weak' attribute may be specified if you don want compiler to throw any error if it was unable to resolve external symbols. This is useful if you are planning to provide function or variable in near future and do not want to modify the main source at that time.
#include<stdio.h>
extern int k() __attribute__((weak));
extern int k2 __attribute__((weak));
int main()
{
if(k == NULL)
{
if(&k2 == NULL)
{
printf("No symbol k or k2 found\n");
}
}
else
{
k();
}
}
This example compiles just fine and gives no linkage error even if the symbols are not found. However if we are using those symbols we need to check NULLness of those symbols else the program will result in seg fault.