Does inline have any effect when using const function attribute? - c

Take this function
__attribute_const__ static inline int mul(int a, int b)
{
return a * b;
}
versus this one
__attribute_const__ static int mul(int a, int b)
{
return a * b;
}
Is there a reason to use inline when using a const attribute? Does it help the compiler at all to use inline here?

None of the attributes necessarily help here, because a static function would be inlined anyway regardless of inline if the compiler so decides, and because it is a static function then the source would be present in the translation unit where it would be used, then the compiler can also see that it calculates the product of the two arguments and compilers are smart enough to conclude that the product of two arguments depends only the values of those arguments.
The inline case gets more interesting in the case of inline/extern inline. Also, the attribute case gets more interesting when the compiler cannot see the code (because the function is defined only in another translation unit), or cannot deduce its behaviour properly - for example a const function might touch some common lookup tables initialized in the beginning of the program but the compiler wouldn't be able to ensure that they will remain constant.

The inline functions are substituted where they are called (at compilation time) and the attribute const is telling the compiler that further calls to the function using the same parameters could be avoided, because the result will be the same. If you are marking the const function as inline then you are loosing the const behavior since the inline is not per se a "call" and the const optimization relays on repeated calls

Related

When is the "inline" keyword effective in C?

Well, there is no guarantee by the standard that inline functions are actually inlined; one must use macros to have 100 % guarantee. The compiler always decides which function is or is not inlined based on its own rules irrespective of the inline keyword.
Then when will the inline keyword actually have some effect to what the compiler does when using modern compilers such as the recent version of GCC?
It has a semantic effect. To simplify, a function marked inline may be defined multiple times in one program — though all definitions must be equivalent to each other — so presence of inline is required for correctness when including the function definition in headers (which is, in turn, makes the definition visible so the compiler can inline it without LTO).
Other than that, for inlining-the-optimization, "never" is a perfectly safe approximation. It probably has some effect in some compilers, but nothing worth losing sleep over, especially not without actual hard data. For example, in the following code, using Clang 3.0 or GCC 4.7, main contains the same code whether work is marked inline or not. The only difference is whether work remains as stand-alone function for other translation units to link to, or is removed.
void work(double *a, double *b) {
if (*b > *a) *a = *b;
}
void maxArray(double* x, double* y) {
for (int i = 0; i < 65536; i++) {
//if (y[i] > x[i]) x[i] = y[i];
work(x+i, y+i);
}
}
If you want to control inlining, stick to whatever pragmas or attributes your compiler provides with which to control that behaviour. For example __attribute__((always_inline)) on GCC and similar compilers. As you've mentioned, the inline keyword is often ignored depending on optimization settings, etc.

Is it possible to inline functions only with certain calls

For example, if we have function A, is it possible to tell the compiler that hey you need to inline this function at this point of the code but not do it (make a call to it) at that point.
You cannot selectively tell a compiler to inline some calls, atleast not portably.
Note that inline is just an suggestion to the compiler, the compiler may or may not obey the suggestion to inline the body of the function inline to the point of call but some conditions like One definition rules will be relaxed by the compiler for such a function.
gcc has attributes noinline and always_inline.
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
I think the requirement is not useful, and the answer to your question is: No.
However, you can achieve something to that effect by using a macro:
#define f_inline do { int i = 1 + 2; } while( 0 )
void f() {
f_inline;
}
You can now use f_inline; if you want to force the code of f to be applied in-line.
It doesn't particularly matter whether you inline function calls at all. See What does __inline__ mean ?. I would just write the function non-inlined, and let the compiler decide how to inline it optimally.
If the compiler unconditionally honors your use or non-use of the inline keyword, or if you use the gcc extensions __attribute__((__always_inline__)) and __attribute__(__noinline__)), then you can achieve what you want with a simple wrapper function:
static inline int foo_inline(int a, int b)
{
/* ... */
}
static int foo_noninline(int a, int b)
{
return foo_inline(a, b);
}
I've written it with the inline keyword, but since compilers will normally treat it just as a hint or even ignore it, you probably want the gcc attribute version.

How does const pointer arguments optimized when calling functions?

How does compilers optimizes theese 4 types of function definitions. Is there any optimization done in sense of argument passing?
int check_collision(const SDL_Rect const *A,const SDL_Rect const *B) { ... }
int check_collision(SDL_Rect const *A,SDL_Rect const *B) { ... }
int check_collision(const SDL_Rect *A, SDL_Rect const *B) { ... }
int check_collision(SDL_Rect *A, SDL_Rect *B) { ... }
And if it matters, what do you think would be the preferable way of passing read only arguments to a function in cases where these argument might inefficent to copy when calling the funcion?
Use const in any of these cases to indicate the purpose of your usage more clearly and writing more readable code, modern day compilers are efficient and smart enough to apply required optimization's whether you pass the function argument as const or not.
In short, use const in this case for readability & preventing usage errors, & not for compiler optimization,
Compiler is smart enough to take care of that.
Note that your first three declarations are effectively all the same, even if SDL_Rect is a typedef (because the const keyword never "penetrates" a typedef, as I like to put it).
The const keyword acts in different ways in different places. In this case it merely makes a (revocable) promise that check_collision will not alter or replace *A (nor A[i] for any i), nor *B (nor B[j] for any j). However, it's possible that A[i] and/or B[i] are modified by any function that your code calls, because the underlying objects may be modifiable and some other function might know how to access them. The C99 keyword "restrict" tells the compiler that this is not the case, and provides a lot of opportunities to optimize; it's usually what you want here.
C99 also adds a new use for the "static" keyword to enable certain compile-time optimizations that go above and beyond those provided by "restrict". These apply only when the pointers point to the first element of arrays whose size is at least some knowable value. (It's meant for vectorization, mainly.)
As #Als noted, it's best to start with the simplest statement of "what you mean" and only add optimization keywords if you discover that the program is taking a lot of time in some particular part(s) of the program.

Putting variable declarations in a separate function in C

Is it possible to put the variable declarations in an external function? After reading from Wikipedia that:
an inline function is a function upon which the compiler has been requested to perform inline expansion. In other words, the programmer has requested that the compiler insert the complete body of the function in every place that the function is called, rather than generating code to call the function in the one place it is defined.
I hypothesized that the following might work. It did not take long for the compiler to slap my fingers :(
inline void declaration(){
int a;
}
int main(){
declaration();
a=2;
return 0;
}
This may not be how it is done but if you want a basic idea of how you can think about what happens when you inline a function.
Imagine the compiler turning your code into something like this, then you see why it will not work.
int main(){
{
int a;
}
a=2;
return 0;
}
The call to declaration() is replaced by the contents of the function including brackets, thus int a; is declared in an inner scope and is not visible in the main function.
No, this is not possible.
What is possible, is to use a preprocessor directive #define:
#define VARBLOCK int a, b, c; char ca, cb, cc;
int main()
{
VARBLOCK;
a = 2;
}
This would be a bad practice. Also these would still be variables only available in the scope of function where it were placed, without values being shared.
No - as far as I'm aware an inline function must behave semantically equivalent to a non-inline function; it doesn't affect what counts as legal code. It's just an optimization.
In particular, you could have a variable called a in both functions, but they'd be separate variables on the stack.
(Even if you could do this, I'd suggest it would be a very bad idea in terms of readability.)
inline functions are usually just a function containing no more than about 4 lines and you would want the compiler to do the optimization you where talking about since it would be faster to do what the function does, rather than adding extra code.
Inline expansion is used to eliminate the time overhead when a function is called. It is typically used for functions that execute frequently.
So there's nothing special with the inline function, rather than it might be handled differently by the compiler. They don't share their stack with any other function, which would be the only way for main to use a variable that is created in a different scope.
So my tip is; write your functions, and treat them as you usally should. Then when you are done, inline the short ones that you use a lot.
And if you really wanna create a variable in another function, allocate it on the heap in the function and return a pointer that you save and then set to 2 (your case). :) Just remember to free the memory!
You can do this, though:
#include <stdio.h>
int* GetMyIntAddress(void)
{
static int blah = 0;
return &blah;
}
int main(void)
{
printf("%d\n", *GetMyIntAddress());
*GetMyIntAddress() = 123;
printf("%d\n", *GetMyIntAddress());
return 0;
}
blah will be a global variable defined in the scope of the GetMyIntAddress() function.
If you add inline to the definition of GetMyIntAddress(), you are risking to get multiple independent instances of blah if the inline function is used in different modules (e.g. included from a shared header file).

Does the order of C objects matter?

Does the order in which C objects appear on the file matter?
For example, in functions, if I create two functions and the one above references the other one will it work? (Yes it will, I've tried it.)
Is the same in effect for static functions, INLINE functions, etc.?
Is the same in effect for structs? What happens if I reference a struct which is defined further down on the .c file?
Is this to any extend compiler-specific? How does the compiler work in this case? Does it first scan the whole file for all declarations/definitions and then attempts to dereference functions/symbols?
First, if by "if I create two functions and the one above references the other one will it work?" you mean something like this:
int foo()
{
return bar();
}
int bar()
{
return 0;
}
Then the compiler may do educated guesses at what bar() is, but it will at least spit a warning if bar() wasn't already declared. For symbols that can't be called (like variables or types), it's an outright error if they're used before they're declared.
In C, whenever you use an identifier (and no matter the kind of the identifier: it may be a function, a variable, a type, etc.), it should be declared beforehand. The various modifiers you may add to any identifier (like you said, static, inline and all the others) have no impact on this.
Do not confuse declaration and definition. A declaration is just telling the compiler that a name exists; a definition actually tells the compiler what it is.
For instance, this is a definition:
int bar() { return 4; }
Notice how it has a body, with (simple) code inside.
This is the matching declaration:
int bar();
The compiler will gladly accept the use of a function as soon as it sees either the declaration or the definition for it. For organization reasons and better flexibility, it's often better to write declarations for all your functions at the top of your C file (or inside an included header file) then the definitions.
So, my first example should look like this:
int foo();
int bar();
int foo()
{
return bar();
}
int bar()
{
return 0;
}
With the declarations above the C code, I can change the order of the functions in any way I like.
Typically something must be defined above where you use it. You can avoid this in different ways for different situations.
For functions, just provide a prototype above where it's called and all will be well.
int trol(int a, int b);
// use trol(int, int)
int trol(int a, int b) { }
If you have two functions, a and b, and they call each other and are defined in the order of: a, b, then you must provide b's prototype above the definition of a. a's prototype is not required because it is defined above where it is used inside b. Then the compiler will have no problems.
One other special case for functions is that you can use a function without declaring it and the compiler will try to infer the signature from the call. This answer explains it pretty well I think: Must declare function prototype in C?
For structs, you can use pointers to them before they are actually defined (but you can't access any of the fields) by providing a forward declaration:
struct s;
// use s*'s
struct s { };
(The above scenario facilitates recursive data structures like linked lists and trees; you can use pointers to structs before they are fully defined because the size of any type of pointer is constant.)
It matters, because if the compiler doesn't know what the function is - it will try to 'guess' (create a default int foo() prototype with matching parameters), and if your call is incorrect - you'll have mismatches (build errors, implicit castings, whatever).
It is common practice (if not even required) to declare the function before calling it (through prototypes aka forward declarations).
For functions with variable parameter lists (like printf) you must have a forward declaration for them to work properly. For example this code will not compile:
int foo(int a)
{
b(a);
b("hello", "kitty");
}
void b(int a, ...)
{
printf("%d", a);
}
But this - will:
#include <stdio.h>
int foo(int a)
{
return b(a);
}
int b(int a)
{
return printf("%d", a);
}
(with warning about the implicit forward declaration)
So in order to avoid dealing with the order of the objects in the file - use prototyping (forward declarations) to let the compiler know what's following.
From my experience, everything in C has to be written with the referenced "object" before the reference is made. I don't think this is specific to any compiler, but maybe there are some which I haven't found. Basically, everything always has to be:
Object Declaration
...
Object Reference

Resources