#BB10
ฝัง
- เผยแพร่เมื่อ 10 ก.ย. 2024
- A brief look at what namespaces and macros can do for us hobbyist coders.
► PCBWay $5 for 10 pieces www.pcbway.com
Both namespaces and macros are under-utilised by most hobbyist coders so let's change that and improve the readability and subsequent maintenance of our C++ programs.
The complete code for the demo examples can be found in the GitHub for the previous video in this series (about Code Organisation):
github.com/Ral...
► List of all my videos
(Special thanks to Michael Kurt Vogel for compiling this)
bit.ly/TH-camV...
► You can support me by buying me a coffee!
buymeacoffee.c...
► If you like this video please give it a thumbs up, share it and if you're not already subscribed please consider doing so and joining me on my Arduinite (and other μControllers) journey
My channel, GitHub and blog are here:
------------------------------------------------------------------
• / ralphbacon
• ralphbacon.blog
• github.com/Ral...
• buymeacoffee.c...
------------------------------------------------------------------
I want to give you ten thumbs up. When I started programing the Arduino, I kept coming across the xxx::yyy syntax and it just did not make since to me. I kind of figured it out enough to get on with hobby programming, but I never really understood what what going on. In ten minutes, you fixed that - thanks. Really - THANKS!!!!
Glad to have helped you out, Edward. Hang on, ten minutes... does that mean you didn't watch the _entire_ video?!? 😥
@@RalphBacon LOL - no I watched the whole thing, but I did already know how to use "define" , so I subtracted that part! And, I watch almost everything at 1.25% speed, so it goes by a little quicker.
Excellent choice for a video and excellently presented. One caveat: "using namespace std", Anybody reading texts/books on C++ will find this phrase in almost each and every code example. For that code it is not a problem, it will run as expected. The author has done this so that when the reader is diligently typing the code into her/his PC, she/he is saved the arduous task of prefixing, say, cout with "std::".Because he hasn't named any of his functions cout(). Nevertheless, the standard library have put all their code, 100s of functions and templates into the namespace std. They do this for the sake of the developer. If they hadn't done so and the developer is about to write her/his own function, she/he would have to browse through all the headers in the standard library before coming up with a name for that doesn't clash with any of the names in the standard library. So, don't get into the habit of using "using namespace". Woman up and get in the habit of writing "std::" when appropriate it really is quicker than trolling through the Standard Library.
I agree entirely with Michael Keegan. There's far too much "stuff" in the std namespace to simply write "using namespace std". I tend to specify the functions etc that I'm going to use, as in "using std::cout; using std::endl;" and so on. It can get a bit wearisome typing all those "using" statements, but it's better than hitting name clashes when you just use the whole namespace.
Cheers,
Norm.
And I too must agree. I pondered long and hard about whether I should even _mention_ the "using namespace ..." and decided not to, because the minute you do that you basically undo all the good work you've done by using a namespace. The _std_ namespace is perhaps an exception, but even now I tend to type std::xxx rather than default to its scope.
I'm a software engineer but enjoy watching beginner videos, you never know what kind of hidden gems you may find in them. Just wanted to say exceptional video, I love the effort you put into explaining why to the user. if you're a newbie reading this, you're in good hands!
Very few people put the proper amount of effort into explaining the value of the techniques they teach. I also love the emphasis on readability and organization.
The concepts explained in this video are 100% transferrable to nearly any other language and believe it or not are things I often see even the most seasoned professionals getting wrong. The bane of engineers everywhere is thinking they are more clever than they actually are so neglecting the basics like this is actually somewhat common.
It does not do you any favors, mark my words if you neglect readability you will have many frustrating days of debugging ahead of you trying to fix issues you introduced by not understanding what you wrote.
Kind words, thank you. But as we were always told at work, the next poor b***ard who has to fix this code in a year's time will probably be YOU! So make it readable!
And they were right. 😄
@@RalphBacon This is so true. On more than one occasion in my life I have been trying to work on some code that was confusing/poorly written only to realize it was me that wrote it lol. It takes a surprisingly short amount of time to completely forget the code you wrote and it looks no different than a stranger wrote it.
This was so useful. It is a much more elegant way to tidy up my code. After ~50 years as an engineer I still love learning, especially when it is so well taught. Thank you!
You're very welcome!
I think your probably the only person that’s ever been able to teach me something. Really interested in coding but fall asleep watching others videos. Don’t know what it is your doing to NOT make it so mind numbingly boring but I appreciate it.
I have a secret telepathic power and I can detect if you are 😴 feeling drowsy. Then I say something interesting to 😲wake you up.
Very informative Ralph as 'Macros' are very useful tool's to have but personally I haven't yet found a need for 'namespace' however if I do have the need for them then I can come to your tutorial...cheers.
Thanks for sharing! But give it a whirl on even a simple project and you will quickly see the benefits.
Cheese!!!!!!!!!!!!!!!!!
@@fredflintstone1 Squeak !!!!!!!!
Sir, this helps a lot! I am self-taught ? your #BB videos elevated my work on ESP projects much higher! Thank You! Regards from Ukraine~!
I'm glad it helped your coding techniques and expertise! 👍
When I first started using C, I used macros a lot, to shorten and simplify my code. But with lots of experience, I came to dislike them. I found that for anything non-trivial, you have to be too aware of what the macro does; it's not a "black box." Now, I rarely use them for anything but literals (like numeric constants). Even with numeric constants, I often use const (for example "const int BUTTON_PIN = 7;") instead.
Giving that test for a button press a human readable name is a good idea. It could have been done just as well with a function. For something nearly trivial like that condition, putting the function definition (i.e. including the body of the function) in a header file makes it easy for the compiler to inline, just like with the macro. A function tends to be less error prone than a macro.
Agreed -- "refactouring via macros" is basically what's demonstrated in the later stages of the video, which is not something I'd promote.
Yes, nowadays, I consider use of #define a code smell. The biggest problem caused is that it is a preprocessor directive, so the compiler can't see through what's happening. Helping the compiler optimise is essential for professional code and I'd agree with you on const int, or even better constexpr.
A macro is good at what it does. Look at the Arduino code behind the scenes. Lots of macros (starting with the well-known "min" function - which isn't a function, just a macro to hide the "complex" code [a ternary condition] 🤣).
I just showed that code can be substituted by a macro. Use it wisely.
I've been puzzled by namespaces since starting with Visual Studio Code a couple of years ago. Thanks for making it clear for me!
Happy to help!
Thanks Ralph, that was interesting and helpful.
Glad you enjoyed it!
I really appreciate the c++ tutorials. AS I mentioned elsewhere, I have history with this language and you are helping me understand (a little) the black magic that is c++. More of these.
No black (or any other colour) magic in C++, just a lack of understanding so I am very happy you now understand more of the magic. Oh. 😅
@@RalphBacon Perhaps not black magic, but I have been in c++ shops where the rule of thumb was that if you spend over a certain amount of time (usually double the time you spent writing the code) unsuccessfully debugging a program, you threw it away and re-wrote it. Agreed, this was before the multitude of development tools that are available came out. I spent many nights with the manual trying to figure out what punctuation or incorrect spelling was responsible. I may one day write a book of programming horror stories. I doubt anyone would want to read it. COBOL seems so simple by comparison.
i'd love if every tutorial on youtube have used namespaces, not "just install zip with library and paste my messy code and boom, it works". I also appreciate stressing such details on such lowspec yet popular platform as Arduino
I'm not sure the Arduino is so lowspec TBH. Sure, an actual Arduino board is unlikely to be used in a commercial or industrial project, but the underlying ATMega328P chip could well be used. Quite powerful.
@@RalphBacon compared to STM32, RPi-Pico or even ESP-8266 you must admit that in raw computing power (crunching numbers and driving IO lines) stands just after PIC-µcontrollers ;)
I'll admit that AVRs are powerful in terms of vesatility or just getting job done, however routine to to compute Mandelbrot fractal and display it over SPI LCD is painfully slow and i recall that Amiga 500 with bootsector Mandel routine handled that task more efficent.
Depends on what we are doing with the device. The humble ATMega328P is quite old now (mid 1990s) so the modern chips you mention are unexpectedly more powerful.
@@RalphBacon so what you essentialy mean is not that Mega is ugly weak, but nowadays toys are more powerful than they "should be", got your point :)
Mate: these two videos #BB9 and #BB10 are about to elevate my code writing in a major way; you have demonstrated how to organize code yet make it readable at a later time - even to me who wrote it. How curious - given all the C++ programming videos I have watched over the years, I lament that I didn't get to these FIRST! Next: Buy you a coffee (or tea). cheers
I'm very glad you have found these useful, Thornton!
Hi Ralph, very informative as usual!. Could you explain how structs and unions work?
Great suggestion! As always, when you know how they work, you will think "Is that all there is to it?" 😁
Excellent video Ralph, thanks. I've been using namespaces for a few years now, and I find them very useful.
Cheers,
Norm.
Thanks for your corroboration, Norm; I guess if anyone was already using these it would be you 😉
@@RalphBacon You know what stamp collectors say, Philately will get you anywhere! Thanks.
Cheers,
Norm.
Great Explanaions, I have aleady used some namespace from your previous videos. I do like to organize the code, much easiear to understand and better yet, I can use some of the namespaces created in other programs without the hassle of coding or writing it, I am not a great programmer, just a hobbiest, but it helps a lot for my home projects.!!
THANK YOU FOR YOUR TIME DOING THIS CLASS!
Your attitude of organising code will ensure that you have a much better success rate with your code, both initially, and when you come to enhance or maintain it, some months down the line. 😃
Using macros to substitute for somewhat complex statements is a great idea. Though I might suggest doing that only after the statement has been tested. Otherwise, our expectation bias may keep us from figuring out where the problem actually happens to be.
Yes, that's a good suggestion. We don't want to hide errors behind our macros. Prototype first and then clean it all up.
I would definetly buy you a beer!
Nice of you to say. Who knows, one day our paths may cross... in a bar! 🍺
Thanks Ralph. I always learn something new from your videos.
My pleasure!
Double thumbs up! Excellent video Ralph. Thanx for sharing.
Great! Thanks for watching (and learning).
Very handy and very well explained.
But what is the easiest way to find the namespace back through all the xxx.h files?
Thanks
Kind regards
Naming convention! If you have a helper (header) file called lcdDisplayHelper.h it would make sense to call the namespace lcd (short names are less effort to type and look neater).
Tip: When you define a series of numbers that represent similar things like button numbers, it might be useful to use "enum" or "enum class" instead of a series of #defines. Then have your function signature require the appropriate enum type instead of the generic int type. This allows for self documentation and in the case of "enum class" it also allows the compiler to check for mistakes at compile time (eg you passing a value for a pin instead of a button).
I do believe I showed the *enum class* construct in a recent video, that shows how it prevents you (the programmer) assigning values that were not defined in the class.
Excellent Ralph…. Learning so many things that were a mystery before….
I'm glad they mysteries are being made unmysterious. Is that even a word? 🤔
@@RalphBacon It is now.. :-)
Thank you very much i shall use them in my next project
Please do!
Excellent video
Thank you so much
Glad you liked it!
Fantastic video! Thank you for raising the curtain on this for me. I will practise this!
Glad it was helpful!
Will be applying this asap 👍✌🏻
Do so! It really does help when looking at the program later.
Thanks! Really enjoyed the explanation.
Glad you enjoyed it!
Oooh. Great stuff Ralph. I'm not really a beginner but it seems that you have a good way of showing the "why" of things to anyone. I still find myself picking up bits and pieces even though I'm fairly confident with avr micros. I met a fairly new arduinite in one of the places I chat and offered a few pointers on some things they might like to look at. At first they didn't feel too confident about sharing code, but I wasn't bothered how it looked and was interested. Plus I might have been able to offer tips. :)
Knowing the "why" means people are not blindly following a method. "We've always done it like that" is no excuse for not knowing _why_ it's been done like that (in reality, the reason has been long forgotten - time to step back and reinvent the wheel!)
This is wonderful! Hobbyists like me, who can bodge a prototype code, have no experience in maintaining a code and no idea how to structure it. Hence what we write are not elegant at all. I would highly appreciate it if you could do some videos on how to refactor a prototype code (not sure whether that is the right term)
I'll have a think about that; thanks for the idea!
Sir, this made my day! Regards from far Ukraine!
Glad you enjoyed it!
Thanks for another great video. I learned something as always.
Thanks for watching!
Really nice video - THX a lot !
Glad you liked it! 👍
Very clearly explained. I've never really got into C++ (other than for eample commenting with // ) as a life long C programmer. These make me always wonder if I should switch more into C++.
Well, the use of objects could be interesting for you. OOP is definitely an eye-opener.
@@RalphBacon Yes, I find them interesting. I studied C++ while back but never really got into it.
Early compilers did not make that nice code and the need for huge optimization on battery powered devices kept me in C before.
Compilers have got better and even if there is some overhead, in non-battery operated system and platforms like ESP32 there is room for non-optimal code now.
If you go for C++ please do remember not to use pointers. They have been [mostly] superseded by other mechanisms such as references. I got caught on this just recently.
@@RalphBacon That's a great tip! So easy mistake to make. Thanks!
Thanks Ralph! I do want to see more details, but this is a good area between rigid class structure and C 'struct' structure. Now, I want to apply this to ISRs and I/O modules...
Yes, you can apply this naming and scoping mechanism to ISRs and tasks and everything! It doesn't change the code, just the way we see that code.
Thankyou verymuch. Excelent info!
Very welcome!
Like this video is part of the BB namespace 🙂
😁 Very good comment!
I'll add my thanks for these useful short takes. A follow-on question: I've done 'utility' programming in C off-and-on for years, but never learned C++. Now that I'm playing in the Arduino world, I find that many useful libraries (especially Adafruit's) are all C++ classes etc. under the hood, so it's hard to figure out what's really happening! Can you recommend a good intro to this stuff for someone who (more-or-less) knows C?
I did a step-by-step video on how to create an Arduino library (and tried to make it language agnostic): th-cam.com/video/fE3Dw0slhIc/w-d-xo.html and should get you started if you follow it EXACTLY. 👍
@@RalphBacon Thanks for that link. Watched it once so far (and enjoyed Benny's cameo). This is clearly going to take several viewings and some practice, but the fog is at least a little thinner. Much appreciated!
Very useful! Thanks.
Glad it was helpful!
I don't know if PlatforIO has different requirements but in Arduino IDE I have to add "using namespace" in main .ino code but not only #include. Without "using namespace" compiler gives an error in some cases. What about "using namespace"?
That "using namespace" is not required - and it something to be avoided if at all possible as it negates the very purpose of namespaces.
All functions within a namespace *have to be prepended* with the name of the namespace. This gives instant, automatic documentation of where that function is.
For example, if have a namespace "utils" with a function "getTemperature()" inside it, then to access that function you must:
1) include the file if it is in a separate .h file
2) refer to the function by the namespace, two colons and the function, such as utils::getTemperature();
This works both within the Arduino IDE and all other IDEs. It's standard C++. If you still think you are getting an error, copy and paste the error you get here as a reply.
@@RalphBacon Thx, I have no idea what happened before when I've got that error. It told that called function was not declared in that scope. I included external .h file so I don't know the reason. When I placed "using namespace" error disappeared, but now I removed that and still work without previous error. Probably this was caused by code sequence. Maybe I placed one .h include before other .h include. Anyway, thx for this episode, I could remake my project code a little to keep it more clean and I've learnt something new :)
If I was on the other side of the pond, I "would" get you a beer (pint?).
Very kind of you sir, and I will drink a virtual pint in your honour 🍺
Another wonderful video! Do you have a video in which you setup VS instead of the Arduino IDE?
I don't but I bet there are several YT videos that do this. It would take more than 30 minutes, I suspect, unless steps were glossed over.
Nice video on namespaces (old "c" guy here).
Two short questions:
1) why don't you make the "const uint8_t pinBtn = 3;" also a macro? This saves on RAM and time when using functions and interrupts.
2) where did you get that breadboard???
About 1: With a macro you probably lose type safety. Also you probably won't save RAM. Modern compilers will optimize the variable away in most cases.
Hey, "old C guy" good to have you here.
A const variable will undoubtedly be optimised by the compiler so that it either becomes a constexpr if it can work it out or a true const once the variable has been initialised; so no wasted space at all. Compilers is clever, they is.
That breadboard is great and is available from Cool Components in the UK. I now have 5 of them, as I keep building stuff ready for videoing but then run out of boards for my next project 😁
@@RalphBacon Ordered two... 😊
Good to know what the double colon means when I come across them. As an intermediate Arduino hobbyist I have never wrote a large enough program where I would need to use namespace and .h files to keep track of what the code is doing. As for your #define PUSH_BUTTON_PRESSED I wonder who is reading your code that digitalRead(btnPin) does not make sense?
I'm of the opinion that no code (apart from the Blink sketch🤣) is not going to be better organised by namespaces and macros!
The point about PUSH_BUTTON_PRESSED is that you can immediately understand the intention without having to actually read a line of C++ (and potentially miss a "not" (! sign) or something).
Just try it, you will soon find the benefits. Or not, in which case, continue as-is. It's your code!
hi Ralph, thank you for sharing this C++ session in Arduino. For the next video, will it be ok for you to share something like how to use C/C++ UNICODE in Arduino platform ? For example, how to read write UNICODE data ( eg. Writing Chinese or Japanese characters "test" is "测试" to and reading from MicroSD card ). Thanks again.
Unicode is not something I've had to use; it's bad enough trying to get my IDE to accept accented (European) characters let alone characters from another language entirely. If I stumble across a solution I'll be sure to mention it.
Great tool to make your code neat. There don't have to be that much code to benefit from this.
Glad you think so! It's definitely true!
isn't this the same as having classes ? Like instead of namspace, we just have classes. And the functions are defined under those classes ?
Classes are objects. You will need to create an instance of them and hold it around to call it's member functions. If it has data members then those will also be initialized with **every** instance of the class which will take memory.
Nope. Nothing like it. Don't confuse the two.
Whilst the syntax might look vaguely the same (it's not, but the :: is a _scope resolution operator_ so it will be used wherever scope needs to be resolved). That includes both namespaces as well as classes.
Looks like a quick video on classes might be in order.
@@sledgex9 Could you explain a bit more ? I just joined a company as an embedded developer and our senior developer (with a software background) always does object oriented programming with lot and lots of classes for arduino framework projects. I was baffled at first but he's the senior so I go with it.
We do have a lot of memory issues atm, i wonder if using a lot of classes are the problem.
@@aneeshprasobhan There isn't a hard rule. Basically if you only have a bunch of functions that belong together, then you group them in a namespace. If those functions operate on a specific object type (eg a button) then it might make sense to put them in a class instead. That class should also hold as a data member the object (eg button).
There isn't a specific reason why a class is bad or good. In terms of memory size it depends on how many data members (variables) it holds and in which order (class padding and alignment).
@@sledgex9 i see. thanks.
So under what circumstances should we choose to use classes and under what circumstances should we choose to use namespaces?
Always prefer classes if you can use them. It makes for much more readable code. So a better way of organising all this would be to have a Button class that has an isPressed() method. Then you can define something like Button showTemperatureButton and write if (showTemperatureButton.isPressed()) ...
Chalk and cheese. Classes are, as you know, part of object oriented programming (OOP), whilst namespaces just define the scope of variables and functions. Not the same thing but can be used independently.
I wouldn't promote OOP to beginners although, unbeknownst to them, they are probably _using_ objects when they use libraries; but creating them is something that most beginners run from.
My video #71 shows how to make a library (which, behind the scenes is a class, of course) but I am careful to avoid using OOP terms, it just scares people away.
Perhaps that video needs a revamp! 😲
@@RalphBacon yes, they are not the same of course, but when you are telling people "how to organise your code" they do suggest alternative approaches. I stand by my comment "prefer classes". I have taught programming for many years at all levels from beginner to postgraduate. Beginners have no problem with OO if taught correctly. Most colleges and Universities teach OO from the outset.
@@mikelopez9893 surely with how skilled you are your time is far to precious to waste on such video’s
@@berry1002
Although I suspect you think you are being clever/snide with your reply, I'll give you a straight answer. No, my time is not precious. I am now retired after a lifetime in computing (50 years in embedded), Much of my recent career (25 years or so) has been spent in teaching programming in computing degrees, both undergraduate and postgraduate and within my teaching I have had a special interest in teaching introductory programming and researching how people come to understand how to program. I follow and respect Ralph because I believe he is a good communicator and cares about programming. That doesn't mean I'll agree with him about everything, although I agree with him that building a solid foundation is important, not just for professional programming, but for hobbyist programming too.
By the way, I think you meant "*too* precious", not "to precious" and the plural of video is videos, not "video's". Attention to detail is important, especially if you want to take up programming.
I'd buy you a beer!
In exchange for a short chat! 😊
Oh I know what you mean, Simon. Four hours of chat followed by "Sorry, did you want that beer now, Ralph?" 🍻😜
@@RalphBacon Ha! No, I'd buy up-front. Promise!
Hehe those blue background LCD's are rubbish at every angle except the one you were looking at it from. There are high-bright and better. Yellow bg and black is pretty good.
or oled ... , used yellow on black colours back in my dBase3/4 days ...
TBH, Chris, I've never had an issue with those ocean blue LCDs. Maybe the viewing angles aren't as good as OLED ones but for the money... I do believe I have a yellow/black version, I will have to try that one out and see if it videos any better!
Nice namespaces nullifying nasty nodes - - nametastic.
I like that! 👍
It should have been named btnPin in stead of pinBtn. And its confusing to have both a namespace 'sensor' and a temperature sensor object named 'sensor'. The latter should have been named 'temperatureSensor.'
Yes and yes. I never noticed either points 😲. Then again, I've just updated an old piece of code here and found a couple of, well, let's say _idiosyncracies_ that I had to correct!
Still wanna smack you for functions in .h files...
But otherwise...
Damn good intro to namespaces.
Yeah, yeah, bad Ralph 😜putting code in header files. But even Adafruit do it. 😲 Expedient and doesn't confuse the end user. For hobbyist use I think it's acceptable. Glad you liked the namespace explanation!
Hi Ralph. I wish you a good recovery. ...I see that you are using PlatformIO. I like your color theme. Which one are you using ? Thank you. Regards, RJM
Thank you, Rene-Jean, this Covid is refusing to budge 😷 Anyway, my theme in PlatformIO is the "Dark+" theme (default dark). Much easier on the eyes, I find.
@@RalphBacon Thank you Ralph. Indeed it is easier on the eyes. Keep-up with the good work. By the way, your explanation of namespace was EXCELLENT! Regards, RJM
Nice video goto next page if you have read this page:-)
I'm stuck on this page now because there isn't a next page... now what do I do?
@@RalphBacon go to line one:-)
🤣
"consultant"(like myself) with clients
Indubitably. One client or a thousand. Still a consultant, hey?
Nice video. But please can you move onto "real" information. Jon
It's as real as you want to make it Jon. The first casualty in a rushed program is documentation; well, this mechanism allows your programs to be self-documenting at virtually no cost to the programmer (ie you).
I'm sorry but you are making programming tedious and detached. I respect your intentions and your dogmatic approach but you are driving people away from the joy of programming. In the 70' s I wrote in assembler for the 8080 family of processors and I've seen many languages and techniques come and go (TG). Please just teach programming constructs - good code will follow - it will be readable and logical and work in any language.
Peter, I am a little confused by your comment. Can you describe how you find Mr. Bacon's approach "tedious and detached?" I have the opposite impression, finding the videos informative and inspiring. Perhaps we are looking for different knowledge. As I understand it, his videos are aimed at "somewhat newish" programmers. Ones that have written a few Arduino scripts and are looking to advance their skills. They have the basic constructs in hand (for the most part). I don't believe it is Mr. Bacon's intent to tutor programming concepts. If you are looking for more basic knowledge I'd advise checking out the following content providers:
.NeuralNine
.Caleb Curry
.Corey Schafer
.Tech With Tim
and possibly Ben Eater, for "way back to basics" computing.
Just my two cents.
Oops. I forgot to add
. Low Level Learning
I didn't realise, Peter, that my approach was perceived as dogmatic 😬
I'm just promoting Best Practices. ✅ In a commercial environment there would be no discussion on how to structure your code; your employer would have a company style and that would be that.
In the hobbyist world we can do what we want, including (even) programming in Python 😅, but I'm suggesting better ways to write C++ code to keep it maintainable and self-documenting. If you don't like my suggestions that's perfectly fine for both of us, I'm not going to berate you!