A valid use of IS_ERR() macro - c

I was creating a simple driver and came across a sample code which does this
if(IS_ERR(c = class_create(THIS_MODULE, "char")))
{
...
}
I tried to know what is behind IS_ERR() and i saw this
It defines as,
...
#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
static inline long __must_check IS_ERR(const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}
and what is this 'unlikely' thing?

Reference: http://kernelnewbies.org/FAQ/LikelyUnlikely
likely() and unlikely() are compiler directives to re-arrange generated code for conditional branching in such a way that best utilizes processor's pipeline.
if(likely(condition)): This condition will be "true" in most of the cases, so compiler should arrange the branching in such a way that code under 'then' statement has least jumps and pipeline flushes.
if (unlikely(condition)): This condition will be "false" in most of the cases, so compiler should arrange the branching in such a way that code under 'else' statement has least jumps and pipeline flushes.

The definitions of unlikely() is in include/linux/compiler.h, here is one of them:
# ifndef likely
# define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
# endif
# ifndef unlikely
# define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
# endif
Those macros are optimization hints for compilers.

Related

Will the compiler allocate any memory for code disabled by macro in C language?

For example:
int main()
{
fun();//calling a fun
}
void fun(void)
{
#if 0
int a = 4;
int b = 5;
#endif
}
What is the size of the fun() function? And what is the total memory will be created for main() function?
Compilation of a C source file is done in multiple phases. The phase where the preprocessor runs is done before the phase where the code is compiled.
The "compiler" will not even see code that the preprocessor has removed; from its point of view, the function is simply
void fun(void)
{
}
Now if the function will "create memory" depends on the compiler and its optimization. For a debug build the function will probably still exist and be called. For an optimized release build the compiler might not call or even keep (generate boilerplate code for) the function.
Compilation is split into 4 stages.
Preprocessing.
Compilation.
Assembler.
Linker
Compiler performs preprocessor directives before starting the actual compilation, and in this stage conditional inclusions are performed along with others.
The #if is a conditional inclusion directive.
From C11 draft 6.10.1-3:
Preprocessing directives of the forms
#if constant-expression new-line groupopt
#elif constant-expression new-line groupopt
check whether the controlling constant expression evaluates to nonzero.
As in your code #if 0 tries to evaluate to nonzero but remains false, thereby the code within the conditional block is excluded.
The preprocessing stage can be output to stdout with -E option:
gcc -E filename.c
from the command above the output will give,
# 943 "/usr/include/stdio.h" 3 4
# 2 "filename.c" 2
void fun(void)
{
}
int main()
{
fun();
return 0;
}
As we can see the statements with the #if condition are removed during the preprocessing stage.
This directive can be used to avoid compilation of certain code block.
Now to see if there is any memory allocated by the compiler for an empty function,
filename.c:
void fun(void)
{
}
int main()
{
fun();
return 0;
}
The size command gives,
$ size a.out
text data bss dec hex filename
1171 552 8 1731 6c3 a.out
and for the code,
filename.c:
void fun(void)
{
#if 0
int a = 4;
int b = 5;
#endif
}
int main()
{
fun();
return 0;
}
The output of size command for the above code is,
$ size a.out
text data bss dec hex filename
1171 552 8 1731 6c3 a.out
As seen in both cases memory allocated is same by which can conclude that the compiler does not allocate memory for the block of code disabled by macro.
According to Gcc reference:
The simplest sort of conditional is
#ifdef MACRO
controlled text
#endif /* MACRO */
This block is called a conditional group. controlled text will be
included in the output of the preprocessor if and only if MACRO is
defined. We say that the conditional succeeds if MACRO is defined,
fails if it is not.
The controlled text inside of a conditional can include preprocessing
directives. They are executed only if the conditional succeeds. You
can nest conditional groups inside other conditional groups, but they
must be completely nested. In other words, ‘#endif’ always matches the
nearest ‘#ifdef’ (or ‘#ifndef’, or ‘#if’). Also, you cannot start a
conditional group in one file and end it in another.
Even if a conditional fails, the controlled text inside it is still
run through initial transformations and tokenization. Therefore, it
must all be lexically valid C. Normally the only way this matters is
that all comments and string literals inside a failing conditional
group must still be properly ended.
The comment following the ‘#endif’ is not required, but it is a good
practice if there is a lot of controlled text, because it helps people
match the ‘#endif’ to the corresponding ‘#ifdef’. Older programs
sometimes put MACRO directly after the ‘#endif’ without enclosing it
in a comment. This is invalid code according to the C standard. CPP
accepts it with a warning. It never affects which ‘#ifndef’ the
‘#endif’ matches.
Sometimes you wish to use some code if a macro is not defined. You can
do this by writing ‘#ifndef’ instead of ‘#ifdef’. One common use of
‘#ifndef’ is to include code only the first time a header file is
included.

if 0 is compiled in c program

I'm trying to removed unused code from my program - I can't delete the code for now, I just want to disable it for a start.
Let's say that I have the following code:
if (cond){
doSomething()
}
and cond is always false so doSomething is never called.
I want to do something like:
#define REMOVE_UNUSED_CODE 0
if (cond && REMOVE_UNUSED_CODE){
doSomething()
}
Now this is obvious to us (and hopefully for the compiler) that this code is unused.
Will the compiler remove all this if condition or it will leave it and never get in?
P.S.: I can't use #if 0 for this purpose
GCC will explicitly remove conditional blocks that have a constant expression controlling them, and the GNU coding standards explicitly recommend that you take advantage of this, instead of using cruder methods such as relying on the preprocessor. Although using preprocessor #if may seem more efficient because it removes code at an earlier stage, in practice modern optimizers work best when you give them as much information as possible (and of course it makes your program cleaner and more consistent if you can avoid adding a phase-separation dependency at a point where it isn't necessary).
Decisions like this are very, very easy for a modern compiler to make - even the very simplistic TCC will perform some amount of dead-code elimination; powerful systems like LLVM and GCC will spot this, and also much more complex cases that you, as a human reader, might miss (by tracing the lifetime and modification of variables beyond simply looking at single points).
This is in addition to other advantages of full compilation, like the fact that your code within the if will be checked for errors (whereas #if is more useful for removing code that would be erroneous on your current system, like references to nonexistent platform functions).
Try
#ifndef REMOVE_UNUSED_CODE
if (cond) {
doSomething();
}
#endif
Instead.
Don't forget to do a
#define REMOVE_UNUSED_CODE
somewhere.
The answer depends on the implementation of the compiler. You should never depend on this.
Instead be explicit:
#define REMOVE_UNUSED_CODE 0
if (cond && REMOVE_UNUSED_CODE){
#ifndef REMOVE_UNUSED_CODE
doSomething()
#endif
}
Looking at this snippet of your code
#define REMOVE_UNUSED_CODE 0
if(cond && REMOVE_UNUSED_CODE)
{
doSomething();
}
REMOVE_UNUSED_CODE is replaced with 0 by preprocessor before compilation.
So if(cond && 0) will always be evaluated as false and will never be executed. So you can say, irrespective of what cond is, it will always be false.
So I'd rather prefer it doing this way:
//#define REMOVE_UNUSED_CODE 0
#ifdef REMOVE_UNUSED_CODE
if(cond)
{
doSomething();
}
#endif
You should not do it that way:
Suppose you have a function bool f(void* input) with side effects.
Then with
if( f(pointer) && false ) { ... }
the body is not evaluated, but f should be.
In the case of
if( false && f(pointer) ) { ... }
f is not evaluated because of the short-cut rule of the &&operator.
If you use
#define REMOVE_UNUSED_CODE
#ifndef REMOVE_UNUSED_CODE
if( f(pointer) && false ) { }
#endif
the whole code is not even compiled in and will never be executed.
Not a direct answer, but may be helpful. There are compiler-specific intrinsics to do code removal.
For MSVC, it is __assume(0)
For GCC/Clang, it is __builtin_unreachable().
Notice, however, that if you write something like:
if (cond){
__builtin_unreachable();
doSomething()
}
Your condition should never evaluate to true, otherwise behavior is undefined.
Combining both && REMOVE_UNUSED_CODE and __builtin_unreachable() ensures that your code will be removed by the compiler.

sdcc inline asm() not working

I'm using GCC (correction) SDCC with the Eclipse IDE to compile C code for an 8051 architecture embedded target. I need to insert a few NOPs for timing, and I can't get the compiler to accept inline assembly code.
With __asm__ ("; This is a comment\nlabel:\n\tnop"); (as suggested below) or variations I get warning 112: function '__asm__' implicit declaration and then error 101: too many parameters, as if I'm trying to call an undeclared function. I've tried all other options in the SDCC manual section 3.14 also. __asm ... __endasm gives a syntax error on __asm, same with a single underbar, and combinations of whitespace, newlines, or the same line don't help.
If I'm piecing together the command line from the Makefile correctly (without the #include path), the CFLAGS on the SDCC command line are:
-Wp,-MD,$(#:%.rel=%.d),-MT,$#,-MP --disable-warning 110 -Wa,-p --model-medium
Moved from comment
In the sources of SDCC 3.1.0's lexer, I see that both _asm/_endasm and __asm/__endasm are supported. I haven't noticed yet support for __asm("string") in the parser yet.
Also in the lexer's code, the lexing type of the inline assembly token "blob" gets changed to CPP_ASM only if a property called preproc_asm is set to 0, as can be seen in sdcc/support/cpp/libcpp/lex.c:1900.
result->type = CPP_NAME;
{
struct normalize_state nst = INITIAL_NORMALIZE_STATE;
result->val.node.node = lex_identifier (pfile, buffer->cur - 1, false,
&nst);
warn_about_normalization (pfile, result, &nst);
}
/* SDCC _asm specific */
/* handle _asm ... _endasm ; */
if (result->val.node.node == pfile->spec_nodes.n__asm || result->val.node.node == pfile->spec_nodes.n__asm1)
{
if (CPP_OPTION (pfile, preproc_asm) == 0)
{
comment_start = buffer->cur;
result->type = CPP_ASM;
_sdcpp_skip_asm_block (pfile);
/* Save the _asm block as a token in its own right. */
_sdcpp_save_asm (pfile, result, comment_start, result->val.node.node == pfile->spec_nodes.n__asm);
}
result->flags |= ENTER_ASM;
}
else if (result->val.node.node == pfile->spec_nodes.n__endasm || result->val.node.node == pfile->spec_nodes.n__endasm1)
{
result->flags |= EXIT_ASM;
}
/* Convert named operators to their proper types. */
else if (result->val.node.node->flags & NODE_OPERATOR)
{
result->flags |= NAMED_OP;
result->type = (enum cpp_ttype) result->val.node.node->directive_index;
}
break;
The solution was to add #pragma preproc_asm - (or +) at the top of the file and to use the multiline __asm/__endasm blocks.
this link: http://www.crossware.com/smanuals/c8051/_t243.html
has this to say about inline assembly code
Assembler code can be embedded into your C source code in two ways:
using the #asm/#endasm preprocessor directives
using the _asm keyword
The pre-processor directives #asm and #endasm allow assembler code to be included anywhere within the C source code file, the only restriction being that it cannot be positioned within an expression. All lines between #asm and #endasm are passed straight through unmodified to the intermediate file processed by the assembler and so all of the rules for the cross assembler source code are supported.
The pre-processor directives #if, #ifdef, #ifndef, #else, #elif and #endif are valid between #asm and #endasm and so can be used to maintain the assembler code if required.
The _asm keyword can only be used within functions. It is used with following syntax:
_asm();
The string constant is passed straight through unmodified as a single line to the intermediate file processed by the assembler. Each should therefore be a valid line of assembler code.
One advantage of the _asm syntax is that it is subject to token replacement by the C preprocessor. Therefore the statement can be generated by a series of macros.
Also with the _asm syntax, the compiler supports a special construct to enable easy access to C variables. If the variable name is placed in the string contant within curly braces, the compiler replaces the variable name (and the curly braces) with the appropriate substring depending upon the location of the variable. See the following sections for more details.
The compiler generates upper case mnemonics and so if lower case is chosen for the in-line assembler code it can be clearly distinguished from the compiler generated code in the list file.
however, the correct format is: '_asm(" nop");' because a mnemonic assembly instruction cannot be the first thing on a line (that privilege is for labels)

"if " and " #if "; which one is better to use [duplicate]

This question already has answers here:
Difference between preprocessor directive #if and normal if
(3 answers)
Closed 9 years ago.
I learned that if or #if can both be used for condition checks.
As we can check conditions using if, why would we use preprocessor #if?
What difference will it make to my code if I use #if instead of if?
Which one is better to use and why?
if and #if are different things with different purposes.
If you use the if statement, the condition is evaluated at runtime, and the code for both branches exists within the compiled program. The condition can be based on runtime information, such as the state of a variable. if is for standard flow control in a program.
If you use the preprocessor's #if, the condition is evaluated at compile-time (originally this was before compile-time, but these days the preprocessor is usually part of the compiler), and the code for the false branch is not included in the compiled program. The condition can only be based on compile-time information (such as #define constants and the like). #if is for having different code for different compile-time environments (for instance, different code for compiling on Windows vs. *nix, that sort of thing).
we could not say which better to use, because one is used in the compilation phase (#if) and the other one is used in the runtime phase(if)
#if 1
printf("this code will be built\n");
#else
printf("this code will not\n");
#endif
try to build the above code with gcc -E and you will see that your compiler will generate another code containing only :
printf("this code will be build\n");
the other printf will not be present in the new code (pre processor code) and then no present in the program binary.
Conclusion: the #if is treated in the compilation phase but the normal if is treated when your program run
You can use the #if 0 in a part of your code inorder to avoid the compiler to compile it. it's like you have commented this part
example
int main(void) {
printf("this code will be build\n");
#if 0
printf("this code will not\n");
#endif
}
it's equivalent to
int main(void) {
printf("this code will be built\n");
/*
printf("this code will not\n");
*/
}
Hey both are different
#if Tests if the condition is true at the compile time.
if is evaluated at runtime.
You should use #if when the outcome of the condition is known at compile time and regular if when outcome is not known until runtime.
#if DEBUG
I know at compile time I am making a debug build
if (date == DateTime.Today)
Depends on what day it is
Some uses of #if are:
You want to put extra prints, or checks when you build a debug version of your code
you want to ensure the compiler doesn't include a .h file twice
you want to write code that will use different system calls, and depending on the system it gets compiled on use the appropriate ones.
Because all of the above are checked at compile time this means that:
The condition must be able to be evaluated at compiletime
The produced code will not contain the branches that evaluate to false, leading to smaller code, and faster, as the condition is not checked every time the program is run.
Examples:
Adding extra checks only for debug mode:
#define DEBUGLEVEL 2
#if DEBUGLEVEL > 1
printf("The value of x is: %d", x);
#end if
#if DEBUGLEVEL > 2
printf("The address of x is: %x", &x);
ASSERT(x > 100);
#end if
Ensuring header only gets included once:
#ifndef PERSON_H
#define PERSON_H
class Person{
....
};
#end if
Having different code depending on platform:
#ifdef WINDOWS
time = QueryPerformanceCounter(..);
#else
time = gettimeofday(..);
#endif

warning: unused variable

see in one code i have written
void my_function()
{
INT32 i; /* Variable for iteration */
/* If system is little-endian, store bytes in array as reverse order */
#ifdef LITTLE
{
// i m using i for operating one loop
}
#endif
/* If the system is big-endian, store bytes in array as forward order */
#ifdef BIG
{
// using i for loop
}
#endif
return;
}
by compiling this code with -Wall flag it shows
warning: unused variable ‘i’
why?
how can i remove this?
Put the declaration of i just inside the {} where you actually use it. Even better if you have C99, declare the loop variable inside the for(int i = 0, i < bound; ++i)
By defining either LITTLE or BIG. I doubt many compilers give that warning for this code when one of those symbols are defined. If you still have the warning, then you might change the second #ifdef to an #else.
I don't see any #endif anywhere -- presumably in the real code, those appear.
You need to define either BIG or LITTLE (as mentioned elsewhere).
In order to stop this happening again in the future, you can raise a specific compile-time error using the following:
#if !defined LITTLE && !defined BIG
#error You haven't defined one of your macro names
#endif
Alternatively, you could include i only when using either code block by surrounding it with #if defined as well:
#if defined LITTLE || defined BIG
INT32 i;
#endif
In both cases, note the keyword to use is #if not #ifdef or #ifndef.
You do not have to declare the iteration number. Just do it in your for statement.
for(int i = 0; i < 6; i++){
// insert loop code here
}
hey i got the answer...
see BIG & LITTLE are preposser flag & they are given at compile time.
when i was compiling my project with make file i was giving this flag at compile time but while testing each individual file i was compiling like
gcc -Wall -c filename.c
This was comming because i havent given any flag so compiler going to neglet that much portion of code & i was getting warning.
gcc -Wall -c -LITTLE filename.c
works perfectly...

Resources