The Inline Keyword in C.
Vložit
- čas přidán 17. 08. 2020
- Patreon ➤ / jacobsorber
Courses ➤ jacobsorber.thinkific.com
Website ➤ www.jacobsorber.com
---
The Inline Keyword in C. // Inlining functions and the "inline" keyword in C have caused a significant amount of confusion over the years for students and professionals. In this video, we look into how the "inline" keyword, the "always_inline" function attribute, and compiler optimization levels impact function inlining behavior.
***
Welcome! I post videos that help you learn to program and become a more confident software developer. I cover beginner-to-advanced systems topics ranging from network programming, threads, processes, operating systems, embedded systems and others. My goal is to help you get under-the-hood and better understand how computers work and how you can use them to become stronger students and more capable professional developers.
About me: I'm a computer scientist, electrical engineer, researcher, and teacher. I specialize in embedded systems, mobile computing, sensor networks, and the Internet of Things. I teach systems and networking courses at Clemson University, where I also lead the PERSIST research lab.
More about me and what I do:
www.jacobsorber.com
people.cs.clemson.edu/~jsorber/
persist.cs.clemson.edu/
To Support the Channel:
+ like, subscribe, spread the word
+ contribute via Patreon --- [ / jacobsorber ]
+ rep the channel with nerdy merch --- [teespring.com/stores/jacob-so...]
Source code is also available to Patreon supporters. --- [jsorber-youtube-source.heroku...]
A couple other things to watch out for with inlining: 1) It usually makes executable size large because it is basically copy-pasting instructions everywhere. This can be an issue, especially in embedded systems. 2) Because there are more instructions in a given routine, the instruction cache is less likely to be able to hold everything so you might get more expensive cache misses with the increased code size.
yeah, but performance is more important than size for regular computers
In all this Javascript Framework mess thanks for choosing C!
C will always be King.
@@kermitdafrog8 rust is trying to take its crown
@@framepointer let me repeat. C will ALWAYS be King.
@@kermitdafrog8 well god damn, so be it!
@@kermitdafrog8 What about C++?
Back in the stone age, assembly was the first thing I learned. The best thing I ever did. I could then picture the code that compilers generated and instinctively know how, why and when to optimize.
The double parenthesis when using __attribute or __attribute__ are there to allow it to be "macroed" in c versions that do not support variadic macros.
Ah. That makes sense. Thanks.
can you explain it in a simpler way (more verbose)?
@@JacobSorber No problem. I love your videos keep them going :)
@@benjaminshinar9509 Basically because attributes are different per compiler you would probably want to set up macros accompanied by #ifdefs to make your code compilable by multiple compilers. However because __attribute__ takes a variable number of arguments, macros need to take a variable number of arguments too (they need to be variadic) which is not supported by all c versions/compilers. Placing double parentheses makes compilers treat the series of arguments as a single argument bypassing the need for variadic macros. I hope you understand my explanation :)
@@cyberdank3160 Thank you :)
This was missing extern inline. Instead of supplying two different implementations of the function, you can but the inline one in the header file and write an extern inline prototype in exactly one translation unit.
This behaves similar to static inline, but is better because static inline may create a copy of the function in every translation unit, assuming it isn't inlined, whiles the extern inline version would, if it isn't inlined, always fall back on the extern inline version, which is only ommited in one translation unit.
Hi Jacob, I found your video while searching material to prepare for a technical interview for an embedded kind of position. I learned a lot and I'm happy to explore your channel. Thank you very much for your hard work.
Jacob, I love all of your content that allows us to get under the hood! Is there a list of resources (besides you CZcams videos) that you would highly recommend?
Thank you for your time, effort and content, I love your videos! By the way... Nice t-shirt :)
Thanks!
It has been helpful, indeed. Thank you! You always explain yourself very clear
Love your content!! This series is great :)
Glad you enjoy it!
Thank you for this video Jacob.
to put an irish tone in it, your content is fooking awesome
This video is great! Thanks for the thorough explanation!
My pleasure!
solid video about inline! I learned something new!
Your videos are awesome Jacob ! Don't ever get discouraged by low subscriber count, we like your content ! 😄
Any plans on making videos on how compiler optimization works ? if not will you please suggest some resources to understand the same ?
Thanks! Not discouraged. In fact, I was just thinking, "Wow, I have 23k subscribers. Cool. I should celebrate." 🎉
I have compiler optimization on my topic list. Not sure how long it will take me to get to them (it's a solid list).
As for resources, there are good compiler books out there (Muchnick, Aho+), lots of online resources, but I think compilers themselves are one of the best teachers. You can play with different programs and see how optimizations are applied. You can check out the compiler source code and see how they are implemented. And, of course, you can try your hand at implementing your own optimizations.
@@JacobSorber Thank You! for your valuable time and suggestions . Eagerly waiting for your next video 😁
I don’t know why I’m being recommended C related videos of yours recently (maybe because I’ve googled a lot of things because I did a bit of C# recently) but they’re damn interesting, like I don’t do C (from my understanding if I would, C++ would probably be a better idea?) but it’s still fun to learn about features in languages I don’t know
The video chooses the viewer. 😀 Glad you're enjoying them.
Thanks for the video! Question - would it be better to use function-like define to enforce inlining?
Thank you for this video Jacob.
More power to this channel 🌟.
Ps. Please make a video on debugging C programs using syslog server
Thanks. I'll add syslog-based debugging to the list and see what I can do.
Hi Jacob, I inspired by your videos all the time, could you please explain the "cmake" utility?
Now THAT'S an intro!
I didn't realize this is what inline meant in C. In Pascal the inline keyword allows you to insert machine code into the executable directly (at least in Borland Turbo Pascal, anyway). That was very useful in the 386/486 days when you needed graphics routines to be as fast as possible but you didn't want to write the entire thing in straight assembly. Completely different, and interesting.
wow yes I remember that. that was a very cool feature. I whish you could do that in modern languages. but when you think about it's very close to inline in C, as it would probably just stick the assembly code at every call site.
Thanks
Inline keyword does not ensure inlining, however, it increases the probability of inlining. The compiler (at least clang do it) gives point to each function for inlining and inlines that function if it has a high point for inlining. If we declare a function as inline, it increases that point.
nice content :) thanks. Can you make series on compiler design course or operating system course?
Sure. I already have videos on a variety of operating system topics (threads, processes, IPC). And, there are definitely more to come.
I would also love to see a few topics on this channel for compiler design!
How does one use 'extern inline'? I've seen that mentioned on SO, but do not understand it.
My full preemptive multitasking routine for 4 tasks on an 8051
push A
push B
push PSW
mov A,SP
xch A,stack3
xch A,stack2
xch A,stack1
mov SP,A
pop PSW
pop B
pop A
clr PSW.5
clr TMR2CN0.7
reti
Thanks for the examples. A question: what is the use case to have two versions of the same function where one is for inlining and one is not. Seems to defeat the purpose of inline IMO. And it's confusing since having two implementations of a function is not inherently something related to the general concept of inlining.
When optimizing for speed notsize inline avoids problems with using macros example creating an and macro is easy but dangerous related to arg evaluation. Inl8ne works better without function call overhead.
The point of the inline keyword is to allow you to provide the definition (not declaration!) in header files (w/o causing multiple definition errors) so that a definition, rather than just declaration, of a function can be present in each compilation unit since the compiler needs the definition in the compilation unit to inline a function.
I mean you should be able to just define the inlined function in the header file, only once, not static. That works in c++ at least on any modern compiler (past 20 years). Having two separate implementations is definitely not a used solution by anyone of course haha, weird that you even describe it as something that some people do.
What do you think of the idea to write inline functions into the header files?
Great video! Oils you just have a look at your audio levels? I’ve my AirPods on full blast and I can’t hear a thing
CZcams seems to recommends anywhere from -13 to -15 LUFS. Would be interesting to analyse and see what the video file is producing
Jacob, thanks you for all the content! it's perfect!
I have a question: Is inline behave the same in Cpp?
I just started learning c++ in college, but according to the book the professor recommend as source, the inline in c++ is actually what you would expect: removes the call to the function. The book is extremely old thou (and hasn't been updated in years), so maybe it's not like that now a days.
@@codex8797 hi, i did some tests with cpp code and it's not so simple. it's not always inline the function...
thanks for the info bro. I guess compilers are complex beasts after all
Well, naturally, could you please make another video talking about all the things about inline?
You're going to need to be more specific.
why does including "nums.h" give a linker error "multiple definition of two"?
You cannot have multiple definitions of an identical function signature or else it is ambiguous which one should be used. I cannot see your code (so I am just making an educated guess here) but I would guess that you forgot to make one definition inline like the video showed.
I'm old and haven't done any C or C++ for many many years.... so excuse me if my knowledge is very out-of-date (I don't think C had `inline` last time I used it ;) )... `inline` definitely will inline a function in C++, yes?
I wrote some code to test the behaviour and got errors for a while. The include of nums.h into the main file (test.c) breaks the compilation, both with gcc and clang. Do you know why?
Sadly, not without more information.
@@JacobSorber sure. Just a question: do you include nums.h into the test.c file? Thanks a lot
@@OmarRampado87 No, in the example, I did not include nums.h.
In C++ but I believe its applicable to C as well, when I use delete keyword to clear a pointer memory. Then is there a way to check if the content of memory has been erased. I try to check the pointer against being nullptr but it doesnt work. So after I delete I have to force the pointer to be equal to nullptr. I was thinking is there any method to check it without doing so?
I think that if you use shared_ptr and call .reset() it will take care of the issue and will no it's not pointing anywhere.
No, in both C and C++ you are by design expected to keep track of and be responsible for all pointer values yourself. It is up to you how you choose to achieve that. In C++ you are only supposed to use 'delete' and 'delete[]' with a ptr value that you got from 'new' and 'new[]' respectively, and in both languages calling 'free' with a ptr value not returned from a previous call to 'malloc/calloc/realloc' results in undefined behavior. Note that pointers may quite reasonably have other ptr values, such as to the middle of an array or to a local variable on the stack, but using these with 'free' is still erroneous.
That said, some compilers will insert extra debugging or "intrumentation" code in your code if requested to, so that for instance the free function also will fill the memory with a predefined pattern, which then can be inspected from the debugger. This is only intended as a development help, though, and the final program code should never rely on such a feature. As a more reliable "hardening" feature of a commercial program it used to be quite common to wrap the alloc/free mechanism in your own set of such functions, tailored a bit more to the specific needs of that application. A simple alternative in C could be just #define FREE(p) (free(p), p=0) and then use FREE everywhere instead of free. Nowadays there is of course smart pointers as a good alternative in C++. One may also often consider that if one really needs to check if the pointer is still valid/allocated, then that would be a design flaw or "code smell", so should be fixed on a different level than trial and error with a debugger.
Your pointer doesn't become null after you free the memory, however the memory to which it was pointing to is returned back to the OS.
What is the editor that you use? I really need a good editor. Most just strain my eyes.
I'm currently using vscode.
@@JacobSorber oh. Thank you. Btw, your way of expression is the best. Even without crafty animations or drawing panels, it's all really easy to understand. I hope to develop coding and communication skills that are close to yours. Great job, professor.
@@darkstar4734 Thanks. Glad I could help.
And C what it is
pretty good stuff (Y)
Personally I think it's useful to learn how to read assembly to kind of get an idea of what compilers are doing with your C behind the scenes. But not really to write assembly. Because, come on. No one hand-writes assembly. Maybe it's marginally faster but 10x the effort of just writing C.
Anyone please clarify about Static inline function?
I recommend you check out my video (or some other resource) on static. All it's doing here is limiting the function to this specific translation unit.
@@JacobSorber Thanks a lot for your reply:-)static and inline both are clear...but in some functions it is used as static inline function_a....static inline (together used for one function) means?
I love that t shirt!!!
Thanks. I know where you can get one.
@@JacobSorber
first thing i did when opened the video was search for it.
the page in the shop is down, currently :(
@@JacobSorber i found it. :-).nice that you can deliver to europe!!! Viel Erfolg mit dem online-shop! :-). You are one of my favourite serious technical youtubers. I wish i had had you as teacher many years ago at university!
@@amaia6393 Super! Danke schön.
@@benjaminshinar9509 Hmmm... what URL did it send you to? Was it this one? teespring.com/stores/jacob-sorbers-store
do you have a github?
I do have a github account, but you can find source code from my videos through Patreon.
why turbo synthax and not intel %%%%%%%%%
Do the movie about stdatomic in C11
Could you explain what a translation unit is?
Have you heard of Compiler Explorrer? I asume not.
The treble hurts my ear, can you lower the treble a bit, in your later videos please?
I've made a lot of adjustments since this video posted. Are my recent videos working better for you?
@@JacobSorber it's there, the "ss.." sound hits really sharp, other than that the sound is really clear, thank you for looking into the matter.
i am a beginner and a student . i want to learn IOT .
IOT focused towards industry requirements rather than just playing with it.
(not blinking LEDs on microcontroller but instead focusing on how can we create our own microcontroller ).
so, in similar manner working on IOT,doing something that actully matter and we can innovate/produce somethting out of it .
Maybe inline functions could be used for something similar to a const of define.
I.E. "inline float return_pi() {return 3.14;}"
Good video. I personally think that "inline" should be dropped from the standard since the optimizers usually deal with it how they please anyways.
So, I guess my takeaway is: don't use the inline keyword or optimization flags, because you don't know what will actually happen.
yikes that sounds hard to maintain
somehow i have returned after over a year, and I agree with myself that yikes that sounds hare to maintain
compare the two codes:
------------------------------------------------------------------------------------------
//VERSION 1
int main(){
int n = 5;
cout
Okay, this was helpful, now I know, don't waste my time with inline, it's worthless
lost debug ability , that is not what I want
Please don't write source code where the code flow and functionality can differ based on optimization flag specified!
You're basically shooting yourself in the foot by getting the compiler to do whatever it feels like that day, and a compiler doesn't have a soul, it should just always do what you tell it to do, precisely!
Never have a static and a global (linked) function with the same name, unless you're following a strict naming specification! (And only then, make sure you declare every signature as static within the .c file, don't contaminate your headers with it.) That's called ambiguity and it's a HORRIBLY bad coding practice!
I see no reason why you shouldn't add an affix to the symbol name, eliminating ambiguity and making clear in which context it is being used.
Of course I'm not saying don't inline functions. It's a great optimization feature and you should want to use it. But only within the context of the translation unit! And use the O2 flag or higher to expect it to take effect, otherwise it'll turn the task of debugging into unneeded torture for yourself.
Personally I stay away from any compiler specific pragma's and hints, since those are usually death sentence to maintainability.
Imagine having to use a different compiler that isn't GCC or Clang, then everything breaks and you waste a lot of time working around that stuff.
Just pick a C standard and make sure all platforms you intend to run your program on have a compiler available that accepts that C standard.
Anyways make sure it'll link using just object files. The O2 optimized components should link perfectly fine with O0 optimized ones. No repeat code, no code difference at all apart from optimizations.
Hope that wasn't too ranty, but I expected better
If C was a person it was you
So, C is your favorite language, right?
@@JacobSorber return true;
really, 16min video for "inline" ?..
Yeah, I had the same thought. But, one thing led to another, and... 16 minutes later, here we are.