Notifications
Clear all

Some MACRO tidbits

15 Posts
3 Users
3 Likes
664 Views
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6939
Topic starter  

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
Quote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2523
 

@zander

More of a niggle than a criticism, but I think you'd be better off using something like

#define BETWEEN(NUM,LOW,HIGH)    ((NUM>=LOW) && (NUM<=HIGH))

Reasons ...

1) all three values specified

2) no need to create an pointless struct

3) independent of struct component names

4) equivalent form is BETWEEN(37,Q1.Start,Q1.End)

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6939
Topic starter  

@will Excellent point Master Will. I was addressing a specific use case, and should have mentioned the BETWEEN macro was not generic. More like a set operator really. I will steal thay (with your permission of course) and back fit it into my use case, that way it's a win win. Thanks buddy.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@zander

Posted by: @zander

I was working an issue earlier today and saw the need for a macro or two. I also have not seen many or maybe any macros being used on the forum so maybe some of the newer members are unfamiliar with them, I am sure all the old boys like me are very familiar. I also have a feeling my C++ friends will show me how they can do it better. The first macro is a simple "is this number between two other numbers" while the second is just a test/debug print statement I didn't feel like copy/paste/editing so I made a macro instead. Let me know if you have questions, corrections, improvements (especially the comparison, I think it can be better)

[snipped example code]

Your macros look ok to me, but... their use is frowned upon these days, and there are better or cleaner ways to achieve the same result.

A few good reasons not to use them may include:
  Ugly and hard to read as they get bigger
  They do not have a namespace, and as such they do not have any scope, and can break code easily
  Very difficult to debug as they are a simple text replacement by the preprocessor

I don't see anything wrong with using a struct or class as you have, but if you're just going to use it the way you've shown, then there is a better way to implement your desired functionality using one

I'll cobble up as an alternative for you shortly...

Cheers


   
Ron reacted
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

   
Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6939
Topic starter  

@frogandtoad I actually agree with you re all the reasons macros are not a good idea, and I see that Arduino recommends against them also. Since I was still seeing a vast majority of folks and examples using #define vs const I assumed anarchy still ruled the IT world. It sounds like there may be hope.

My path to the macros was very random and I was trying to work out a way to simplify a specific coding problem but then tried to turn it into a generic solution. My BAD.

As to your solution, as you may remember I do not understand C++ so the syntax looks very weird to me. I am going to make a guess that the statement below is doing dual duty, one as a constructor and one as a member thingy??? Don't get me wrong, I like terse language in many cases especially now that my old brain has such a small cache size. The second question is that 0 is NOT between 1 and 101 so where is the message or error or something, is there yet another C++ feature I am not knowing about?

isBetween(1, 101).number(0);

 

 

 

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 
Posted by: @zander

@frogandtoad I actually agree with you re all the reasons macros are not a good idea, and I see that Arduino recommends against them also. Since I was still seeing a vast majority of folks and examples using #define vs const I assumed anarchy still ruled the IT world. It sounds like there may be hope.

My path to the macros was very random and I was trying to work out a way to simplify a specific coding problem but then tried to turn it into a generic solution. My BAD.

As to your solution, as you may remember I do not understand C++ so the syntax looks very weird to me. I am going to make a guess that the statement below is doing dual duty, one as a constructor and one as a member thingy??? Don't get me wrong, I like terse language in many cases especially now that my old brain has such a small cache size. The second question is that 0 is NOT between 1 and 101 so where is the message or error or something, is there yet another C++ feature I am not knowing about?

isBetween(1, 101).number(0);

I'll try to explain the best I can.

Firstly, "isBetween" as a struct (and is also considered a class in C++), and "number(num)" is a member function of that class.

I created a custom constructor "isBetween(min, max)" to accept the two values for flexibility of use.

Calling "isBetween(1, 101)" creates a "temporary" object, so rather than creating a persistent object:

    isBetween rangeObject(1, 101);

... and then calling the member function upon it:

    rangeObject.number(0);

... it's easier to just use the temporary object and call the member function directly upon it:

    isBetween(min, max).number(num_to_check);

Does that make sense?

In essence, I'm using a class as a better function.

As for your second question, the number function has a default parameter, thats why I demonstrated both versions... if you add "true" for the third parameter, you should see the message 😉

Cheers


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6939
Topic starter  

@frogandtoad I could use a lesson. I see nMin and nMax used 3 or 4 times and I suspect they are not really the same thing. Could you re-do that code snippet with each variable in a different namespace using a different name so I get a better sense of what is happening.

Also why does the entire thing start with struct, I see no pieces as in my example.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6939
Topic starter  
Posted by: @frogandtoad
Posted by: @zander

@frogandtoad I actually agree with you re all the reasons macros are not a good idea, and I see that Arduino recommends against them also. Since I was still seeing a vast majority of folks and examples using #define vs const I assumed anarchy still ruled the IT world. It sounds like there may be hope.

My path to the macros was very random and I was trying to work out a way to simplify a specific coding problem but then tried to turn it into a generic solution. My BAD.

As to your solution, as you may remember I do not understand C++ so the syntax looks very weird to me. I am going to make a guess that the statement below is doing dual duty, one as a constructor and one as a member thingy??? Don't get me wrong, I like terse language in many cases especially now that my old brain has such a small cache size. The second question is that 0 is NOT between 1 and 101 so where is the message or error or something, is there yet another C++ feature I am not knowing about?

isBetween(1, 101).number(0);

I'll try to explain the best I can.

Firstly, "isBetween" as a struct (and is also considered a class in C++), and "number(num)" is a member function of that class.

I created a custom constructor "isBetween(min, max)" to accept the two values for flexibility of use.

Calling "isBetween(1, 101)" creates a "temporary" object, so rather than creating a persistent object:

    isBetween rangeObject(1, 101);

... and then calling the member function upon it:

    rangeObject.number(0);

... it's easier to just use the temporary object and call the member function directly upon it:

    isBetween(min, max).number(num_to_check);

Does that make sense?

In essence, I'm using a class as a better function.

As for your second question, the number function has a default parameter, thats why I demonstrated both versions... if you add "true" for the third parameter, you should see the message 😉

Cheers

GOT IT, thanks. However not enough to start writing it, just need to understand enough to read it. 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6939
Topic starter  

@frogandtoad Thanks, that helps. I will study that. In case I have not mentioned it, muy brain was injured at birth so now I often don't remember proper names of things like struct pieces? as in name, address etc. Maybe struct fields?

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@zander

Posted by: @zander

@frogandtoad Thanks, that helps. I will study that. In case I have not mentioned it, muy brain was injured at birth so now I often don't remember proper names of things like struct pieces? as in name, address etc. Maybe struct fields?

No worries.

In C++ terminology, class variables are referred to as "data members" or "member data" when generalising. Likewise, functions are called "member functions".

Cheers


   
Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6939
Topic starter  

@frogandtoad Ok, got it, for now LOL.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@zander 

Forgot to mention yesterday, with respect to how macros don't respect namespaces and have no scope.  This was actually a classic example of why to avoid macros if you can!

Initially, I wanted to name my class variables 'min ' and 'max' for my example, but look what happened:

image
image

Because Arduino.h is implicitly included in every sketch, it also implicitly includes the macros 'min' and 'max' via other header files. Even if I wrap my own code with a namespace, the macros will still not respect them... so I was forced to use 'nMin' and 'nMax' to my disliking - This is how code is easily broken by using macros, as they are now always in scope when you don't want them to be, polluting the global namespace.

Cheers


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6939
Topic starter  

@frogandtoad EXCELLENT example. 

My profuse apologies for my (hopefully) brief wanderings in the land of frankenstein code. At least I hope my transgressions were educational. Now if everyone would stop using them (including #define) then life would be easier for those of us who spend a lot of time trying to fix others code.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote