Right, it’s the ino file that gets special handling IIRC.
it is all in one file
original is here
and @Pharap
made this —> https://github.com/Pharap/TicTacCurly/
You can spread a sketch out over multiple .ino files. But yes, .cpp .c and .h files don’t get the full Arduino “magic”.
I didn’t know that.
I’m still going to predecalre them though since that’s non-standard behaviour and I want to keep everything I do as portable as possible. Plus it means people don’t have to read the function body to get a better idea of what a function is doing.
You do, but everyone has to start somewhere and there’s no rush to learn it all, you can take it a bit at a time.
You’re making some decent games that actually work so you’re definitely doing well so far.
As long as you read a tutorial or two, or try learn the basics of at least one new language feature a week, by the end of the year you’ll be able to look back on how much you’ve learned and feel proud about it.
(Also, don’t be too daunted by all the things I did to TicTacCurly, I’ve been doing C++ for at least about 3 years now, so I’ve had the time to learn about all those things. Even now there’s still quite a few things I don’t know.)
Playing devil’s advocate,
Just as you are quick to point out that “C and C++ are not ‘basically the same thing’”, I could make the argument that C++ and Arduino are not the same thing. Although they are very similar (because they share the same compiler) the Arduino “magic” makes it not strictly C++ anymore.
For instance:
- You provide setup() and loop() functions instead of main()
- byte is used instead of unsigned char.
- boolean is used instead of bool.
- The main code file has the extension .ino
- You don’t need to provide prototypes for forward referencing.
I could posit that by including forward references, you’re no longer accepting Arduino “standard behaviour”, which could be confusing for beginners looking at your code who are trying to learn “Arduino”.
Might be more correct to say that C++ and .ino files aren’t “exactly” the same… if your sketch includes .cpp and .c files I believe these are used as-is… and indeed I think the best design for anything ambitious is a very minimal .ino with almost all the actual C and C++ code in regular files… then you are dealing with C/C++ and don’t have to worry about what crazy magic Arduino will think of next.
You can also supply your own main() if you really know what you are doing and plan to boot the chip yourself… making it even more like normal C.
And honestly it’s probably more accurate to say Arduino is just C/C++ with a small amount of pre-processing applied to your .ino file, which is much closer to the truth. It pretty much just adds function prototypes (if needed), sniffs libraries (so it knows which code to use and which libraries to link), and adds it’s own main() which expects you to provide setup() and loop().
Then your not following the “Arduino” philosophy. Which may not strictly be a “bad thing” but could be confusing for beginners following Arduino documentation.
It’s a bad philosophy if it says put all your code in one large .ino file. Maybe ok for small things and beginners but anyone whose done medium or large projects knows there are much better ways. And the IDE natively supports this now (by opening all the related files), so it must be at least somewhat kosher.
It doesn’t. It says include as many .ino files in your sketch as you want, to break things up for manageability and readability.
Interesting - but yet also happily opens up your raw C files and lets you edit and compile them also. So I’d say the philosophy might be a little open to interpretation, like most things.
Wait a minute… I was under the obviously mistaken assumption you had one .ino file and then the other files you created with ‘create new tab’ were not ino files. Damn, googling this has confused me.
So to get this straight, if I create a sketch, then add a new tab and call it foo.ino, i can have functions in both that can access each other without any predeclaration needed?
I’ve never seen that done, but mlxxp says it’s doable.
I did say I was playing devil’s advocate. And I think the intent was to allow .h .cpp and .c files for advanced programmers who are used to them or are porting code, but recommends .ino to keep things simple for beginners.
Read the build process document that I’ve already referred to previously.
When your sketch is compiled, all tabs with no extension are concatenated together to form the “main sketch file”.
(Tabs with no extension are .ino files)
Firstly, the C vs C++ matter is a semantic difference as well. There are programs written in C that would genuinely behave differently if compiled with a C++ compiler. If the same can be said for Arduino (i.e. that certain programs that are both valid C++ and valid ‘Arduino’ will behave differently when compiled as ‘Arduino’) then that would be fair enough, but I have yet to see evidence suggesting that is the case.
There is actually a main
function, it’s hidden away in …\hardware\arduino\avr\cores\arduino\main.cpp.
Unsuprisingly it’s responsible for calling setup
and loop
.
If you want though, you can provide a main
and the compiler will use that instead.
byte
isn’t used instead of unsigned char
, byte
actually is an unsigned char
that’s been typedef
ed either in the headers or by the compiler. The same can be said for boolean
and bool
, boolean
is a typedef
of bool
. This can be proven through using a template simulating the C++ stdlib’s std::is_same
, or by looking at …\hardware\arduino\avr\cores\arduino\Arduino.h where they are both typedef
ed.
I’m not sure how the compiler itself treats the ino
file - whether the behaviour that makes it different is from the Arduino IDE or from the gcc compiler itself. Granted when using the IDE there is behaviour that is not standards compliant, but I do not know if any of that would make valid C++ code behave differently. The only thing I’ve found that ‘break’ the code is attempting to typedef byte
or boolean
as something else, which can be explained by the behind-the-scenes header files.
Granted, choosing to predeclare functions might confuse some beginners who are using ‘Arduino’ as their first language and have not encountered predeclaration, but there is nothing in the language to state that you are not allowed to predeclare them and the exaplanation as to why they are predeclared is simple enough and I for one am not going to tell people to choose either approach since both are prefectly fine.
If you want to tell me that choosing to use predeclared functions is a bad thing, then by all means feel free to. I can choose to accept or ignore your argument either way.
Again, I’m talking mainly philosophically, from the point of view of a beginner learning program their Arduino using the Arduino documentation.
It’s not GCC. It’s java code in the IDE that turns each .ino into a VALID .c or .cpp file… then those are what’s passed to GCC. Just look in the temporary build directly the IDE creates to see what it generates. Arduino IDE is just a fancy pre-processor plus some C/CPP libraries.
I’m running under the assumption that they’re also learning from other sources that are targetted at learning C or C++ in general rather than just using Arduino-oriented things.
Besides which they’d run into the issue the moment they tried to run their code on a different compiler so they’d have to learn eventually if they ever wanted to use C++ in a non-Arduino environment.
I suspected that would be the case but I don’t like to make too many assumptions about things I only have a vague idea about so I erred on the side of potentially being wrong.