Because I like C for small machines and want C rules.
Most C is also valid C++ and the Arduino doesn't run standard C++ anyway.
You can probably find a C compiler for whatever processor your particular Arduino has but things like the board-pinout won't automatically be "abstracted" and you'd have to write your own bootloader or use a separate programmer, and at that point there's not much reason to use an Arduino...
Incorrect. The gcc compiler used by the IDE adheres to C++ standards.
I´m curiuos.
Why?
Hi @GoForSmoke. The .ino file of your sketches will always be compiled as C++ (after it is converted to valid C++ via sketch preprocessing). However, you can add additional files to your sketch with the .c file extension. The code in these files will be compiled as C.
This means you can either make a program from a mixture of C++ and C (as is done in most Arduino cores and some libraries), or you can leave your .ino file completely empty and implement your entire program in the .c file of the sketch.
You can override the main() in your main ino file
int main()
{
}
This will basically get rid of the HAL and I think that that is what you want.
You can add additional .c and .h files
sketch.ino
extern "C"
{
#include "somestuff.h"
}
int main()
{
sum(3, 4);
}
It's my understanding that the extern "C" is needed to keep the linker happy when mixing C and C++. Not 100% sure though.
somestuff.h
#ifndef _SOMESTUFF_H_
#define _SOMESTUFF_H_
int sum(int x, int y);
#endif
somestuff.c
int sum(int x, int y)
{
return x + y;
}
Next I went one step further and added a main.c
sketch.ino
// empty
main.c
#include "somestuff.h"
int main()
{
sum(3, 4);
}
The two somestuff files did not change.
I did try to add some serial stuff in C (328P datasheet examples) but had some errors; I'll leave that up to you ![]()
Are my reasons not good enough? How well do you know C cast?
THANK YOU!
I wrote C for a while in the 80's and loved the simplicity. There are algos I can write in C but C++ changed the rule and the use of cast, written to be used, goes out of the window. Sorry, I can't map memory straight because an optimization now or in the next century or three?
On a PC that's okay to me but on an 8 bit MCU?
I am leaning towards biting the AVR ASM bullet. I'm getting more familiar with the chip itself that the extra layer of complications C++ brings destroys the simplicity.
I don't see AVR's as toys just as I don't see knives as toys (Scouting back when we did knives/axes/etc just to get to 2nd Class rank) . They are simple, effective tools.
AMD, not so simple inside. Closer to 486 or at least 386 PC's.
True. IIRC, Arduino Serial was written in Java or Python (not C++) source.
With what Ptillish wrote I may not have to cut the HAL that doesn't open the pod bay doors. ![]()
Arduino's hardware serial is written in C++. You are referring to the IDE implementation, not the core files ![]()
I think that the ability to add .c and .h files that don't call Serial with .cpp that does could do what i want.
I had Borland C++ 3.2 that let me do that.
I was referring to something like below in somestuff.c; example taken from the 328P datasheet.
void USART_Init( unsigned int ubrr)
{
/*Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
The compiler breaks its neck over UBRR0H. I (think I) understand why but did not feel like figuring out what to exactly include and/or how to define the registers.
I guess that you saw this;
. These code examples assume that the part specific header file is included before compilation. Be aware that not all C compiler vendors include bit definitions in the header files and interrupt handling in C
is compiler dependent. Confirm with the C compiler documentation for more details.
Chip core file that the IDE uses?
Yes; but had forgotten about it
Thanks for the wakeup call ![]()
You are not allowed to perform arbitrary pointer casts in C eiter. See https://en.cppreference.com/w/c/language/object#Strict_aliasing and https://open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=95
An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
- a type compatible with the effective type of the object,
- a qualified version of a type compatible with the effective type of the object,
- a type that is the signed or unsigned type corresponding to the effective type of the object,
- a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
- an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
- a character type.
This is very similar to the restrictions in C++. The main difference is the explicit exception in C for unions. However, this was only added in C99, type punning using unions was not allowed in the 80s, even though the compilers back then were primitive enough that it often worked in practice.
“Clever” hacks that used to work in the 80s don't work (and shouldn't work) on this century's compilers.
Yes you can, either by casting to a character type, or by using memcpy, which is optimized away to a noop in many type punning applications. In C++, you also have std::bit_cast and std::start_lifetime_as for this purpose.
The purpose of a union is to allow for a memory-efficient implementation of algebraic sum types, not to map arbitrary memory between different types.
" this was only added in C99,"
What you deride as clever, others still see as flexibility we have and have used in ASM and for me, Forth. If iy was up to that lot, DNA would never has existed.
" Yes you can, either by casting to a character type, or by using memcpy, which is optimized away to a noop in many type punning applications. In C++, you also have std::bit_cast and std::start_lifetime_as for this purpose.
The purpose of a union is to allow for a memory-efficient implementation of algebraic sum types, not to map arbitrary memory between different types."
You could have started with the can-do.
Why do you think that C started out with void pointers?
I think that not shutting everything unpredictable down limits what can be done, I don't begin to like that.
"or by using memcpy, which is optimized away to a noop in many type punning applications. In C++,"
memcpy( src, dest) isn't it? Doesn't a copy get made from RAM and cycles?
How is that NOP?
lol, I’m pretty sure DNA exists independently of any of that.![]()
because The Priesthood didn't have a say!
Look at all what can and does go wrong! It needs control that WE decide!
As long as the unpredictability of life stays ahead of the unpredictability of existence we have life.
To implement type erasure and generics/polymorphism, not to allow type punning.
What do you mean?
This is not just an arbitrary rule to annoy programmers. Invalid casts are disallowed because they make it impossible to use Type-Based Aliasing Analysis (TBAA) in compilers, this would significantly impact the performance of all code, even code that doesn't use any invalid casts or union accesses.
memcpy(dest, src, size).
Doesn't a copy get made from RAM and cycles?
No, you're thinking in terms of assembly again. C != ASM.
Type punning using memcpy is a standard pattern. Compilers are aware of this, and optimize it away: https://godbolt.org/z/xo9qq7z45.
Indeed, watch out for the evil cabal of C standard designers, and their mission to take over the world. If we don't stop them in time, they'll impose even more common-sense rules that annoy programmers who helplessly cling on to their long-held misconceptions about the language.
On a more serious note, if you really care that much about this issue, you should get in touch with people that actually write the compilers, and perhaps even people in the standardization process and working groups. Subscribe to their mailing lists, understand their reasoning, and explain your perspective. It is true that embedded software developers are sometimes underrepresented.
That would be much more productive than ranting about it on the internet.
And just stubbornly writing incorrect code because you don't like the rules in the standard is not productive for anyone: you end up with unreliable or broken software, and the rest of the world just moves on without you, and without improving the language.