Is it necessary for Arduino libraries to be object-oriented in C++? Can it be in C language with just only functions? Sometime, there may be a useful library that is in C language. It will be easier to port if there is no need to convert to object-oriented.
lightaiyee:
Is it necessary for Arduino libraries to be object-oriented in C++?
It is not necessary for them to be object-oriented, it's just C++ at the end of the day. Almost any valid 'C' code is also valid C++ and there's nothing stopping you from importing 'C' code if you want to.
Is it necessary for Arduino libraries to be object-oriented in C++? Can it be in C language with just only functions? Sometime, there may be a useful library that is in C language. It will be easier to port if there is no need to convert to object-oriented.
I asked that same question today and was shown that it's pretty easy to convert straight C functions to be arduino library compatible.
I started coding in C back in 1977 using the BDS C compiler. Many years later, I heard Bjarne Stroustrup, perhaps the father of C++, give his talk in the 1980's on "C with Classes". There were about 750 of us in the room, and 749 of us left thinking: "What the hell was that all about?" In 1994, I was forced into an Object Oriented Programming consulting job and still nothing made sense. Then, one day, and I mean literally one second of that day, I had an epiphany and everything made sense. The reason for using OOP suddenly made sense...there's even a beauty to the symmetry of the whole concept. True, most of the code used and published for the Arduino is not OOP code, and there's nothing wrong with that. That being said, however, it is worth the effort to learn OOP. I really believe it will make you a better programmer.
There's no almost about it. C++ is a superset of C. Everything that is valid in C is valid in C++.
The only real reason for using C++ (.cpp files) is that that is what the sketch is converted to. Calling functions in a .cpp file is easier than calling functions in a .c file, because the two types are processed by different compilers. The cpp compiler performs name mangling, which is what enables function overloading. The resulting object file really has two different functions for print with an integer argument and print with a float argument, for instance.
When a c file is compiled, no name mangling needs to be done, because C does not support function overloading.
So, when a cpp file calls a function in the c file, the names don't match, because the cpp compiler has determined the cpp style name that the function in the c file should have. But, the c compiler doesn't agree, so it doesn't assign the "correct" name to the function.
Using directives in the c file, or the header file, the c compiler can be told to generate names that the cpp compiler will like.
But, its simpler to simply use the cpp extension, and have the cpp compiler be invoked, to automatically mangle the names.
PaulS:
There's no almost about it. C++ is a superset of C. Everything that is valid in C is valid in C++.
I don't believe that's strictly true. There are a few differences which can cause 'C' code to not compile as C++, or to behave differently when compiled as C++. However, the differences are minor compared to the similarities and almost everything that is valid in 'C' is also valid in C++.
First post is a laugh with lloyddean. Pouring through Essential C++, Effective C++ C++ for FORTAN Programmers, C by Dissection, Advanced C, C Program Design for Engineers and a Borland C++ Builder 5.
There's no almost about it. C++ is a superset of C. Everything that is valid in C is valid in C++.
The only real reason for using C++ (.cpp files) is that that is what the sketch is converted to. Calling functions in a .cpp file is easier than calling functions in a .c file, because the two types are processed by different compilers. The cpp compiler performs name mangling, which is what enables function overloading. The resulting object file really has two different functions for print with an integer argument and print with a float argument, for instance.
When a c file is compiled, no name mangling needs to be done, because C does not support function overloading.
So, when a cpp file calls a function in the c file, the names don't match, because the cpp compiler has determined the cpp style name that the function in the c file should have. But, the c compiler doesn't agree, so it doesn't assign the "correct" name to the function.
Using directives in the c file, or the header file, the c compiler can be told to generate names that the cpp compiler will like.
But, its simpler to simply use the cpp extension, and have the cpp compiler be invoked, to automatically mangle the names.
Excellent post PaulS! You get karma for that. I'm not a very proficient C++ programmer, and I spent years avoiding it. Now I'm working through it all, it's posts like this that save a lot of time digging. I'd like to see some more of that.
PaulS:
There's no almost about it. C++ is a superset of C. Everything that is valid in C is valid in C++.
I don't believe that's strictly true. There are a few differences which can cause 'C' code to not compile as C++, or to behave differently when compiled as C++. However, the differences are minor compared to the similarities and almost everything that is valid in 'C' is also valid in C++.
Can you cite any specific examples? I'm always interested in this kind of stuff.
afremont:
Can you cite any specific examples? I'm always interested in this kind of stuff.
There are some obvious ones - because C++ introduces lots of keywords, any 'C' code using those keywords is unlikely to be valid C++. For example:
int old, new; // good luck compiling this with C++
There are also some subtleties to the way types behave. In 'C', a struct declaration only creates a struct tag; it does not create a type. In C++ it also implicitly creates the type. This means that code which does not refer to a type in 'C' could refer to the type in C++.
struct foo
{
int a;
int b;
int c;
};
int bar(int foo)
{
int x = sizeof(foo);
// what is the value of x?
// in 'C', foo refers to the argument
// in C++, foo refers to the type
}
I'm sure this is not a comprehensive list. It's true (as far as I know) that the C++ language is a superset of 'C', but it does not follow that everything that is valid 'C' is also valid C++ or that code which is valid in both languages will behave the same in both languages.
No it does not, C++ and C both use the definition from the closest scope, as in 'int foo'. In C++ to disambiguate, you can use scope operators, although this is a special case where using the struct keyword anywhere other than a structure declaration is actually doing something:
int bar(int foo)
{
int x = sizeof(foo); //Argument
int x = sizeof(::foo); //struct
int x = sizeof(struct foo); //struct
}
pYro_65:
No it does not, C++ and C both use the definition from the closest scope
You're right. In order to demonstrate the problem, I should have used a global variable and a local type instead of the other way around. However, the point I was trying to make is that in C++ the code defines a type which is not present when the same code is compiled as 'C', and this can affect the behaviour of the code.