|
Ha! What's jarring to me is
When people write partial sentences. - punctuating and capitalizing them as though they are complete sentences.
Comments to me are usually partial thoughts rather than complete sentences like
if(ptr) { // if not out of mem
memcpy(buf,ptr,sizeof(buf)); // copy it
}
Like that, so that's why I do not punctuate
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
Exactly ... missing punctuation (for me) is an incomplete thought.
My comments are comments; and sometimes they are instructions; and sometimes they are warnings. Anything else is noise.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
The code looks clear enough, but why are you using all those C-language headers in C++ code? I started to read the documentation and like the structure, but it would take me far too long to read (and understand) the entire document. First impressions are that it is well presented and clearly written. My only negative comment is the light text on a dark background (but that's just me). Overall I would say it looks like you have worked hard on this.
[edit]
Mea culpa! I just found the "dark to light" switch.
And on a further read (as someone who is rubbish at documentation) I am impressed by the quality.
[/edit]
modified 5-Oct-23 3:19am.
|
|
|
|
|
Thanks. The reason for the C headers is zero-overhead C++ without the STL is my typical environment because of IoT and embedded. That resolves to "Cish" C++.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
honey the codewitch wrote: I was wondering how difficult it is to follow
Presuming it is the docs and not the code...
Some review comments...(I didn't review completely - just randomly jumping around.)
I suggest that you use a different name than 'GFX'. Possible that you might even be required to since a company uses that. Also makes it easier to google for information on it if it much more unique.
You just start right up into what I can only presume is the setup. I say presumably because you do not actually state that. As an intro? example there should only be one example.
Myself I prefer that code blocks are indented from explaining text.
There is nothing in the entire document about exceptions or errors. Nor troubleshooting.
----------------------------------
Pixels
Intro is a bit odd.
There are subsections but those are not in the table of contents?
Pixels section is also hanging out by itself in table of contents.
Perhaps Pixels should be under 'Addendum'? Seems like it might fit.
Arduino TFT Bus
Lots of stuff like 'PIN_NUM_CS' in code. Is that a stand in for actual hard value? A macro that user must define? From the library (your library) that you reference?
Streams
This seems extreme. Anyone that is going to be using this successfully needs to already understand a fairly high level of programming. So is this section needed?
Suspend and Resume
What happens if there is a suspend but then I want to stop completely?
Drivers
This is in the wrong location based on the content (sparse). This and what you put in the header suggests you need a section on setting up to use the library including decisions (with examples) that one might make.
Tools
Fontgen seems to make sense to me but Bingen doesn't.
Always concerning to me when header files initialize data. Which is what the text seems to suggest with 'test_dat_stream'?
There is an odd 'performance' link at the bottom of this page?
|
|
|
|
|
Thanks! I'll bookmark this feedback and use it when I do a doc update.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
Regarding your comments on my use of x and y , I honestly can't think of a more descriptive name for them, as they translate directly to 2D cartesian coordinates*. In math that's x and y.
*y is inverted.
Anyway, do you have suggestions for those, as I am drawing a blank?
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
honey the codewitch wrote: Anyway, do you have suggestions for those, as I am drawing a blank?
There's always abcissa and ordinate, but that's getting just a wee bit pedantic, in my opinion. I think that anyone familiar with the problem space would probably expect the use of x, y (and z) for cartesian coordinates. At the very least, they shouldn't be confused by it. Just as you wouldn't expect someone to be confused by the use of (theta,r) for polar coordinates, or F=m*a, etc.
Keep Calm and Carry On
|
|
|
|
|
x and y it is (X and Y as properties) ... and often, accompanied by Left and Top. And you should be aware when they correspond. x and y can also simply mean displacements.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
I think anyone who works, or wants to, with computer graphics, will understand the use of x and y addressing.
|
|
|
|
|
honey the codewitch wrote: Regarding your comments on my use of x and y
Me? I don't think I said anything about that.
|
|
|
|
|
I could have sworn you did, but sure enough you did not.
I can't find it on this thread, so I don't know where I got that. Sorry!
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
I assumed you saw something we didn't get to see, somehow.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
If I have a for loop, the program will allocate memory for an int every frame. When the for loop is done will the memory be released or will it result in garbage that piles up every frame.
int main()
{
for(int anint = 0; anint < 100; anint++)
{
}
}
modified 26-Sep-23 8:35am.
|
|
|
|
|
This memory is allocated on the stack and will be "released" after the loop finishes.
|
|
|
|
|
The program knows I don’t need the integer after the loop is done, thanks.
|
|
|
|
|
|
I suspect maybe that is a bit different especially given the OP.
C, so before C++, would limit the scope to the method. C++ would have been based on the same. So if one has 3 for loops in one method with each in a block for a if statement, the compiler might or might not have limited it to the block.
What you refer to makes that explicit. The compiler thus must reuse the stack space.
The OP though is referring both the scope which is a method and, I believe, to each iteration of the for loop.
|
|
|
|
|
jschell wrote: C, so before C++, would limit the scope to the method. No, C89, C90 through until C98 had method scope.
jschell wrote: So if one has 3 for loops in one method with each in a block for a if statement, the compiler might or might not have limited it to the block.
The ISO standards are listed at the bottom of this page. Could you point out what you are referring to?
I see what you are saying now. You are describing old C89 rules. Are you an embedded C programmer? Those scope rules were changed way back in 1999.
Yeah, modern compilers don't have method scope at all anymore. Some embedded compilers still do C89
modified 25-Sep-23 14:04pm.
|
|
|
|
|
Randor wrote: Could you point out what you are referring to?
I should have read your original post more carefully....
The following is part of what the OP posted.
"allocate memory for an int every frame."
To me the terms I underlined are significant.
Most compilers that I have ever seen, not just C/C++, use a 'stack frame' to manage the variables within a method.
The allocation, far as I can tell, is how the OP is referring to, because the post specifically uses those terms.
But it is still up to the compiler. As a matter of fact at least at one time compilers at one time made a big deal (advertising) that the method variables were managed as CPU 'register' values and were not put onto the stack frame at all. And that is definitely not in the specifications for C or C++.
I do know, because I looked at the assembly that compilers used to emit (and at times modified it) that compilers at one time did nothing more than allocate variables on the stack frame sequentially. I might even recall reading an article that a developer would need to manage variables more carefully to limit that. (I can perhaps recall the suggestion that all variables should be declared at the top of the method for that very reason.)
Now back to what you posted...
For what you posted the "scope" refers to where the variable is visible from. At the language level.
That does NOT specify how the compiler is to manage the variables.
Do you have a different specification, which would probably need to be after C99, that does state how the stack frame is to be managed? I say C99 since I was familiar with that one and I am rather certain that it says nothing at all about the stack frame.
I also looked through my books for "C++ Programming Language" and "C Programming Language" and found nothing at all about the stack frame. I did not expect to find it.
I did look through the Dragon book where I would expect this to be discussed. It doesn't use that term instead it uses the term 'activation record'. It discusses how the activation record can be managed by a stack.
|
|
|
|
|
The C99 standard is here: C99 Standard
Scope starts at 6.2.1
But you would probably want to read: 6.2.4 Storage durations of objects
I use to read all these many years ago, I stopped reading the specs after C11
At Microsoft we had a huge internal mailing list where everyone got to watch the compiler team go back and forth over the new language features. The gatekeeper of the STL library had the initials S.T.L. I always thought that was funny.
|
|
|
|
|
Randor wrote: 6.2.4 Storage durations of objects
But 6.2.4 says nothing about how a stack frame is built.
Just as with your other reference it explains what the compiler must enforce but not how it must enforce it.
Following is the only thing that relates to the language
4 An object whose identifier is declared with no linkage and without the storage-class specifier statich asautomatic storage duration.
5 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in anyway.(Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.
The second paragraph is the only one even close to relevant and basically makes the same point as your other reference.
It does not specify how it is built on the stack frame.
Again a compiler writer could make a fully compliant compiler which used new slots on the stack frame for each block. Or it could reuse existing ones. Both implementations are compliant.
The referenced section allows a compiler writer to produce optimized code that reuses the slots. And they cannot be considered non-compliant if someone attempts to use a declared variable in a block outside the block (for example via a pointer.)
Consider exactly that case - using a pointer outside the block.
1. Compiler A uses new slots so the code works.
2. Compiler B reuses slots so the code doesn't work.
The user complains that Compiler B is non-compliant. The creators can tell them explicitly that they are using code that the spec does not support.
But it says nothing about Compiler A. Compiler A is NOT required to attempt to determine that a pointer belongs to a variable that goes out of scope. (Similar to having a method return a pointer to a local variable.) The compiler might choose to warn about that but is not required to do so.
|
|
|
|
|
Thanks for writing all that. The ironic part of this conversation is that the answer to the question at the top of this thread been the same since C99.
|
|
|
|
|
I'm still not clear about this.
If variables X and Y are defined in a block, must they both be available throughout the lifetime of that block?
If the compiler does a complete flow analysis, detecting that variable X is only used in the first half of the code, and variable Y only in the second half, with no overlapping use possible for any possible execution path, can then X and Y share the space?
For the running code, sharing would be OK. A debugger might display both X and Y as soon as the block is entered, and all the time until the block is left. If X and Y share a location, then Y would be incorrectly displayed for the first half, X for the second half. Does anything in the C++ standard forbid this? Does the language standard at all relate to tools like debuggers, or only to the executing program code itself?
|
|
|
|
|
trønderen wrote: If variables X and Y are defined in a block, must they both be available throughout the lifetime of that block?
Via the spec? No. The spec is just asserting that they are not 'available' outside the block.
In reality, in terms of the compiler emitted code? Probably.
Consider what difficulty the compiler has in determining what the scope of A is in the following. Keep in mind that the code can get much more complex.
{
int A = 3;
int *B = &A;
int **C = &B;
doit(C);
}
|
|
|
|