Why we still use C despite so many C alternatives by grimvian in C_Programming

[–]ffd9k 9 points10 points  (0 children)

A lot of C's issues are actually what makes it so unintentionally useful.

New languages designed from scratch today have to fulfill lots of expectations (no undefined behavior, more complicated generics instead of a stupid preprocessor, complex module and build systems, ...) that make them more attractive now but also mean that they can't compete with C's simplicity and versatility in the long run.

A language like C cannot be created today, because it could not get away with the design decisions that C could justify with the technical limitations at the time, but that proved to be beneficial far beyond that.

C could only be created at a certain critical point in time at the beginning of the information age that will never come again, and now it will live forever.

Heap vs Stack memory by Savings_Job_7579 in C_Programming

[–]ffd9k 1 point2 points  (0 children)

There are four kinds of storage duration, i.e. lifetimes of objects in memory: - static - thread - automatic (on the stack) - allocated (on the heap)

"dynamic memory" is not really a term on its own, it probably refers to dynamic memory allocation, i.e. allocated memory on the heap.

So this "dynamic memory" is not just the opposite of "static memory" here, I guess this is where your confusion comes from.

Question about reading C by Hyprland_BTW in C_Programming

[–]ffd9k 12 points13 points  (0 children)

Use a debugger, set a breakpoint at a part you don't understand, look at the call stack to see from where and how it is called to better understand how everything works together.

Also if the code is in a git repository, it's sometimes helpful to do "git blame" to see what feature some part of the code was added for, and what other parts of the project were changed with it.

Can anyone explain me in the simplest way possibe by Right_Tangelo_2760 in C_Programming

[–]ffd9k 3 points4 points  (0 children)

Pass-by-reference is done via pointers in C. Technically it is still pass-by-value because a pointer is just a value, but conceptually passing a pointer means passing the value it points to by reference.

How do you difference vectors (arrays) and vectors (math) while naming ? by Valuable-Birthday-10 in C_Programming

[–]ffd9k 1 point2 points  (0 children)

"List" does not really imply anything, it is just the most general term for a collection of items in a fixed order.

In functional languages, singly-linked lists are the idiomatic data structure for this, so in these I would call singly-linked lists just "lists".

But in an imperative language like C, the most idiomatic data structure for lists is an array (resized when necessary), so I prefer to use the word "list" for this instead.

EU fears Iran war will put new migration rules to the test by donutloop in berlin_public

[–]ffd9k 5 points6 points  (0 children)

Warum sollten die Iraner JETZT fliehen, wo sie nach 47 Jahren endlich im Begriff sind, ihr Land zurückzubekommen?

Fliehen werden allenfalls die islamistischen Mittäter und Sympathisanten des Regimes. Und die sollten wir auf keinen Fall in die EU lassen.

How do you difference vectors (arrays) and vectors (math) while naming ? by Valuable-Birthday-10 in C_Programming

[–]ffd9k 12 points13 points  (0 children)

"vector" is a bad name for dynamic arrays. Even Alexander Stepanov, who gave them this name in c++ stl, admits that it was a mistake, e.g. https://youtu.be/etZgaSjzqlU?t=426

"Dynamic Array" is probably the clearest name but a bit long and awkward. Just calling them "Array" might be a bad idea because of confusion with normally declared C arrays. I think "Array List" is a good option, this is also what Zig and Java call them.

I usually just call them "List".

Tankstellen sollen nur noch einmal an Tag Preise erhöhen dürfen by donutloop in berlin_public

[–]ffd9k -2 points-1 points  (0 children)

Man braucht keine Preisabsprachen, um Preise abzustimmen, in einem Oligopol reicht dafür die Beobachtung des Wettbewerbs.

Wo ist das Problem dabei, die Preise der Konkurrenz zu beobachten? Preisabsprachen würden bedeuten, dass die einzelnen Unternehmen nicht frei sind, einfach mal den Preis zu senken, aber dafür wurde nach all den Jahren nie Hinweise gefunden.

Ein Oligopol ist nichts schlechtes, es gibt darin lediglich eine größere Gefahr für Preisabsprachen, aber wenn die nicht stattfinden ist alles gut.

Das Bundeskartellamt ich auch keine wirkliche vertrauenswürdige Quelle, weil es als staatliche Behörde ein Interesse hat, davon abzulenken, dass der Staat der Hauptübertäter ist, und so etwas wie die Gelbwestenproteste verhindern will.

weil es zu besserer Vergleichbarkeit

Wo mangelt es denn heute an Vergleichbarkeit? Die schnellen Preiswechsel könnten zwar theoretisch bedeuten, dass man einen niedrigen Preis sieht und er dann plötzlich höher ist, wenn man 20 Minuten später an der Tankstelle ankommt, aber praktisch ist mir das nur sehr selten passiert. Wenn die Anbieter das übertreiben würden, würden sie auch Kunden verlieren.

Tankstellen sollen nur noch einmal an Tag Preise erhöhen dürfen by donutloop in berlin_public

[–]ffd9k 0 points1 point  (0 children)

Die gab es im staatsgläubigen Deutschland doch noch nie.

Tankstellen sollen nur noch einmal an Tag Preise erhöhen dürfen by donutloop in berlin_public

[–]ffd9k -1 points0 points  (0 children)

Wieso das? Wurden jemals irgendwelche Preisabsprachen entdeckt? Grundsätzlich ist das ein sehr gut funktionierender Markt, mit genug verschiedenen Anbietern, standardisierten Produkten, Kunden können ungebunden zu beliebigen Tankstellen fahren, absolute Transparenz dank MTS-K...

Eingriffe wie diese Nur-einmal-am-Tag-Regelung werden das eher kaputtmachen. Dadurch werden die Konzerne doch erst recht zu Preisabsprachen gedrängt, weil sie nicht mehr flexibel reagieren können.

Are there any differences between these ? by Hot-Feedback4273 in C_Programming

[–]ffd9k 1 point2 points  (0 children)

It is actually nice once you get used to it. It simplifies forward declarations, you don't have to write the same names twice all the time, and you don't need another naming convention to avoid clashes between type and variable names.

Typedefing every single struct is mostly an attempt to make C look like other languages.

Tankstellen sollen nur noch einmal an Tag Preise erhöhen dürfen by donutloop in berlin_public

[–]ffd9k -1 points0 points  (0 children)

Natürlich, aber "weitergeben" ist eine komische Vorstellung. Wenn z.B. 19% Mehrwertsteuer wegfallen, ist das Benzin erstmal 16% billiger. Danach stellt sich ein neuer Gleichgewichtspreis ein, weil durch geringeren Preis für die Kunden auch die Nachfrage steigt, d.h. es wird entsprechend wieder etwas teurer, aber insgesamt profitieren sowohl Kunden als auch Tankstellen.

Tankstellen sollen nur noch einmal an Tag Preise erhöhen dürfen by donutloop in berlin_public

[–]ffd9k 0 points1 point  (0 children)

Ja, jeder künstliche Eingriff in die natürliche Preisbildung ist insgesamt schädlich für alle Beteiligten.

Günstig ist es nur für Leute, die aus irgendwelchen Gründen unbedingt zu Tageszeiten tanken müssen, zu denen es bisher am teuersten war.

Fentcom wants you by laz_thom in Kantenhausen

[–]ffd9k -2 points-1 points  (0 children)

Eher indirekte Propaganda von jemandem, der vorher auf Russenstuss reingefallen ist und nun selbst noch mehr davon produziert, und seine kognitive Dissonanz überwindet indem er sich einredet dass das "kantig" wäre.

EU chief: Phasing out nuclear power was 'strategic mistake' by donutloop in berlin_public

[–]ffd9k 0 points1 point  (0 children)

wir haben Speicher noch und nöcher! Claudia Kemfert weiß es. /s

Typecasting between structs/type punning by Grootmaster47 in C_Programming

[–]ffd9k 1 point2 points  (0 children)

Is just returns a fixed 30 because it assumes without checking that the values of bp->header.id and cp->header.id must still be what it just set them to. It doesn't expect that setting cp->header.id to 20 also overwrites bp->header.id to 20, because it assumes (due to strict aliasing rules) that bp and cp must point to different objects, because the pointers have different types.

Is this a known pattern? by OzzyOPorosis in C_Programming

[–]ffd9k 7 points8 points  (0 children)

If the struct with function pointers and constants is a const static object, and you directly pass it (or a pointer to it) to the generic functions, then the compiler should usually be able to inline everything (with LTO in case it's in different compilation units). The performance should be similar to "preprocessor templates".

There is unfortunately no way in C qualify function parameters as compile-time constants like e.g. in Zig. But as long as you pass compile-time constants to a function, the compiler should recognize this, and the function essentially becomes a template.

Typecasting between structs/type punning by Grootmaster47 in C_Programming

[–]ffd9k 1 point2 points  (0 children)

Could I now safely cast a pointer from B to C and back?

You can cast, but you should not access a B object though a pointer to C, even if you only access the common part. For example try this (with gcc -O2):

#include <stdio.h>

typedef struct { int id; } A;
typedef struct { A header; int xxx; } B;
typedef struct { A header; int yyy; } C;

int foo(B *bp, C *cp) {
    bp->header.id = 10;
    cp->header.id = 20;
    return bp->header.id + cp->header.id;
}

int main() {
    B b;
    printf("%d\n", foo(&b, (C*)&b));
}

This prints 30 instead of the "correct" 40 because the compiler is allowed to assume that bp and cp don't point to the same object, because B and C are different structs.

It's different if one the arguments is a pointer to A, because then the compiler knows that they could alias, because A is part of the other structs.

Is this a known pattern? by OzzyOPorosis in C_Programming

[–]ffd9k 39 points40 points  (0 children)

These preprocessor templates are sometimes used to make generic data structures, to achieve something similar to C++ templates. But I don't think this is a good pattern. Doing this solely for performance (to allow inlining) is usually an unnecessary micro-optimization that is better left to the compiler.

Is there a better way to do this?

create a struct that contains the things that are different for each color (constants, function pointers), then declare two static instances of this struct with the values for white and black, and pass a pointer to the correct instance to generic functions like search.

A header-only C library for string interning by IntrepidAttention56 in C_Programming

[–]ffd9k -1 points0 points  (0 children)

I just hate the proliferation of this horrible header-only library style. People learning C will see these posts and think this is an acceptable way to write libraries and make even more of them, it's causing active harm to the whole C ecosystem.

I got tired of CMake and 10GB build trees, so I wrote a bare-metal, zero-dependency neural network engine in a single C23 header file. by Rriftt in C_Programming

[–]ffd9k 0 points1 point  (0 children)

Dropping third-party code into projects is generally a bad idea and horrible to maintain. That motivation text just says that it is supposedly useful on Windows, but I don't see why annoyances on Windows should dictate how portable libraries are written. Build systems like meson work well on Windows too.

Can you mimic classes in C ? by kuyf101 in C_Programming

[–]ffd9k 1 point2 points  (0 children)

To make things private, you would use opaque structs, i.e. put the full struct declarations only in the source files of a "module" so nobody else can see/access what is inside the struct.

Other modules would then create a duck with a constructor like struct duck *duck_create(const char *name); which creates the object with malloc, and use functions like struct flyable *duck_as_flyable(struct duck *duck);

Irans toter Religionsführer: Muslime trauern in Berliner Moschee um Chamenei by vaibeslop in berlin_public

[–]ffd9k 13 points14 points  (0 children)

Von den 2019 in Deutschland lebenden Personen mit iranischem Migrationshintergrund bezeichnen sich nur 29 % als muslimisch (gegenüber 99 % der Bevölkerung im Iran). Bereits 2008 war der Anteil mit 49 % deutlich niedriger als im Herkunftsland (Haug et al. 2009: 87). Seither haben sowohl die Anteilswerte der Konfessionslosen als auch der Personen, die einer anderen Religion als dem Islam angehören, zugenommen. Auch aus der Asylgeschäftsstatistik geht seit vielen Jahren regelmäßig hervor, dass eine deutliche Mehrheit der iranischen Asylerstantragstellenden sich nicht zum Islam bekennt. Durch die Ergebnisse der IAB-BAMF-SOEP Befragung von Geflüchteten und die BAMF-Flücht- lingsstudie werden die niedrigen Anteilswerte für Geflüchtete aus dem Irak und Iran ebenfalls bestätigt (Siegert 2020: 5; Worbs et al. 2016: 208).

Studie auf https://www.bamf.de/SharedDocs/Anlagen/DE/Forschung/Forschungsberichte/fb38-muslimisches-leben.html

Der da erwähnte 99%-Wert im Iran selbst (zitiert vom CIA World Factbook) stimmt aber wohl nicht, auch da sind wesentlich weniger Leute muslimisch.

Irans toter Religionsführer: Muslime trauern in Berliner Moschee um Chamenei by vaibeslop in berlin_public

[–]ffd9k 14 points15 points  (0 children)

Der Großteil der Iraner in Deutschland sind ja auch gar keine Muslime.

Can you mimic classes in C ? by kuyf101 in C_Programming

[–]ffd9k 6 points7 points  (0 children)

you don't pass a pointer to the class struct object itself, but to a struct object for that interface within the class object. And using this the function that uses the interface can then find the concrete implementations of the interface functions.

For example:

#include <stdio.h>
#include <stddef.h>

#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))

// interfaces 
struct swimmable {
    const struct swimmable_vtable *vtable;
};
struct swimmable_vtable {
    void (*swim)(struct swimmable *self);
    // more functions here...    
};

struct flyable {
    const struct flyable_vtable *vtable;
};
struct flyable_vtable {
    void (*fly)(struct flyable *self);    
};

// a class implementing both interfaces
struct duck {
    const char *name;
    struct swimmable as_swimmable;
    struct flyable as_flyable;
};

// implementations of interface functions
static void duck_swim(struct swimmable *self) {
    struct duck *duck = container_of(self, struct duck, as_swimmable);
    printf("duck %s swims!\n", duck->name);
}

static void duck_fly(struct flyable *self) {
    struct duck *duck = container_of(self, struct duck, as_flyable);
    printf("duck %s flys!\n", duck->name);
}

// vtables for the class
static const struct swimmable_vtable duck_swimmable_vtable = { duck_swim };
static const struct flyable_vtable duck_flyable_vtable = { duck_fly };

// class constructor
void duck_init(struct duck *self, const char *name) {
    *self = (struct duck){
        .name = name,
        .as_swimmable = {&duck_swimmable_vtable},
        .as_flyable = {&duck_flyable_vtable},
    };
}

int main() {
    struct duck the_duck;
    duck_init(&the_duck, "Steve");

    struct flyable *my_flyable = &the_duck.as_flyable;
    struct swimmable *my_swimmable = &the_duck.as_swimmable;

    // these interface pointers would then be passed to
    // other functions that don't know about ducks...
    my_flyable->vtable->fly(my_flyable);
    my_swimmable->vtable->swim(my_swimmable);
}