any quick recs for starting points for c for the object-oriented language oriented ? either web reference or a book I can find at the library or buy cheap-ish.

I found Essential C somewhere in this thread which seems pretty decent.

4 Likes

so I kinda just realized how much of a funny question that was - I sat down with that pdf and “learned C” in like two hours

cuz that’s the whole thing right, it’s “”“simple”"", as in barely any syntax, but complex to execute. so “learning C” is going to be much more about reading code in the style that I need to use it. that’s a big step away from how learning other programming languages work.

idk just a funny/neat realization at 9:40 pm

7 Likes

Syntactically, C is fairly simple. The bigger gotchas are things like memory leaks, segmentation/bus faults, and undefined behavior. Those really suck because you can have code that looks completely innocent but will actually crash when you try to run it. It is feature of C that makes it very special :wink:

In fact, there is a whole contest for doing just this: https://en.wikipedia.org/wiki/Underhanded_C_Contest

3 Likes

4 posts were merged into an existing topic: Lower-level audio programming

I haven’t read through all of it yet, and as always with these things you may not agree with everything…

But I’ve already found out about -Wdouble-promotion which is pretty useful on embedded devices!

e.g. from the article

bool float_promotion_example(float val) {
  return val > 2.6;
}

Will cause val to be promoted to a double for the comparison (fixed with a 2.6f instead). That’s just the kind of silly mistake that I’d make all the time!

Sadly the -Wdouble-promotion is too new to be included in avr32-gcc

3 Likes

I’m wondering if there’s an easy way to set one C++ array equal to another…
Something like

float array1[16] = {1, 2, 3, 4, 5,…}, array2[16];
array2 = array1;

Is there a simple way to do this? should I actually be using vectors? and so on

It’s been a while since I’ve done any C++, so AFAIK…

Using C arrays in C++ will give you C semantics, so array2 = array1 is just 2 pointers to the same array (aka aliasing), and not a copy.

If you want to copy C arrays then you need to use memcpy.

But… in C++ it’s better to use STL based data structures, so either vector or array. Have a look at this for the various copy methods.

When I did do C++ I always used to use https://en.cppreference.com/w/ to look stuff up (it’s good for the C standard library too), it’s not the easiest as a beginner… but it’s worth trying to figure out your way round.

Thanks a lot my friend. Now I can try and make my VCV module not crash Rack in its entirety…

just echoing with examples…

in C, use memcpy, and be careful:

#include <string.h>
#include <stdio.h>

#define SIZE 10 // can't initialize stack-allocated C-style arr with variable size

int main() {

    typedef float sample_t;
    sample_t a[SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    sample_t b[SIZE];
 
    memcpy(b, a, SIZE * sizeof(sample_t));

    // change stuff in `a`
    for (int i=0; i<SIZE; ++i) {
	a[i] = i * 2;
    }

    // print `b`
    for (int i=0; i<10; ++i) {
	printf("%f ", b[i]);
    }
    printf("\n");
}

in C++, prefer std::array (fixed size) or std::vector (mutable size), and built-in copy semantics:

#include <array>
#include <iostream>

constexpr size_t size = 10; // yay, `constexpr` exists
typedef float sample_t;

int main() {
    typedef std::array<sample_t, size> arr_t;
    arr_t a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    arr_t b;
    b = a; // copies

    // change stuff in `a`
    for (int i=0; i<size; ++i) {
	a[i] = i * 2;
    }

    // print `b`:
    for (auto& x: b) {
	std::cout << x << " ";
    }
    std::cout << std::endl;
}

5 Likes

Thanks, that’s really helpful

Does anyone have a favourite data structures library for C? I’m guessing something macro based…?

In particular I’m looking for a linked list (single or double), and a queue. Heap allocated / malloc is fine, though it would be nice if the queue had the option of pre-allocating with a max size.

And along similar lines, anyone have any techniques for making tagged unions easy to work with?

Those are usually so simple it’s worth writing your own for; I rarely use libraries for things that aren’t highly complex (like an rtos or a vendor abstraction layer).

2 Likes

For linked lists I generally prefer to add my own code directly to the class/struct that’s being stored in them. It’s just a matter of adding next/previous pointers to the same class, and static front/back pointers.

For C++ I stick with the good ol’ Standard Template Library.

maybe sys/queue.h and sys/tree.h, from the BSD libc extensions? these are macro-based and most queue operations are O(1).

{ https://github.com/freebsd/freebsd/blob/master/sys/sys/queue.h }
{ https://github.com/freebsd/freebsd/blob/master/sys/sys/tree.h }

2 Likes

That’s certainly one way to abuse the macro system in C. Still interesting though. Makes me wonder what they are used for internally.

Couldnt see a mention of Numerical Recipes In C - this has been a bible for me for years… really handy for basic efficient algorithms, especially useful for embedded stuff…

1 Like

I’ve been successfully navigating some larger C codebases in emacs using xcscope. This emacs/cscope combo is really simple and easy to learn (assuming you’ve already drunk the emacs Koolaid) - highly recommended.

Kind of curious whether cscope is a popular choice in 2020 - I’m sure it’s ancient… Don’t have much experience of the other options (other than grep obviously)

Haven’t used it or heard of it–certainly drunk off the emacs kool-aid so next time I’m browsing a load of C I’ll see if this comes in handy!

I looked into this recently, accidentally bought the examples book (showing use cases of the library code) instead of the book itself.

The code is very strictly licensed so I’m curious if the book itself is a good resource for learning how to implement patterns or just a recipe book that needs to be licensed if you want use it?

Well well well.

GCC 10 defaults to -fno-common :tada:

C language issues

Default to -fno-common

A common mistake in C is omitting extern when declaring a global variable in a header file. If the header is included by several files it results in multiple definitions of the same variable. In previous GCC versions this error is ignored. GCC 10 defaults to -fno-common, which means a linker error will now be reported.

Remember kids, friends don’t let friends C without -fno-common.

3 Likes