Author Topic: Good C programming books  (Read 1893 times)

0 Members and 1 Guest are viewing this topic.

Offline Jwillis

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: ca
Good C programming books
« on: September 26, 2019, 11:18:05 pm »
Hey folks. I haven't done any programmming in C since the ATARI ST days (1985-1991)  and I lost or gave away all the resources I used then.Now I'm having a job wrapping my head around this Arduino because I've forgotten everything.
I've started again with a project I found on you tube  using the TLC594016-ChannelLED Driver.
 
But I want to add more chips and do more patterns. I managed to figure out the circuit schematic reading the programming text. but still having trouble relearning the rest.
Can you folks direct me to some decent books so I can relearn.I like books because I find un-printed PDFs hard to work with and some web sites hard to navigate .

 
« Last Edit: September 26, 2019, 11:20:51 pm by Jwillis »
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 1122
  • Country: nz
  • Currently at SiFive, previously Samsung R&D
Re: Good C programming books
« Reply #1 on: September 27, 2019, 01:07:53 am »
This doesn't seem to have anything much to do with C?

p.s. Arduino language is officially called "Wiring" and is a carefully-crafted subset of both C++ and Java and sketches are supposed to work in either. (the IDE automatically adds forward function declarations for C++, and a class wrapper for Java)

I suspect the Java compatibility of standard code isn't checked all that often these days. And of course user-written code often uses full C++ features.

 

Offline Jwillis

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: ca
Re: Good C programming books
« Reply #2 on: September 27, 2019, 05:50:12 am »
That explains why it looks so strange. I don't know anything about Java. So What I'm looking for is a book specifically for Arduino coding then?
 

Online westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #3 on: September 27, 2019, 09:10:43 am »
Quote
Arduino language is officially called "Wiring" and is a carefully-crafted subset of both C++ and Java and sketches are supposed to work in either. (the IDE automatically adds forward function declarations for C++
This is wrong.  The Arduino Language is officially called "the Arduino Language" (1)

It is based on the Wiring Language defined as part of Hernando Barragán's Master's Thesis (2)

Neither the Arduino Language nor the Wiring Language contain any Java, although they were influenced by "The Processing Language" (3) (which is Java), and have similar abstractions, elimination of build complexities, and rejection of the standard libraries.


While they'd apparently like to believe otherwise, the Arduino and Wiring Languages are both C++, though without the C++ STL or even normal C++ libraries (depending on actual chip, actually.)  They do some trivial pre-processing to generate forward declarations, and then run the standard avr-gcc/avr-g++ compilers.  And they have their own set of "standard" library functions (although avr-libc and/or newlib-nano are present as well.) (4)


You can also include plain C/C++ files in your Arduino projects, and the IDE will handle them fine (just with less pre-processing.)  (And within the limits of the C++ libraries and features available from the particular compiler.)


A good C book is a fine place to start, if you want to understand Arduino code.

« Last Edit: September 27, 2019, 09:17:33 am by westfw »
 

Online westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #4 on: September 27, 2019, 09:27:42 am »
Quote
A good C book is a fine place to start, if you want to understand Arduino code.

I should add that "a good C++ book" is probably a TERRIBLE place to start, if your goal is to understand Arduino.  Most C++ books will immediately plunge you into features and library functions that just aren't there in Arduino (or shouldn't be used, even if they do exist.)
Even for C, the starting "Hello World" program won't work because you need to use "Serial.print()" instead of "printf()"  (But that's the big one for "beginning C", whereas for C++... I think you'd run into a lot more.
 
The following users thanked this post: Ian.M

Online westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #5 on: September 27, 2019, 10:02:19 am »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #6 on: September 27, 2019, 03:29:58 pm »
Just a note, something I kind of keep repeating. C is NOT a subset of C++. The subset of C++ that looks like C still has pretty different rules from C about many things, and I personally think using C++ to learn C is definitely a borked approach.

So actually naming the subset Arduino uses "Arduino" was a good idea, so that things don't get mixed up.

It's not just the printf() that won't work. Many C constructs are invalid in C++.
 
The following users thanked this post: Nominal Animal

Offline Jwillis

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: ca
Re: Good C programming books
« Reply #7 on: September 27, 2019, 07:23:28 pm »
Any personal recommendations on the books I should check out?I have nothing right now and theirs just so many choices.
 

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1307
  • Country: gb
Re: Good C programming books
« Reply #8 on: September 27, 2019, 08:32:00 pm »
If you want to learn C, the original book
"The C programming language"
by Kernighan and Ritchie.

As others have pointed out, it will not directly work on Arduino. Some tailoring required.

Personally, I have not seen ANY Arduino example code that even bearly resembles C++
It all looks like some sort of C.
« Last Edit: September 27, 2019, 08:34:53 pm by MosherIV »
 
The following users thanked this post: Jwillis

Online westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #9 on: September 27, 2019, 10:53:22 pm »
Quote
The subset of C++ that looks like C still has pretty different rules from C about many things ...
It's not just the printf() that won't work. Many C constructs are invalid in C++.
"Many"?  Care to mention a few that are significant, something that would bite a beginning programmer, and not in the "things you shouldn't do anyway" category?  I took a look at https://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B and the biggest things that jumped out where "C++ won't let you assign (void*) pointers to type pointers without an explicit cast" (which is trivial) and assorted "reserved keywords"...

printf() and "cout << stuff" are both capable of working "just fine" in Arduino.  It's just that neither stdout nor cout is defined, by default.


Quote
So actually naming the subset Arduino uses "Arduino" was a good idea, so that things don't get mixed up.
Maybe.  As things are now, we get questions from "experienced" programmers looking for "more complete definitions of the Arduino Language" (which don't exist, because it's "see a C/C++ manual.)  If it was heavily documented as being C++, we'd probably get a similar number of complaints (from similar sources) about exceptions or some STL thing not working.
 

Offline Ampera

  • Super Contributor
  • ***
  • Posts: 2506
  • Country: us
    • Ampera's Forums
Re: Good C programming books
« Reply #10 on: September 28, 2019, 06:16:31 am »
Learning C as a means to learn C++ is excellent, learning C++ to learn C is not so much.

The book I used to learn C is https://www.amazon.com/dp/0321776410/
I've found it to explain the basic programming concepts of C in a fairly thorough and easy to understand way, at least enough to use before simply relying on online reference materials.

Ardunino programming is also a much different concept, as the standard library is completely different. That's the wonder of C, in that the actual library functions being used can change radically based off what system you're using, but the core syntax and language structures will remain mostly compliant to one of the various C standards. Keep in mind you should have your provided bowl of asterisk cereal for all the damn exceptions that exist.

I personally started programming using the Turbo C implementation, as I could more easily jump into the advanced parts of the C language while doing neat things on a DOS platform (like direct screen memory access and messing with BIOS/IVT functions). This may or may not be a good place for you to start too, for which I would suggest the OSDev wiki as a good resource on the various inner mechanisms of the IBM PC architecture.
C/C++/Java Programmer, Legacy hardware enthusiast, madman.
If it's broken, I probably did it.
EEVBlog IRC: irc.austnet.irc #eevblog
 
The following users thanked this post: Jwillis

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 1122
  • Country: nz
  • Currently at SiFive, previously Samsung R&D
Re: Good C programming books
« Reply #11 on: September 28, 2019, 06:51:14 am »
Personally, I have not seen ANY Arduino example code that even bearly resembles C++
It all looks like some sort of C.

Code: [Select]
void loop() {
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue);
  delay(1);
}

What the heck do you call Serial.println(sensorValue)? That can only be C++ (or Java), not C.
 

Offline Ampera

  • Super Contributor
  • ***
  • Posts: 2506
  • Country: us
    • Ampera's Forums
Re: Good C programming books
« Reply #12 on: September 28, 2019, 07:44:13 am »
couldn't you store the pointer to a function in a structure?
C/C++/Java Programmer, Legacy hardware enthusiast, madman.
If it's broken, I probably did it.
EEVBlog IRC: irc.austnet.irc #eevblog
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 1592
  • Country: us
Re: Good C programming books
« Reply #13 on: September 28, 2019, 07:44:39 am »
Personally, I have not seen ANY Arduino example code that even bearly resembles C++
It all looks like some sort of C.

Here you go, I created this to make you happy. Even used main instead of setup/loop to make it look more normal (the default main() is declaried with a weak attribute, so you can replace it). to make it look more normal. I already had Pin() and Port() classes, so this was trivial.
Code: [Select]
// blink program for digispark attiny85

 #include "pin.hpp"

int main() {               

  init(); // initialize hardware timers so we can use delay()
 
  // initialize output pins
  Pin led0(Port::B, 0, OUTPUT); // utility led on digispark attiny85 version B
  Pin led1(Port::B, 1, OUTPUT); // utility led on digispark attiny85 version A

  // Blink the builtin led pins. Whichever pin the led is attached to will be visible to the user.
  while(1) {
    led0.toggle();
    led1.toggle();
    delay(1000);
  }
}
 

Offline Jwillis

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: ca
Re: Good C programming books
« Reply #14 on: September 28, 2019, 08:08:39 am »
Looks like I have some catching up to do.
 

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1307
  • Country: gb
Re: Good C programming books
« Reply #15 on: September 28, 2019, 10:07:59 am »
Quote
Learning C as a means to learn C++ is excellent
I would dissagree.

I learnt C first. Then I had problems converting from fuctional programming to object orientated.
I would recommend learning C++ or Java first to learn OO first.
It is easier to comvert from OO to functional (functional is a subset of OO)

Quote
led1.toggle();
As Ampera said, this can be a call to a function pointer in a struct. The dot operator does not make it C++ !

Objects/classes make it C++
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 1592
  • Country: us
Re: Good C programming books
« Reply #16 on: September 28, 2019, 10:39:55 am »
Personally, I have not seen ANY Arduino example code that even bearly resembles C++
It all looks like some sort of C.

Here you go, I created this to make you happy. Even used main instead of setup/loop to make it look more normal (the default main() is declaried with a weak attribute, so you can replace it). to make it look more normal. I already had Pin() and Port() classes, so this was trivial.
Code: [Select]
// blink program for digispark attiny85

 #include "pin.hpp"

int main() {               

  init(); // initialize hardware timers so we can use delay()
 
  // initialize output pins
  Pin led0(Port::B, 0, OUTPUT); // utility led on digispark attiny85 version B
  Pin led1(Port::B, 1, OUTPUT); // utility led on digispark attiny85 version A

  // Blink the builtin led pins. Whichever pin the led is attached to will be visible to the user.
  while(1) {
    led0.toggle();
    led1.toggle();
    delay(1000);
  }
}
Quote
led1.toggle();
As Ampera said, this can be a call to a function pointer in a struct. The dot operator does not make it C++ !

Objects/classes make it C++

So how do you explain away the scope resolution operator in the declaration of led0 and led1?
But I'll give you more since you seem to be in denial:
Code: [Select]
#ifndef pin_hpp
 #define pin_hpp

 #include <avr/io.h>
 #include "port.hpp"

class Pin {
public:
Pin(volatile Port &port, uint8_t pin, uint8_t mode, uint8_t activeLevel = HIGH);
void mode(uint8_t mode, uint8_t activeLevel = HIGH);
void high();
void low();
bool active() const;
void toggle();

private:
volatile Port *mPort;
uint8_t mPinMask;
};

inline void Pin::mode(uint8_t mode, uint8_t activeLevel) {
((Port *)mPort)->mode(mPinMask, mode, activeLevel);
}

inline void Pin::high() {
((Port *)mPort)->high(mPinMask);
}

inline void Pin::low() {
((Port *)mPort)->low(mPinMask);
}

inline bool Pin::active() const {
return ((Port *)mPort)->active(mPinMask);
}

inline void Pin::toggle() {
((Port *)mPort)->toggle(mPinMask);
}

 #endif
Code: [Select]
#include "pin.hpp"

Pin::Pin(volatile Port &port, uint8_t pin, uint8_t mode, uint8_t activeLevel) :
mPort(&port),
mPinMask(1 << pin)
{
((Port *)mPort)->mode(mPinMask, mode, activeLevel);
}

Yeah, I left out the documentation blocks, since I didn't want you to get bored before you got to the code.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #17 on: September 28, 2019, 02:50:58 pm »
Quote
led1.toggle();
As Ampera said, this can be a call to a function pointer in a struct. The dot operator does not make it C++ !

Yes.

This, on the other hand, can't be C:
"Pin led0(Port::B, 0, OUTPUT);"
so it's immediately obvious that's it's not C code, and that Pin is a C++ object.
 

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1307
  • Country: gb
Re: Good C programming books
« Reply #18 on: September 28, 2019, 06:33:37 pm »
Ok, I conceed. The scope operator is definitely C++

However, I re-iterate my original statement, most examples of Arduino code is more procedural than object orientated.
They are very poor examples to teach people good object orientated coding.

I would not recommend using Arduino to learn C++
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #19 on: September 28, 2019, 07:49:43 pm »
Ok, I conceed. The scope operator is definitely C++

However, I re-iterate my original statement, most examples of Arduino code is more procedural than object orientated.
They are very poor examples to teach people good object orientated coding.

I would not recommend using Arduino to learn C++

Oh, I agree with that. I'm just saying it's also an even poorer way of learning C. ;D

(The libraries themselves are pretty much all written as OO. Granted, basic classes, but still OO. But then yes, most of the example code you can find outside of libraries is poor crap, that is neither really proper C++ nor C. ;D )
 

Online westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #20 on: September 28, 2019, 10:30:45 pm »
Quote
Personally, I have not seen ANY Arduino example code that even bearly resembles C++

heh.  It depends on what you think C++ should look like.Apparently there is a whole class of C++ programmers who think that C++ programs should look much different than "C with Classes."  (Arduino definitely leans toward "C with Classes."  I mean, not a single use of STL in the whole thing!  And no templates at all!  Precious little in the way of operator overloading!  Horrors!) (significant amounts of function overloading, though.)


Interesting discussion here: https://softwareengineering.stackexchange.com/questions/48401/learning-c-properly-not-c-with-classes


I suspect that the people who think like this are not embedded programmers.  I find the example "sort" code posted at that link to be ... horrifying, and most "C++ for Microcontrollers" advice starts with "avoid the STL, since it's heavily dependent on dynamic allocation."


Quote
I would not recommend using Arduino to learn C++

Agreed.  Although, one of the "problems" learning any new language or paradigm is finding a project that is small enough to understand, and big enough (and scoped) to provide motivation.  "Convert THIS segment of the Arduino code to be more in the C++ style" would probably be a great "learning C++" exercise.  (Likewise: "modify this C++ library to work better in the Arduino environment.")

« Last Edit: September 28, 2019, 10:33:04 pm by westfw »
 

Offline Ampera

  • Super Contributor
  • ***
  • Posts: 2506
  • Country: us
    • Ampera's Forums
Re: Good C programming books
« Reply #21 on: September 29, 2019, 03:37:43 am »
I would dissagree.

I learnt C first. Then I had problems converting from fuctional programming to object orientated.
I would recommend learning C++ or Java first to learn OO first.
It is easier to comvert from OO to functional (functional is a subset of OO)

Then perhaps you're getting at it wrong. There's nothing forcing you in C++ to do object oriented much of anything. If anything it's C with some nicer standard libraries and then OOP if you want it.
This is how I started C++, and I, for the most part, treat it a lot like C still, just with some nicer quality of life features like maps and simpler memory management that C doesn't have.
C/C++/Java Programmer, Legacy hardware enthusiast, madman.
If it's broken, I probably did it.
EEVBlog IRC: irc.austnet.irc #eevblog
 

Online westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #22 on: September 29, 2019, 08:25:25 am »
"I can write C code in quite a few other languages!"
 
The following users thanked this post: Ampera, dcarr, worsthorse

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 1592
  • Country: us
Re: Good C programming books
« Reply #23 on: September 29, 2019, 09:05:37 am »
I learned and used C before C++, but there wasn't a choice in my case. It was before C++ was created.

I also learned the VI editor before the computer mouse was a thing. It's still worth using as well, and the fact that you still don't have to have a mouse to use it is a good thing.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #24 on: September 29, 2019, 02:28:06 pm »
"I can write C code in quite a few other languages!"

Ouch, that was a great summary of the current state of things, I think. :-DD
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 1122
  • Country: nz
  • Currently at SiFive, previously Samsung R&D
Re: Good C programming books
« Reply #25 on: September 29, 2019, 06:57:49 pm »
I learned and used C before C++, but there wasn't a choice in my case. It was before C++ was created.

I also learned the VI editor before the computer mouse was a thing. It's still worth using as well, and the fact that you still don't have to have a mouse to use it is a good thing.

I learned C and vi together in 1982, on "Eunice" under VMS. The next year we had real Unix on a Zilog System 8000.

C was fine. A bit uglier than Pascal or Modula 2, but usable. I bought the first Zortech C++ compiler (for DOS) and ran it on a Mac under VirtualPC. Within a year Apple had C++ as part of MPW (Macintosh Programmer's Workshop) and I switched all my development from C and Pascal to C++.

I hated vi right from the start. So crude compared to EDT or EVE on the VAX. Still, that's what Unix systems had, so that's what I learned to use.

I don't think I had access to a proper emacs until 1996 or so when I started to use Linux and also acquired a cast-off SPARCStation ELC with Solaris. It was love at first keystrokes and I dropped vi like a hot potato. Ever since then I've used emacs as my primary editor no matter what OS I'm on: Linux, Mac, or Windows.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 10034
  • Country: gb
    • Having fun doing more, with less
Re: Good C programming books
« Reply #26 on: September 29, 2019, 07:20:06 pm »
I learned and used C before C++, but there wasn't a choice in my case. It was before C++ was created.

I also learned the VI editor before the computer mouse was a thing. It's still worth using as well, and the fact that you still don't have to have a mouse to use it is a good thing.

I learned C and vi together in 1982, on "Eunice" under VMS. The next year we had real Unix on a Zilog System 8000.

So did I, except it was on that decent operating system from Microsoft: Xenix.

Fortunately it also had a rather tasteful editor from a young James Gosling (subsequently of Java fame), Unipress emacs.

Quote
I hated vi right from the start. So crude compared to EDT or EVE on the VAX. Still, that's what Unix systems had, so that's what I learned to use.

Ah yes, EDT. The trouble with that was that if you hit "delete word/character", it would delete one of two words/characters depending on what you had been doing some time in the past. If you last moved forwards(backwards) then it deleted the next word forward(backward).

Fortunately you could override that idiocy via macros.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 6534
  • Country: us
Re: Good C programming books
« Reply #27 on: October 04, 2019, 04:41:45 pm »
If you want to learn C, the original book
"The C programming language"
by Kernighan and Ritchie.

As others have pointed out, it will not directly work on Arduino. Some tailoring required.

Personally, I have not seen ANY Arduino example code that even bearly resembles C++
It all looks like some sort of C.

Everybody should have that book on their bookshelf, it's a classic!  The "ANSI Version" should be on the desk.
https://www.amazon.com/Programming-Language-ANSI-Version/dp/8131704947

When working with the Arduino, learning C is a secondary topic.  The more important part of the project will be interacting with the hardware.

Everything that can possibly be done with an Arduino has already been done and the project is out on the Internet, complete with code.  Pretty much everything can be built with copy-and-paste.

Still, the Arduino code is mostly C and is useful for a learning environment.  But, in the end, it's all about interacting with the hardware and library code abounds.
 

Online MarkF

  • Super Contributor
  • ***
  • Posts: 1380
  • Country: us
Re: Good C programming books
« Reply #28 on: October 05, 2019, 12:06:54 am »
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 2859
  • Country: us
Re: Good C programming books
« Reply #29 on: October 05, 2019, 12:47:21 am »
I'll put in a word for "C Traps and Pitfalls", by Andrew Koenig. It doesn't pretend to be comprehensive, but it covers many of the most common mistakes that are easy to overlook, either by inexperienced programmers or due to shortcomings of the language and operating environments. It's pretty old, so some of the more recent issues around Undefined Behavior are not explored in as much detail as you can find today.
 

Offline jackthomson41

  • Regular Contributor
  • *
  • Posts: 53
  • Country: us
Re: Good C programming books
« Reply #30 on: October 10, 2019, 03:58:18 pm »
For learning Embedded, the best book is "PIC Microcontroller & Embedded Systems using Assembly & C Language" by Mazidi , there are also his books for Atmel & AVR.
 

Offline SimonR

  • Regular Contributor
  • *
  • Posts: 111
  • Country: gb
Re: Good C programming books
« Reply #31 on: October 21, 2019, 04:00:03 pm »

Code: [Select]
void loop() {
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue);
  delay(1);
}

What the heck do you call Serial.println(sensorValue)? That can only be C++ (or Java), not C.

You're wrong its completely legal C.

couldn't you store the pointer to a function in a structure?

You're right you can

Code: [Select]
struct {
    void(*println)(int);
} Serial = {printfunction};

void loop() {
  int sensorValue = analogRead(0xA0);
  Serial.println(sensorValue);
  delay(1);
}
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 2859
  • Country: us
Re: Good C programming books
« Reply #32 on: October 22, 2019, 10:26:16 pm »
So a function named println is only capable of taking ints? Something is very fishy here.

The reason that the code cannot be C is that it uses polymorphism (the printing function is either overloaded or uses template metaprogramming), not the presence of the direct selection operator.
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 1592
  • Country: us
Re: Good C programming books
« Reply #33 on: October 22, 2019, 11:40:52 pm »
So a function named println is only capable of taking ints? Something is very fishy here.

The reason that the code cannot be C is that it uses polymorphism (the printing function is either overloaded or uses template metaprogramming), not the presence of the direct selection operator.

Pretend he wrote "foo" instead of "println" then, and that foo is declared as "void foo(int);". Then you won't drag in unstated assumptions about unstated libraries that have nothing to do with the point being demonstrated.
« Last Edit: October 22, 2019, 11:42:32 pm by Nusa »
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 1122
  • Country: nz
  • Currently at SiFive, previously Samsung R&D
Re: Good C programming books
« Reply #34 on: October 23, 2019, 02:31:54 am »
So a function named println is only capable of taking ints? Something is very fishy here.

The reason that the code cannot be C is that it uses polymorphism (the printing function is either overloaded or uses template metaprogramming), not the presence of the direct selection operator.

Pretend he wrote "foo" instead of "println" then, and that foo is declared as "void foo(int);". Then you won't drag in unstated assumptions about unstated libraries that have nothing to do with the point being demonstrated.

Here is "ASCIITable", one of the demo programs included with the Arduino IDE (with absolute beginner comments stripped out for compactness):

Code: [Select]
void setup() {
  Serial.begin(9600);
  while (!Serial) {
  }
  Serial.println("ASCII Table ~ Character Map");
}

int thisByte = 33;

void loop() {
  Serial.write(thisByte);
  Serial.print(", dec: ");
  Serial.print(thisByte);
  Serial.print(", hex: ");
  Serial.print(thisByte, HEX);
  Serial.print(", oct: ");
  Serial.print(thisByte, OCT);
  Serial.print(", bin: ");
  Serial.println(thisByte, BIN);

  if (thisByte == '-') {
    while (true) {
      continue;
    }
  }
  thisByte++;
}

Please explain how this could be C, not C++.

The context was clearly "the Arduino language", so the Arduino library is hardly an "unstated assumption".
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 1592
  • Country: us
Re: Good C programming books
« Reply #35 on: October 23, 2019, 04:31:30 am »
Except that SimonR's point was that that syntax was possible in C. He'd have to have his own println() function, but it's POSSIBLE.

But, now that you've pointed out the context, yes, the Arduino implementation of Serial is certainly a C++ object. The source code is easily found if you really want to see the implementation. There's no mystery at all if one knows enough to read it.

When someone talks about the "Arduino Language", if you choose to call it that, it means they're using a C++ compiler with a library of documented functions, implemented both C and C++, built on top of the wiring framework (implemented in C, usually), which in turn is another library with a default main() that calls setup() and loop() and a collection of hardware interface functions.

All of which is completely optional. You'll notice in my examples above, I used a main(), and the only wiring functions I called were init() and delay(). I didn't feel the need to spend time implementing delay() myself for an example.
 

Online westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #36 on: October 24, 2019, 04:25:44 am »
Quote
Quote
Code: [Select]
  Serial.println(sensorValue);What the heck do you call Serial.println(sensorValue)? That can only be C++ (or Java), not C.
You're wrong its completely legal C.
As soon as you make it:
Code: [Select]
  Serial.println("Sensor Value is");
  Serial.println(sensorValue);
You need C++ (assuming that "sensorValue" isn't a char* pointer or literal string.)
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #37 on: October 24, 2019, 03:41:14 pm »
Yup. We already went through this with the real "Serial" declaration itself, which could not be C.

Of course, if you conveniently omit its declaration (or provide a different one), the rest of the code could look like C, but as westfw just noted, the fact that parameters of different and incompatibles types are passed to the println() function shows it can't be C.

Checkmate. :horse:

Edit: For the most up-to-date C programmers out there, this isn't entirely true. If you're using a C11-compliant compiler, you could have defined println() as a macro, using the new _Generic keyword, expanding to different versions of the println() function depending on the type of its parameters.
So...
Yes, it could be C11. How many of you know the C11 additions though? ::)
And then, the typical declaration of objects (using constructors), which are used ubiquitously in Arduino's libraries, would still not work.

In the end, are we going to endlessly arguing that Arduino could be C(11), whereas it's clearly built on C++?

« Last Edit: October 24, 2019, 03:51:30 pm by SiliconWizard »
 

Offline bsfeechannel

  • Frequent Contributor
  • **
  • Posts: 893
  • Country: 00
Re: Good C programming books
« Reply #38 on: October 24, 2019, 05:43:53 pm »
And then, the typical declaration of objects (using constructors), which are used ubiquitously in Arduino's libraries, would still not work.

You mean like that?
Code: [Select]
#include "Class.h"

int main()
{
Class obj = Class( 1 );
}

Code: [Select]
//Class.h
 #define Class( x ) { (x) }

typedef struct {
int somerandomvariable;
} Class;
« Last Edit: October 24, 2019, 05:57:56 pm by bsfeechannel »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #39 on: October 24, 2019, 07:26:20 pm »
Ahah, good one. It's relying on the fact that function-like macros are expanded only if invoked with the parentheses. Although it can find some practical uses, I would consider doing this really bad coding practice. But anyway, this wasn't the point I guess.

I see this has become a C++ look-alike contest. Or I dunno what.

Still, your example doesn't cover the much more usual way of using constructors implicitly, which can be seen in almost all Arduino code: (actually I hadn't seen the explicit way in like ages, except with the 'new' operator)
Code: [Select]
Class obj(1);
Seriously guys. Arduino is all built on C++. Deal with it and move on.
« Last Edit: October 24, 2019, 07:28:21 pm by SiliconWizard »
 

Online dunkemhigh

  • Super Contributor
  • ***
  • Posts: 1459
Re: Good C programming books
« Reply #40 on: October 25, 2019, 02:47:28 pm »
Quote
the fact that parameters of different and incompatibles types are passed to the println() function shows it can't be C

Code: [Select]
#define cppclone(...)   cppfake(unused, __VA_ARGS__)
Quote
Checkmate.

Practically, but literally?
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #41 on: October 26, 2019, 12:38:00 am »
Quote
the fact that parameters of different and incompatibles types are passed to the println() function shows it can't be C

Code: [Select]
#define cppclone(...)   cppfake(unused, __VA_ARGS__)

Hehe. I see this has sparked some kind of contest. Looks a bit like an obfuscated C contest of some kind, but that's fun.
As I said in my "edit" section, there's actually a standard way of doing this properly in C11 with the _Generic keyword. For people interested, please look it up. It can be pretty handy. (Of course, some coding rules you may be subjected to may forbid its use, just like they would generally forbid any fancy preprocessor stuff.)

In your example, meant to work with earlier versions of the C standard, there are a couple issues.

First, and this is minor (due to a quick typing from your part) is that "unused" is undefined? I get your point, such C functions would require a dummy parameter to make use of variadic parameters, but the passed parameter could be just anything. I would write this instead:

Code: [Select]
#define cppclone(...)   cppfake(0, __VA_ARGS__)
then the cppfake() function could be declared like so:
Code: [Select]
xxx cppfake(int unused, ...)

The main problem with this is that there is no means of passing the types of the expected parameters to the function. To use variadic parameters in C, you need to know the type of each parameter, and their number. The well-known printf() does this through the format parameter. There is no way around it. You can't auto-detect the variadic parameters. So this approach would not be usable.

Supposing you find a way (through the preprocessor) to pass the types and number of parameters in a transparent manner (good luck), it would be so horrendous and bug-prone, bypassing all compiler type-checking, potentially doing very nasty stuff to the stack... eek. And being very inefficient, preventing the compiler to do a whole range of optimizations.

All this could be fun to discuss in a separate thread, but promoting funky (or borderline desastrous) C constructs in a thread that was meant to be about learning C properly is definitely not a good idea IMO.

As one of the users said, "I can write C in almost any language" or something.
And now it's evolving into "I can write C++ in almost any language" :-DD
« Last Edit: October 26, 2019, 12:41:11 am by SiliconWizard »
 

Online dunkemhigh

  • Super Contributor
  • ***
  • Posts: 1459
Re: Good C programming books
« Reply #42 on: October 26, 2019, 07:22:38 am »
Quote
I would write this instead:

A case of fingers getting ahead of brain. Your expansion is how it should be, yes.

Quote
The main problem with this is that there is no means of passing the types of the expected parameters to the function.

Indeed! I was aware of that but left it as an exercise for the reader to complete :)

However, it should be born in mind that this isn't intended to cover all possible circumstances. Even in C++ you still need to write the handlers before it would compile. Having said that, I can't off-hand think of a suitable handler for the cases where you might pass, say, an int or pointer.

Quote
it would be so horrendous and bug-prone

Yes. I wouldn't recommend it! In fact, I wouldn't have bothered thinking of it were it not for the checkmate comment  >:D
 

Online westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #43 on: October 26, 2019, 08:42:45 am »
I did consider that in the old days, you could do:
Code: [Select]
int cppfunc(arg)
    void *arg;  /* accept any type of argument, maybe */
{
    PORTB = (int)arg;
}

int main() {
    cppfunc(1);
    cppfunc(PORTB);
    cppfunc("test");
}
But it was such a bad idea that I didn't mention it.  (you CAN still do this.  Don't!)

 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #44 on: October 26, 2019, 02:39:23 pm »
Some stupid guys at a company that does not even deserve to be mentioned, defined five layers of define of define of define of define of WTF, resulting a mess, and they ask money to tell you what WTF should be equal to what, with which details and consideration.

 :-DD
 

Online legacy

  • Super Contributor
  • ***
  • Posts: 4309
  • Country: ch
Re: Good C programming books
« Reply #45 on: October 26, 2019, 02:40:36 pm »
I am on a piece of code with five level of #define of #define of #define of #define of #define of ...

... what? I am lost  :-DD 
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #46 on: October 26, 2019, 02:45:35 pm »
I did consider that in the old days, you could do:
Code: [Select]
int cppfunc(arg)
    void *arg;  /* accept any type of argument, maybe */
{
    PORTB = (int)arg;
}

int main() {
    cppfunc(1);
    cppfunc(PORTB);
    cppfunc("test");
}
But it was such a bad idea that I didn't mention it.  (you CAN still do this.  Don't!)

It's 1/ limited to a fixed number of parameters so doesn't fully address the question, 2/ going to do nothing like what the user probably expects, and 3/ the compiler will spit out warnings for parameters with any other type than a pointer, unless you explicitly cast in the function call, which would look ugly and certainly not "transparent" as far as passing any type goes. So first and second calls will yield warnings. And no, ignoring warnings is definitely never a good idea either.

For 2/, your third call is just going to issue a write to PORTB with the truncated pointer value of the string, which would certainly do nothing useful here...
« Last Edit: October 26, 2019, 02:48:32 pm by SiliconWizard »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #47 on: October 26, 2019, 02:46:29 pm »
I am on a piece of code with five level of #define of #define of #define of #define of #define of ...

Could you post the chain of 5 #defines so we can have a laugh?
 

Online legacy

  • Super Contributor
  • ***
  • Posts: 4309
  • Country: ch
Re: Good C programming books
« Reply #48 on: October 26, 2019, 05:29:15 pm »
Could you post the chain of 5 #defines so we can have a laugh?

it's spread among several files. In the top header file, there are defines depending on #ifdef #else whose conditions are grabbed from the usual Kconfig mechanism with a simple #include "config.h" autogenerated according to the the user choices done on the menu config, but when you look at what they define, things go deeper into other includes , which only partially define other things, defined in a sub-layer, and again the same, and again the same, and again the same, like a tree which grows from roots to trunks and leaves

Grep says this stuff goes deep from the top to something like 25 files involved, whose low level is practically impossible to be read because there are too many branches and I am not able to follow.

In my case, I counted 5 layers of defines, but I am not really sure that I am observing the right code. I mean, what GCC actually compiles.

Devs must have lost their head for having made this, or they just want to be evil, masters, and mistresses of evil

Because this is really evil, and dark  :-DD


:palm: )
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #49 on: October 26, 2019, 06:22:24 pm »
Oh well, this kind of monster often grows from a code base 1/ maintained by different people using different styles and 2/ meant to be built with many different configurations on many different platforms. Handling that cleanly is hard.
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 1592
  • Country: us
Re: Good C programming books
« Reply #50 on: October 26, 2019, 07:38:09 pm »
Code: [Select]
/// moved here for this example. PIND0 is a platform-specific number defined elsewhere
 #define DIO0_PIN PIND0

 #define MASK(PIN) (1 << PIN)

/// check if pin is an input
 #define _GET_INPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) == 0)

/// check if pin is an input wrapper
 #define GET_INPUT(IO) _GET_INPUT(IO)

Well, here's a real-life case of 5 layers before even getting out of the header file: GET_INPUT(0), _GET_INPUT(0), MASK,  DIO0_PIN, PIND0
Token pasting (##) can both be magic and confusing. This is a pretty simple case. If you don't understand why the final wrapper is needed, look up "Stringification".
(These were swiped from fastio.h in some Repetier printer firmware.)
 

Online legacy

  • Super Contributor
  • ***
  • Posts: 4309
  • Country: ch
Re: Good C programming books
« Reply #51 on: October 26, 2019, 11:21:50 pm »
built with many different configurations on many different platforms

Yes, it seems so. Different architectures, configurations, vendors, and platforms.

I have never given an eye to the layer0, but I need to know exactly where a couple of registers are defined, and which low-level code does handle them.

It looked a simple task, a piece of cake ... I am still digging around :D
 

Online westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #52 on: October 27, 2019, 12:38:57 am »
Quote
Code: [Select]
    int cppfunc(arg)
        void *arg;  /* accept any type of argument, maybe */
    {
        PORTB = (int)arg;
    }

It's 1/ limited to a fixed number of parameters so doesn't fully address the question.

Nah.  Before varargs was standardized, you could do magic with a pointer to the last argument, or something like that.  I've tried to forget...


Quote
3/ the compiler will spit out warnings for parameters with any other type than a pointer

Nope.  It's an old-style K&R definition, which essentially gets no type checking at all.  The whole program as show compiles with no warnings, even with "-Wall" (avr-gcc)...  The function call will put as many arguments as you give it (as "ints", usually) whereever it puts them, and the function will interpret them as it sees fit...


Quote
2/ going to do nothing like what the user probably expects
   ... which would certainly do nothing useful here...
It wasn't written to be a functional example.
Like I said, I'm trying to forget all the ways that we abused C to do what we wanted it to, before better ways were standardized.

The other thing you can do is write assembly language subroutines that do anything you want.  I think we still use "caller()" that returns the address that the previous function was called from..
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 1092
  • Country: fi
    • My home page and email address
Re: Good C programming books
« Reply #53 on: October 27, 2019, 12:56:30 am »
I think we still use "caller()" that returns the address that the previous function was called from..
GCC provides that as __builtin_extract_return_addr(__builtin_return_address(level)), with level==0 yielding the return address of the current function, and level==1 the return address of the previous function.  I've also used __builtin_frame_address(level) for the corresponding stack frame.

Some of this nonstandard stuff is exceedingly useful in debugging and such; probably why they still exist.
 

Online legacy

  • Super Contributor
  • ***
  • Posts: 4309
  • Country: ch
Re: Good C programming books
« Reply #54 on: October 27, 2019, 04:40:30 pm »
I see there are #define __weak defining a prefix for functions.

What is this ___weak attribute used for?
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #55 on: October 27, 2019, 05:27:08 pm »
I see there are #define __weak defining a prefix for functions.

What is this ___weak attribute used for?

This is a GCC attribute, non-standard, but can be pretty handy (although also slippery).
This allows to define a function that can be overriden without causing a symbol clash. Meaning, if a function is defined "weak", you can further define a function with the same identifier, in which case the latter will be used.

One way it can be useful in embedded dev for instance, is that you can provide a weak definition for all interrupt/exception handlers, with a default behavior. Then you can easily override any of them.

https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 1092
  • Country: fi
    • My home page and email address
Re: Good C programming books
« Reply #56 on: October 27, 2019, 09:50:05 pm »
Yep, what SiliconWizard wrote.

Furthermore, it exposes the weak symbol facility ELF files provide; it does not actually generate different code, just marks that symbol weak/overridable in the symbol table.  So, it has everything to do with ELF object files and linking, and nothing to do with C per se.
 

Offline MarkL

  • Supporter
  • ****
  • Posts: 1542
  • Country: us
Re: Good C programming books
« Reply #57 on: October 28, 2019, 12:12:34 am »
Edit: For the most up-to-date C programmers out there, this isn't entirely true. If you're using a C11-compliant compiler, you could have defined println() as a macro, using the new _Generic keyword, expanding to different versions of the println() function depending on the type of its parameters.
So...
Yes, it could be C11. How many of you know the C11 additions though? ::)
I don't the know intricacies of C11 additions, but GCC has supported a similar thing called __builtin_types_compatible_p(TYPE1, TYPE2) which tests whether TYPE1 is compatible with TYPE2.  A series of if's could be built up to handle multiple types.

Apparently _Generic is in gcc as of 4.9, but the functionality isn't new.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf