Even though I always think you're probably a bit obnoxious when I start the video, it always turns out not to be the case at all. You explain every concept clearly and without "bloating" the video length and I very much enjoy the diversity of your content.
Nice video, very informative. You have produced what may be the most intelligent and easy to follow programming tutorial channel on you tube. A few years ago, while tinkering with pointers, I concluded that a function pointer was the memory address of the first instruction of the function. The disassembly that you showed us confirmed my previous conclusion: thanks.
In C you could create a struct with one so you could specify a function for an object (like a C++ class function). In my Deluxe Pacman game the library I used for the game has a sort function where you provide a function for it to use for your sorting. I used it to sort dirty rectangles (areas of the screen that changed and needed updating rather than page flipping etc, MUCH MUCH faster, it's too bad it isn't used much anymore). So my game only redraws areas that actually change each frame. Anyhow, great video. You explained these really nicely! Been working on procedural roguelike dungeon generation lately.
Dirty rectangles! Your graphics programming skills are fantastic Neil :) I think we lost a lot when everything moved to modern GPU libraries! Certainly nice to have DirectX render for us too! Me and NetHack go waaay back! Roguelikes are great fun :)
Awesome video, the only concern I have with it are the colours choices, those highlights in blue with a dark background don't really pop out, but the content is really good
C# equivilent of a function pointer once proved extremely useful for me in a college project We were supposed to write a program on the console with a menu, since it was(still is by the time of this message) the first year everyone was using switch case I was too lazy to write 7 cases so I implemented a dictionary of delegates(function pointers) with the console cmd as the key and the delegate as the value so it was automatically called based upon the user input. It was so much fun.
This is super cool!! I'm a CS student and they started us on C++, and I really took a liking to it. Lately I haven't been doing anything in it, and it just feels good to learn something cool like this in a language that I like. Thanks :)
Function pointers in their own are fine as you'll find them being used a lot in the background and they allow for concepts like the strategy pattern. It's just the level of abstraction that matters. If you expose them in application level as an mutable reference value, it's obvious you will run into issues. Even Vtables and lambdas are based on fn ptrs. Lambdas are pointing to a member function that can be invoked with the capture as context. It wasn't mentioned, but there's also a small difference in mem fn ptrs and ordinary fn ptrs, especially the way they are being invoked (unless working with std::invoke). I've seen some devs using fn ptrs to JIT compile functions into the application in order to escape long compile times or optimize certain parts. As another interesting topic, I'll suggest coroutines. Only a small proportion of people know how these actually work. It would be interesting to show how these state machines are implemented on assembly level.
Dude I enjoy and learn a lot from your videos. I watched your branchless video and started applying that to my work, thank you. Keep doing you and making videos.
This is a pretty powerful technique and ability. It's extremely useful in game hacking, function pointers are used to call internal game functions if you know their address in process and their prototype. Basically you can invoke any function in the given process for whatever you want to achieve, and that opens doors for many things to be done.
Another great video! Also, that weird syntax thing was very sensible when I tried to look at assembly and tried to think how compiler will know what I am doing, thought to emphasize that for anyone finding it weird
@Vendicar Kahn That will be more convenient yeah, though at same time that syntax just informs compiler what to expect and which registers to use to put in arguments and all, and that "*" to inform of it to be pointer. And functions are natively pointer, so we don't need & and all
O my.... Super!, Thank You, Your examples explain me clearly why function pointers are needed :) I read a lot about that problem, but not everybody could explain that with easy examples why they are useful, I was thinking that this is old technique from 90' where C was only used . I was thinking that function pointers have no sense where I can cal functions directly. But now I see I can add functions in to arrays and group them for easier use. :D
What's a Creel? Thanks! Really good video I learnt a lot. I only found this channel recently but I’m absolutely loving it, my favorites computer science channel!
My first use of function pointers was for a turn-based game, where each turn had multiple phases. Each phase would enable certain interactions and then wait for a callback from the currently active player, which could either be a user input event or an AI decision. I was mighty proud of my C# delegate solution that let me both store the next phase and do the callback in just one parameter, as trivial of a usage that was. And soon after it turned into my first experience with how messy event-driven programming can get if it isn't planned carefully.
To extend your example, function pointers are useful for lazy loading of DLLs/shared libraries. Very convenient if you are shipping code to customers and some of them want to read data from a queue while others read only from files and don't have the queue libraries. And it can all be wrapped into a new static library so existing code hardly changes. Halving the number of builds is useful when you already ship to customers on Windows and various Linux/Unix flavours.
Great video! A little suggestion though, the blue text on the black background can be a bit unreadable when sun is shining on your screen. Keep up the good work! :)
What do you mean by "supposedly kinda give you behaviour "polymorphism""? I mean I'm aware function pointers can be bad for a number of reasons but isn't it objective that they allow polymorphism?
Daaaaang, I've been programming (solely as a hobbyist) on and off for 20 years and I'm just now hearing about this? I can think of *multiple* uses for this. One of which I could apply to something I coded a couple years ago (though I'm not sure if the particular language supports function pointers).
Great video, thanks! Not sure if this has been asked already, but did you forget to dereference the dest parameter inside each calculator function in order to update the variable to which it points in the caller context?
Hey, great video! Very informative! On another note, I wanted to ask what you think of RISC-V, especially about its (apparent) lack of CMOV/SIMD features and its vector extensions.
Depends on the semantics/standard you're using. Any recent(ish) C/CPP standard should take that without a syntax error. Might as well add an & to the Add just in case you feel pedantic (and more technically correct). int (*myPtr)(int, int) = &Add;
@@SimGunther After several years, I started to use &func, since it feels like the code is a little more expressive that way. You can immediately see I'm taking the address of something.
I recently hit a challenge trying to hack extra functionality into a GUI element defined as a class (wxWidgets) and hit a problem trying to use a function pointer to a class method - that there was no simple way to pass a 'this' pointer into the function, and obviously the compiler knew this so refused to compile - although there seemed to be some way to do this that I couldn't work out. So I ended up multiple-inheriting in an extra class with a virtual function and using a pointer to that extra class object instead. Any chance of a discussion of how function pointers can relate to class methods and the difference of how a virtual method works compared to the function pointer?
COM and related technologies also rely heavily on function pointers. If I understand it correctly, a COM object is basically a table of function pointers in the order of the COM interface.
One neet thing of function pointers that is not mentioned here is encrypted functions or mutable code, you can actually cast raw bytes into a function using some tricks, and these bytes can be freely mutated, you can even receive different bytes from another source and cast them into a runnable functions.
I think one of the entries in the obfuscated c contest had been a hello world program but main wasn't an int function, nor any function, but an int array with PDP-11 (or some other architecture) opcodes. I rewrote it under DOS and turbo C++ (mov Al, 9, int 21 and everything) and it worked, too.
Nice Video! One thing I'd love to know (and I'm sure if it's possible you'd know it because you love such low level hacky stuff), is there *any* way to get the function pointer for the actually used implementation of a virtual function at runtime, and then call it directly with that function pointer bypassing the virtual function table lookup, also making it possible to read the machine code of that virtual function? Since the pointer would not change for a specific object, I feel like it should be possible, somehow, in some very hacky way.
Can function pointers aid in branchless programming? If given 3 function pointers all with the same return type and parameters with the first and second function pointers set to different functions, could we use a cmovl into the third function pointer and execute that. Or will this just reduce the benefits of branch prediction made by the CPU?
Pleased that you mentioned lambdas in this context. Please prefer std::function (from ) over C-ish function pointers as it makes life much easier for you and for everyone reading your code, as well as solving all kinds of arcane implementation issues.
Pointers to functions are so friggin cool. So are pointers. Of course, if you have some general understanding how you go about doing things in most any assembly language, then you wonder what the big stinking deal is with pointers.
You should add a disclaimer saying that you shouldn't be shuffling things like that. First because it is undefined behaviour (standard requires the comparison to always return the same results), second because while in practice no implementation will cause dangerous UB, it can take a long time to sort with some algorithms, and third because do you really want to do the same thing as Microsoft browser's choice screen? Also in case it wasn't obvious, it's not even good shuffling, and it depends on the underlying sort implementation.
I didn't know you could get the bytecode of the function like that! Sometimes I wonder if someone's ever made a simple CLI bytecode executer given stuff like this >:)
You can allocate memory with VirtualAlloc, then put the machine code bytes into that memory space, mark the page executable with VirtualProtect, point a function pointer to it and execute.
@@phizc Same what i did :) wrote asm code, compiled it in small binary format (without exe) and loaded it into new memory page that has rights to execute code and it worked 🙂
Actually when using typedefs you can just write: typedef int BinaryOperator(int, int); and then: BinaryOperator* Oper1 = Add; In my opinion it's way cleaner than typedef int (*BinaryOperator).
In my 40 year career as a software engineer, I never saw a need to go to the extra expense of using function pointers. Data pointers can be useful, but if it's not required to use a pointer, don't
Great video! Got introduced to your channel via your branchless programming video, super interesting stuff, thanks! Wanted to point out (nitpick) that the shuffling method @ 6:30 I believe is potentially non-compliant to strict weak ordering required by STL sort algorithm. It will likely compile and work as intended, and a segfault would be difficult to replicate, but I guess it's still a potential bug. Maybe the SO thread: stackoverflow.com/a/45492866 could help clarify the issue.
You should probably mention that using some random result in a compare function has a few problems. The results are not even random. This is often called the Microsoft Shuffle and there are explanations why this is bad on the web. Other than that, great video!
Personally, I avoid switch as the plague. The huge issue I see with them is that: 1) they don't have a signature and thus can do whatever inside each case; 2) they bind implicitly to everything in context and of course 3) people miss the "break" unintentionally (bad) or intentionally (how not to see it also as bad?). Normally use dictionaries rather than arrays for supporting the selection, so the keys can be non-integral, etc.
@Vendicar Kahn ah yes, I'm sure you can create a better language... Did you do a course on how to actually build a new language from scratch? Probably not, let me tell you it's not easy...
1:45 That part is for valid reason function is represent just address to be called so information of how it should be called must be preserved. As if it was declaration of function once again. Not only that In C - function names in output executable remain unchanged, can't be overloaded by other functions same name but different parameter list or return value, there can be only one name in executable, in C++ not only there are namespaces but also classes, result name of function vary depending on it's belonging, on parameters, also vary depending on compiler, different compilers make different naming convention. This created C a mess.. and actually im bit dissapointed by what C++ 11 and further focused on. Instead of standardize this once for good and standardize library packaging it focused on templates. Most important problem of C++ comparing to Rust, Python or other higher level languages are LINKING problems. problems not with API but ABI this kind of stuff. C kept it simple C++ not. Not to mention some compilers put _underscore before "extern" C function names some not. You have to know that if you want to call functions from library. Keep compiled executable same naming convention as libraries But i digreess.. Compiler must know full parameter list to know what precise type of function it will point to. Normally in C it would be enough to call it by name. Although syntax for that is bit odd. Star * before name also is odd but makes a lot of sense from compler point of view. It's almost same syntax as for definition of pointer int *myPointer = &variable; Except there is no address extraction of function since functions are adddressses themselfs. There is no other values represented by these except literall address of code to be called. Compiler depending on what type of function its how should be called pushes parameters on stack or into registers so have to keep that information, function pointer must be declared almost as if it was function declaration once again. This is what i like in C it just makes so much logical sense, it's so simple on one hand what happens next LINKER is bit of mess. never standardized. Thanks for tutorial, i had bit of brake of programing, used function pointers a lot, mostly to create mine own versins of handlers of console, of printf and stuff like that depending on what kind of UI user called but also to allow call it in chain. TO create events, to handle asychronious algorithms etc. It's something i keep forgeting, not to mention Borland C++ and Ecere SDK and also Microsoft created these getters and setters functions overloading, virtual functions in class, static ones all that.. friend class, all that C++ stuff gets really complicated comparing to pure C, and functions pointers get very handy to merge these two worlds. Handle events, hooks so on. Wish C++ make it much simpler. SO you could call any C++ library from code written in pure ASEMBLY knowing preciselly rules of C++ naming conventions across the board no matter what kind of compiler made these LLVM, GCC, Microsoft VC++. This is an issue mostly on Linux since WIndows API is mostly pure C. Linux is also but there is not so much in kernel. If LINKER get standardized, library packeging like good old days of DevC++ devpacks easy to install easy to maitain, there would be no Python or Rust, you would have just headers, some def,lib or whatever definition for compiler/linker to let know what type of CPU functions are provided for what calling convention so on.. and wuala. Now it's same you have to grab libraries compiled with same compiler you use. It's not big deal unless you compile it on different platforms using different compilers each time. If this was standardized?! It's by JIT compilers of high level languages and high level language provides appropriate library for your platform. Or as old PHP in form of precompiled extensions. Compiled same compiler as PHP runtime, for same platform you run. That have to be figured out somehow. I sick and tired of templates, enough of this toolkit nonsense.. Two most complicated in C++ are function pointers and linking issues. Why am i even writing SO MANY WORD here? :/ SORRY
Actually no, if you put a function pointer against a lambda it wouldnt end well for the lambda. The function pointer would have turned that lambda into an infinite loop on an untracked thread before the compiler had even loaded std template code for the lambda.
in the phenom II benchmark my ryzen 5 1600 did this score: #1 73.44 BIPS #2 80.31 BIPS #3 80.19 BIPS #4 234.4 BIPS #5 79.24 BIPS #6 163.4 BIPS #7 21.4 BIPS all of them single thread
You're not that far off. Every virtual member function / abstract method saves a (hidden) function pointer (yes, even in java), which is THE way of overwriting functions/methods via inheritance. The function pointer of the object gets written once when you instantiate the object, it points to the appropriate code address where the function implementation for that specific class is. So, the object hidden behind a pointer doesn't really know which type it is, it just knows which code to call. Keep in mind, that your object size will increase by sizeof(void*) with each virtual member function you have.
Please stop using function pointers and vtables. I am a binary security engineer and code that uses any form of function pointer is not only insecure it is low performance. There is nothing wrong with polymorphism as an architectural aid, but there is no reason for the polymorphism to occur at runtime. Please do all polymorphism at compile time and (all else being equal) your applications will be far more secure and performant. There is never any good reason for a function pointer within the application code module space and to the greatest extent possible all code should exist within the applications modules space (i.e. prefer static linking over runtime linking).
You're like a code angel, delivering the salvation of code that I didn't know I needed, exactly when I needed it most.
Ha! Thank you for watching :)
Even though I always think you're probably a bit obnoxious when I start the video, it always turns out not to be the case at all. You explain every concept clearly and without "bloating" the video length and I very much enjoy the diversity of your content.
FANTASTIC video. I like the more well known concepts that you cover since I always learn a bit of information I never did. Awesome stuff!
I'm glad you liked it! Thank you for watching :)
I learned more in depth about C++ from your channel than I did from anywhere else.
Thank you so much for your time and efforts!
That's great! Thank you for watching :)
Nice video, very informative. You have produced what may be the most intelligent and easy to follow programming tutorial channel on you tube. A few years ago, while tinkering with pointers, I concluded that a function pointer was the memory address of the first instruction of the function. The disassembly that you showed us confirmed my previous conclusion: thanks.
Cheers mate! It's amazing how simple these things are under the hood :)
In C you could create a struct with one so you could specify a function for an object (like a C++ class function). In my Deluxe Pacman game the library I used for the game has a sort function where you provide a function for it to use for your sorting. I used it to sort dirty rectangles (areas of the screen that changed and needed updating rather than page flipping etc, MUCH MUCH faster, it's too bad it isn't used much anymore). So my game only redraws areas that actually change each frame.
Anyhow, great video. You explained these really nicely!
Been working on procedural roguelike dungeon generation lately.
Dirty rectangles! Your graphics programming skills are fantastic Neil :) I think we lost a lot when everything moved to modern GPU libraries! Certainly nice to have DirectX render for us too!
Me and NetHack go waaay back! Roguelikes are great fun :)
@Peace Roasted
Really enjoying this content. Upbeat, clear communication, great organization, great visualizations. Cheers fella, appreciated.
Awesome video, the only concern I have with it are the colours choices, those highlights in blue with a dark background don't really pop out, but the content is really good
Amazing, wish there will be more contents about C++, and DirectX, CUDA or other similar stuff, you make all the concepts really easy to follow.
C# equivilent of a function pointer once proved extremely useful for me in a college project
We were supposed to write a program on the console with a menu, since it was(still is by the time of this message) the first year everyone was using switch case
I was too lazy to write 7 cases so I implemented a dictionary of delegates(function pointers) with the console cmd as the key and the delegate as the value so it was automatically called based upon the user input.
It was so much fun.
This is super cool!! I'm a CS student and they started us on C++, and I really took a liking to it. Lately I haven't been doing anything in it, and it just feels good to learn something cool like this in a language that I like. Thanks :)
Function pointers in their own are fine as you'll find them being used a lot in the background and they allow for concepts like the strategy pattern. It's just the level of abstraction that matters. If you expose them in application level as an mutable reference value, it's obvious you will run into issues. Even Vtables and lambdas are based on fn ptrs. Lambdas are pointing to a member function that can be invoked with the capture as context. It wasn't mentioned, but there's also a small difference in mem fn ptrs and ordinary fn ptrs, especially the way they are being invoked (unless working with std::invoke).
I've seen some devs using fn ptrs to JIT compile functions into the application in order to escape long compile times or optimize certain parts.
As another interesting topic, I'll suggest coroutines. Only a small proportion of people know how these actually work. It would be interesting to show how these state machines are implemented on assembly level.
Great suggestion mate! Cheers for sharing, and cheers for watching :)
Coroutines in which language?
Dude I enjoy and learn a lot from your videos. I watched your branchless video and started applying that to my work, thank you. Keep doing you and making videos.
That's great mate! Thanks for watching :)
This is a pretty powerful technique and ability. It's extremely useful in game hacking, function pointers are used to call internal game functions if you know their address in process and their prototype. Basically you can invoke any function in the given process for whatever you want to achieve, and that opens doors for many things to be done.
Another great video! Also, that weird syntax thing was very sensible when I tried to look at assembly and tried to think how compiler will know what I am doing, thought to emphasize that for anyone finding it weird
@Vendicar Kahn That will be more convenient yeah, though at same time that syntax just informs compiler what to expect and which registers to use to put in arguments and all, and that "*" to inform of it to be pointer. And functions are natively pointer, so we don't need & and all
O my.... Super!, Thank You, Your examples explain me clearly why function pointers are needed :) I read a lot about that problem, but not everybody could explain that with easy examples why they are useful, I was thinking that this is old technique from 90' where C was only used . I was thinking that function pointers have no sense where I can cal functions directly. But now I see I can add functions in to arrays and group them for easier use. :D
Chris you the man these things have boggled my mind for a long time, especially the syntax, impressive looking on screen but just naff. Thanks pal
Glad you liked this video! Thanks for watching mate :)
Very Nice dude! Really liked the tutorial, GREAT Guide you made today!
Cheers Chris, your vids always cheer me up bro!
ooh i just found your channel and im early to a video nice :D can't wait to see yiour amazing content
Welcome aboard mate! Thanks for stopping by :)
What's a Creel? Thanks! Really good video I learnt a lot. I only found this channel recently but I’m absolutely loving it, my favorites computer science channel!
I really don't want a sad compiler! Thanks man, made me laugh
My first use of function pointers was for a turn-based game, where each turn had multiple phases. Each phase would enable certain interactions and then wait for a callback from the currently active player, which could either be a user input event or an AI decision. I was mighty proud of my C# delegate solution that let me both store the next phase and do the callback in just one parameter, as trivial of a usage that was.
And soon after it turned into my first experience with how messy event-driven programming can get if it isn't planned carefully.
3:40 I had an STD transform once. Got it sorted at the clinic no problems.
To extend your example, function pointers are useful for lazy loading of DLLs/shared libraries. Very convenient if you are shipping code to customers and some of them want to read data from a queue while others read only from files and don't have the queue libraries. And it can all be wrapped into a new static library so existing code hardly changes.
Halving the number of builds is useful when you already ship to customers on Windows and various Linux/Unix flavours.
Great point!! Cheers for sharing mate, and cheers for watching :)
All hail our glorious mullet man!
Great video! A little suggestion though, the blue text on the black background can be a bit unreadable when sun is shining on your screen. Keep up the good work! :)
Oh, yep. Thank you for the suggestion and thanks for watching :)
Another great video that std::hex thing was cool AF. i was once creating my own objdump for some reason and this could have helped a lot there. Thanks
Welcome mate, thanks for stopping by :)
Such videos are very interresting. and just very educating. awesome.
Function Pointers: wormholes in disguise that supposedly kinda give you behavior "polymorphism" that can't be easily optimized/inlined by the compiler
That's certainly true! The compiler can't really inline when we use these things. Cheers for watching :)
What do you mean by "supposedly kinda give you behaviour "polymorphism""? I mean I'm aware function pointers can be bad for a number of reasons but isn't it objective that they allow polymorphism?
Daaaaang, I've been programming (solely as a hobbyist) on and off for 20 years and I'm just now hearing about this?
I can think of *multiple* uses for this. One of which I could apply to something I coded a couple years ago (though I'm not sure if the particular language supports function pointers).
As usual, fantastic video.
Really informative! Waiting for more videos like these :)
Cheers mate, thanks for watching :)
Great video, thanks!
Not sure if this has been asked already, but did you forget to dereference the dest parameter inside each calculator function in order to update the variable to which it points in the caller context?
Nice video! My only suggestion is that maybe you should put C++ in the title.
Excellent suggestion! I've updated the title :)
I'm a bit out of the loop but why would I use function pointers in c++ when there are already lambdas.
Hey, great video! Very informative! On another note, I wanted to ask what you think of RISC-V, especially about its (apparent) lack of CMOV/SIMD features and its vector extensions.
1:17 I'm not sure what this is. What's that = Add part at the end? Looks like a syntax error:
int (*myPtr)(int, int) = Add;
Depends on the semantics/standard you're using. Any recent(ish) C/CPP standard should take that without a syntax error. Might as well add an & to the Add just in case you feel pedantic (and more technically correct).
int (*myPtr)(int, int) = &Add;
@@SimGunther After several years, I started to use &func, since it feels like the code is a little more expressive that way. You can immediately see I'm taking the address of something.
Yes, sorry, it's just the quick way to assign the pointer to Add function.
Absolutely amazing and useful. Thanks!
I recently hit a challenge trying to hack extra functionality into a GUI element defined as a class (wxWidgets) and hit a problem trying to use a function pointer to a class method - that there was no simple way to pass a 'this' pointer into the function, and obviously the compiler knew this so refused to compile - although there seemed to be some way to do this that I couldn't work out. So I ended up multiple-inheriting in an extra class with a virtual function and using a pointer to that extra class object instead. Any chance of a discussion of how function pointers can relate to class methods and the difference of how a virtual method works compared to the function pointer?
never programmed c/c++. never did C windows programming. Still, the conclusion is really cool.
COM and related technologies also rely heavily on function pointers. If I understand it correctly, a COM object is basically a table of function pointers in the order of the COM interface.
One neet thing of function pointers that is not mentioned here is encrypted functions or mutable code, you can actually cast raw bytes into a function using some tricks, and these bytes can be freely mutated, you can even receive different bytes from another source and cast them into a runnable functions.
That's self-modifying-code! I looove it! Hopefully I can vid on this topic one day. Cheers for watching :)
I think one of the entries in the obfuscated c contest had been a hello world program but main wasn't an int function, nor any function, but an int array with PDP-11 (or some other architecture) opcodes. I rewrote it under DOS and turbo C++ (mov Al, 9, int 21 and everything) and it worked, too.
When i think about how easy and straightforward this is to do in Python... Probably why i could never quite get my head around C++.
you can, just keep at it
Nice Video! One thing I'd love to know (and I'm sure if it's possible you'd know it because you love such low level hacky stuff), is there *any* way to get the function pointer for the actually used implementation of a virtual function at runtime, and then call it directly with that function pointer bypassing the virtual function table lookup, also making it possible to read the machine code of that virtual function? Since the pointer would not change for a specific object, I feel like it should be possible, somehow, in some very hacky way.
Great video!
Can function pointers aid in branchless programming?
If given 3 function pointers all with the same return type and parameters with the first and second function pointers set to different functions, could we use a cmovl into the third function pointer and execute that. Or will this just reduce the benefits of branch prediction made by the CPU?
Pleased that you mentioned lambdas in this context. Please prefer std::function (from ) over C-ish function pointers as it makes life much easier for you and for everyone reading your code, as well as solving all kinds of arcane implementation issues.
Although (unless you're using recursion) you can usually just:
auto myFn = []() { stuff; };
Is the calling convention stored alongside the function pointer type?
Pointers to functions are so friggin cool. So are pointers. Of course, if you have some general understanding how you go about doing things in most any assembly language, then you wonder what the big stinking deal is with pointers.
Good topic.
idea for a video: risc-v? What do you think about it, could we still highly optimize code using only these?
can someone explain how lea eax, [rcx + rdx] returns a+b?
Personally I love function pointers as a concept.
you made my day :)
You should add a disclaimer saying that you shouldn't be shuffling things like that. First because it is undefined behaviour (standard requires the comparison to always return the same results), second because while in practice no implementation will cause dangerous UB, it can take a long time to sort with some algorithms, and third because do you really want to do the same thing as Microsoft browser's choice screen?
Also in case it wasn't obvious, it's not even good shuffling, and it depends on the underlying sort implementation.
Hey that dark blue color is not very visible on black background
Hm... It may seem like an obvious question but. Isn't function prototyping basically a declaration of a function pointer then?
Agner Fog is using it for dispatch :-)
I didn't know you could get the bytecode of the function like that! Sometimes I wonder if someone's ever made a simple CLI bytecode executer given stuff like this >:)
Yeah, it's amazing how simple things are under the hood! Cheers for watching :)
You can allocate memory with VirtualAlloc, then put the machine code bytes into that memory space, mark the page executable with VirtualProtect, point a function pointer to it and execute.
@@phizc Same what i did :) wrote asm code, compiled it in small binary format (without exe) and loaded it into new memory page that has rights to execute code and it worked 🙂
You mean the Clear Interrupt command on x86?
its not like switches are compiled to jump tables anyway, right ? :)
WARNING : Playing a drinking game in which you drink every time he says “just here” may be hazardous to your health.
I NOW CANNOT GET OUT OF MY HEAD THAT THE END OF A FUNCTION CALL IS A SAD WINKY FACE PLS HELP AAAAAAAAAAAAAAA
Ha! Now that you mention it, yeah! Cheers for watching :)
can't unsee o.o
Actually when using typedefs you can just write: typedef int BinaryOperator(int, int); and then: BinaryOperator* Oper1 = Add; In my opinion it's way cleaner than typedef int (*BinaryOperator).
Awesome video!
In my 40 year career as a software engineer, I never saw a need to go to the extra expense of using function pointers. Data pointers can be useful, but if it's not required to use a pointer, don't
Now that I've accomplished watching the whole series, I feel emptyness...
Great video! Got introduced to your channel via your branchless programming video, super interesting stuff, thanks!
Wanted to point out (nitpick) that the shuffling method @ 6:30 I believe is potentially non-compliant to strict weak ordering required by STL sort algorithm. It will likely compile and work as intended, and a segfault would be difficult to replicate, but I guess it's still a potential bug.
Maybe the SO thread: stackoverflow.com/a/45492866 could help clarify the issue.
Great point mate! You are certainly correct, this method for shuffling does not comply! Cheers for sharing, and cheers for watching :)
You should probably mention that using some random result in a compare function has a few problems. The results are not even random. This is often called the Microsoft Shuffle and there are explanations why this is bad on the web. Other than that, great video!
unironically based aussie code jesus
Personally, I avoid switch as the plague. The huge issue I see with them is that: 1) they don't have a signature and thus can do whatever inside each case; 2) they bind implicitly to everything in context and of course 3) people miss the "break" unintentionally (bad) or intentionally (how not to see it also as bad?). Normally use dictionaries rather than arrays for supporting the selection, so the keys can be non-integral, etc.
@Vendicar Kahn ah yes, I'm sure you can create a better language... Did you do a course on how to actually build a new language from scratch? Probably not, let me tell you it's not easy...
Haha got me scratching my head for a few seconds. What does this have to do with opera ( [oper], in German, the word Oper means opera)
I looove Verdi :) My Deutsch is not great, aber danke schön :)
Creel is looking like Jobe from The Lawnmower Man...
1:45 That part is for valid reason function is represent just address to be called so information of how it should be called must be preserved. As if it was declaration of function once again. Not only that In C - function names in output executable remain unchanged, can't be overloaded by other functions same name but different parameter list or return value, there can be only one name in executable, in C++ not only there are namespaces but also classes, result name of function vary depending on it's belonging, on parameters, also vary depending on compiler, different compilers make different naming convention. This created C a mess.. and actually im bit dissapointed by what C++ 11 and further focused on. Instead of standardize this once for good and standardize library packaging it focused on templates. Most important problem of C++ comparing to Rust, Python or other higher level languages are LINKING problems. problems not with API but ABI this kind of stuff. C kept it simple C++ not. Not to mention some compilers put _underscore before "extern" C function names some not. You have to know that if you want to call functions from library. Keep compiled executable same naming convention as libraries But i digreess..
Compiler must know full parameter list to know what precise type of function it will point to. Normally in C it would be enough to call it by name. Although syntax for that is bit odd. Star * before name also is odd but makes a lot of sense from compler point of view. It's almost same syntax as for definition of pointer int *myPointer = &variable; Except there is no address extraction of function since functions are adddressses themselfs. There is no other values represented by these except literall address of code to be called. Compiler depending on what type of function its how should be called pushes parameters on stack or into registers so have to keep that information, function pointer must be declared almost as if it was function declaration once again. This is what i like in C it just makes so much logical sense, it's so simple on one hand what happens next LINKER is bit of mess. never standardized.
Thanks for tutorial, i had bit of brake of programing, used function pointers a lot, mostly to create mine own versins of handlers of console, of printf and stuff like that depending on what kind of UI user called but also to allow call it in chain. TO create events, to handle asychronious algorithms etc. It's something i keep forgeting, not to mention Borland C++ and Ecere SDK and also Microsoft created these getters and setters functions overloading, virtual functions in class, static ones all that.. friend class, all that C++ stuff gets really complicated comparing to pure C, and functions pointers get very handy to merge these two worlds. Handle events, hooks so on. Wish C++ make it much simpler. SO you could call any C++ library from code written in pure ASEMBLY knowing preciselly rules of C++ naming conventions across the board no matter what kind of compiler made these LLVM, GCC, Microsoft VC++. This is an issue mostly on Linux since WIndows API is mostly pure C. Linux is also but there is not so much in kernel.
If LINKER get standardized, library packeging like good old days of DevC++ devpacks easy to install easy to maitain, there would be no Python or Rust, you would have just headers, some def,lib or whatever definition for compiler/linker to let know what type of CPU functions are provided for what calling convention so on.. and wuala. Now it's same you have to grab libraries compiled with same compiler you use. It's not big deal unless you compile it on different platforms using different compilers each time. If this was standardized?! It's by JIT compilers of high level languages and high level language provides appropriate library for your platform. Or as old PHP in form of precompiled extensions. Compiled same compiler as PHP runtime, for same platform you run. That have to be figured out somehow. I sick and tired of templates, enough of this toolkit nonsense.. Two most complicated in C++ are function pointers and linking issues.
Why am i even writing SO MANY WORD here? :/ SORRY
UA-cam, your mid stream ads are dumb.
Why not use lamdas? They are more powerful and more Cpp style.
Function ptr are more of C thing.
Actually no, if you put a function pointer against a lambda it wouldnt end well for the lambda. The function pointer would have turned that lambda into an infinite loop on an untracked thread before the compiler had even loaded std template code for the lambda.
windows programming hurts my eyes with it's cryptic acronyms, I wan to go back to java.
LPCZWSTR_ALL_THE_UGLY_TYPEDEFS_NAMES_ARE_A_PAIN_TO_TYPE :D
Lmao it took me about 0.5 seconds to realize that this man is Australian :D
G'day from Oz mate :)
It is a bit like a delegate in C#.
Another use of function pointer is to
mask the actual code.
in the phenom II benchmark my ryzen 5 1600 did this score:
#1 73.44 BIPS #2 80.31 BIPS #3 80.19 BIPS #4 234.4 BIPS #5 79.24 BIPS #6 163.4 BIPS #7 21.4 BIPS all of them single thread
looks like Java's Interface.
You're not that far off. Every virtual member function / abstract method saves a (hidden) function pointer (yes, even in java), which is THE way of overwriting functions/methods via inheritance.
The function pointer of the object gets written once when you instantiate the object, it points to the appropriate code address where the function implementation for that specific class is. So, the object hidden behind a pointer doesn't really know which type it is, it just knows which code to call.
Keep in mind, that your object size will increase by sizeof(void*) with each virtual member function you have.
Please stop using function pointers and vtables. I am a binary security engineer and code that uses any form of function pointer is not only insecure it is low performance. There is nothing wrong with polymorphism as an architectural aid, but there is no reason for the polymorphism to occur at runtime. Please do all polymorphism at compile time and (all else being equal) your applications will be far more secure and performant.
There is never any good reason for a function pointer within the application code module space and to the greatest extent possible all code should exist within the applications modules space (i.e. prefer static linking over runtime linking).