Alright, sports fans, I have a question to pose, but before I do, I'd like to get better acquainted with you. In that, you may better understand the answer I'm searching for. Smoke 'em if ya' got 'em...
Back in the late 80s, when the 80-386 with a VGA monitor was the hot ticket in hardware, the speed and overall performance of your program would bear poorly if the size of the executable file (.exe) was too big. Period. Data definitions ran small, the smaller the better, and storage location mattered on the 3.5" floppy disks (brand new technology back then). Long story short, I needed smaller .exe files, so I started translating Turbo C functions into assembler language using the Turbo C IDE as my platform. Wicked.
I went into the .h files, got what I needed from their function definition (and threw away the rest), and created my pseudo C functions using: asm(assembler-code); commands throughout my C code. I tore into "conio. h" and rewrote functions like clrscr() and sooo many other, turning them all into little Assembler gems that took up such little space, my executable files ended up 1:10th their original size when using standard Turbo C commands. Some functions required far more time to develop than others, but in the end, everything ran like clockwork, and was WAY FASTER than Turbo C ever dreamed of. Thank you for the time. Now...
There's a file in the Radiohead examples (see pic) for the reliable datagram client/server with a comment that I cannot comprehend.
We understand I'm familiar with both the Assembler and C languages, and I know sure tootin' what the stack is, so, could someone please explain the comment on line 34 of the code attached. It explains:
// Dont [sic] put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
Let's go over what we've got...
uint8_t is an unsigned int 8 bits long, and is 8-bits in size, even when it's compiled on a 32-bit processor.
RH_NRF24_MAX_MESSAGE_LEN equals 28, but there's an overhead that leaves a length of 24 (ref: Bill)
Let's just say we have a buffer of uint8_t elements that's RH_NRF24_MAX_MESSAGE_LEN long. fine.
When may this possibly be sent to the stack?
Why would you want to?
Or better yet, how? I know anything is possible, but, in THIS code example from Radiohead? #SMH
I wish the comment left by the coder had far more explanation than "Don't put this on the stack:."
Grrr. Comments mean more than code ever will. Comments carry concept that code can't. Please comment your code consistently.
Thank you for your time, and if anyone has a clue what this <explative> is talking about, please clue me in.
Side note: once I had every function that I needed from a "???.h" file translated into asm() commands, I no longer needed to #include <???.h> that file in the compile and link, which also reduces the .exe file size down considerably.
Food for thought, that's all. Programming is an art; drink with your mind the elixir of logic gates.
Alright, sports fans, I have a question to pose, but before I do, I'd like to get better acquainted with you. In that, you may better understand the answer I'm searching for. Smoke 'em if ya' got 'em...
Back in the late 80s, when the 80-386 with a VGA monitor was the hot ticket in hardware, the speed and overall performance of your program would bear poorly if the size of the executable file (.exe) was too big. Period. Data definitions ran small, the smaller the better, and storage location mattered on the 3.5" floppy disks (brand new technology back then). Long story short, I needed smaller .exe files, so I started translating Turbo C functions into assembler language using the Turbo C IDE as my platform. Wicked.
I went into the .h files, got what I needed from their function definition (and threw away the rest), and created my pseudo C functions using: asm(assembler-code); commands throughout my C code. I tore into "conio. h" and rewrote functions like clrscr() and sooo many other, turning them all into little Assembler gems that took up such little space, my executable files ended up 1:10th their original size when using standard Turbo C commands. Some functions required far more time to develop than others, but in the end, everything ran like clockwork, and was WAY FASTER than Turbo C ever dreamed of. Thank you for the time. Now...
There's a file in the Radiohead examples (see pic) for the reliable datagram client/server with a comment that I cannot comprehend.
We understand I'm familiar with both the Assembler and C languages, and I know sure tootin' what the stack is, so, could someone please explain the comment on line 34 of the code attached. It explains:
// Dont [sic] put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
Let's go over what we've got...
uint8_t is an unsigned int 8 bits long, and is 8-bits in size, even when it's compiled on a 32-bit processor.
RH_NRF24_MAX_MESSAGE_LEN equals 28, but there's an overhead that leaves a length of 24 (ref: Bill)
Let's just say we have a buffer of uint8_t elements that's RH_NRF24_MAX_MESSAGE_LEN long. fine.
When may this possibly be sent to the stack?
Why would you want to?
Or better yet, how? I know anything is possible, but, in THIS code example from Radiohead? #SMH
I wish the comment left by the coder had far more explanation than "Don't put this on the stack:."
Grrr. Comments mean more than code ever will. Comments carry concept that code can't. Please comment your code consistently.
Thank you for your time, and if anyone has a clue what this <explative> is talking about, please clue me in.
They may be stating that the array should not be passed by value and only by reference? But as we know in C/C++ you can only pass an array by Ref only (i.e. a pointer). Not sure what they are talking about here without looking into the code and honestly I try not to look at some as they can be damage to my health 😉
Scott
EDIT: I looked at the code ;). They are saying have it on the global heap and not the functions locale memory and have it created over an over again (my guess). The array would still be allocated outside the stack though. They may want it created once and not in an automatic way as in a function.
Yeah, any array is automatically declared as a pointer by the compiler, as are strings. Now, find the address for the int *p and int arr[] when *p = &arr and arr[] = p. j/k. So,
He probably wants to keep it in the PSP, which makes sense because why define it more than once?
Still, why declare global variables in the setup() function after the Serial.begin() ran and manager.init() either succeeded or failed? He made it so neither data[] or buf[] are declared and initialized until after then.
It's beyond me, but then, I'm thinking, too, that maybe their code can damage my health.
Cheers.
It's beyond me, but then, I'm thinking, too, that maybe their code can damage my health.
Cheer.
Yeah. Me no like to ready codes like that! 😉
Something else I would like to point out: when I was doing all the C/Assembler code translations (that I "so arrogantly" spoke of - like I was all that AND a bag of chips), I MISSED A LOT OF PUSHES ONTO THE STACK AND POPS OFF THE TOP OF THE STACK AND REGISTERS WERE CORRUPT ALL OVER. I learned the hard way what recursive function calls do to a stack overflow when not properly managed, and I'm glad to have made the mistakes I have.
Philosophically speaking, life is one big learning experience. Learning never ends - ever (thankfully).
Perfect I'm not, nor try to be. I miss that personal trait by a long shot.
All I ask is a chance to better understand; I invite learning from anyone and I'm always glad to lend a hand to others.
Peace always. 🧐
I know what you mean about the stack muck-ups. I've done my fair share. In the late 80's I wrote a program switcher for DOS (as in MS). There was a lot of stack slaughtering during the devl of that code 🙂 I later did a muti-taker for it and that was a big pain. One of the things I hate about X86 based asm is the repositioning of the SP in place of a pop. Bothersome to my eyes 😉
@itscaseydambit Having been a programmer since the days of the Apple II, I certainly didn't see your posting as being arrogant. We tend to just not mention the difficulties we had in creating a program because we assume they are understood to exist.
Pat Wicker (Portland, OR, USA)
Side note: once I had every function that I needed from a "???.h" file translated into asm() commands, I no longer needed to #include <???.h> that file in the compile and link, which also reduces the .exe file size down considerably.
Food for thought, that's all. Programming is an art; drink with your mind the elixir of logic gates.
If you're very space conscious, then, you can also run without the serial object and just implement the standard:
int main() {
return 0;
}
... in the Arduino IDE without the setup() and loop() functions, and implement your own.
I believe you can also remove the boot loader for more speed and space!
...also, you can look into wrapping your string literals with the "F" macro
Serial.print("F("A long string moved into flash to reduce the memory footprint"));
They may be stating that the array should not be passed by value and only by reference? But as we know in C/C++ you can only pass an array by Ref only (i.e. a pointer).
A pointer is not a reference, but in C++, you can actually pass a pointer by reference 😉
An array is passed by a pointer. In C/C++ arrays are passed as a pointer to the first element
An array is passed by a pointer. In C/C++ arrays are passed as a pointer to the first element
Indeed, when passing an array to a function, it is said to "decay" to the first element of the array.
However, I never denied that... I just made the point that in C++, you can also pass it by reference, which you cannot do in C 🙂
In C++, a pointer is not the same as a reference.
That was never in my text. Why add to it? I made it clear what I was saying "a pointer" I do hate extra noise when it's not needed, it does not help I think. Sorry.
In C++, a pointer is not the same as a reference.
OK, I'm confused, I always thought by reference was just a fancy way of saying "by ptr". Can you clarify the difference?
Pat Wicker (Portland, OR, USA)
That was never in my text. Why add to it? I made it clear what I was saying "a pointer" I do hate extra noise when it's not needed, it does not help I think. Sorry.
Indeed, when passing an array to a function, it is said to "decay" to the first element of the array.
I think my opening statement agreed with you, no?
I was just trying to provide the correct formal wording according to ISO standard(s)... and to be absolutely correct, an array (as I said and agreed with you), "decays" to a pointer to it's first element. However, to be technically correct, there is no such thing as being passed by pointer in either C or C++, formally you pass by value in C, and can pass by both value or reference in C++, whether it be a pointer or any other relevant object.
More than happy to go through the ISO standard on this wording should you disagree.