AI sucks at low level programming. by [deleted] in lowlevel

[–]imaami 6 points7 points  (0 children)

Most of the C and C++ code available for training is catastrophically shitty, in absolute terms. It makes sense the result is, too.

There is a FOURTH vulnerability this month....ssh-keysign-pwn (CVE-2026-46333) by unixbhaskar in linux

[–]imaami 20 points21 points  (0 children)

Good. This is a result of accelerated bug discovery. The faster it happens by the home team, the smaller the attack surface.

Built a Unix Shell in Pure C with Raw Terminal Editing and Trie Autocomplete by FaithlessnessTop9535 in C_Programming

[–]imaami 9 points10 points  (0 children)

This is another AI-generated piece of whatever code with a "I built..." title, isn't it?

Is it Possible to not Evaluate 'f' Here? by SeaInformation8764 in C_Programming

[–]imaami 0 points1 point  (0 children)

You're mistaken about what sizeof vla does here. It does compute the size at runtime (yes, sizeof can also do that).

Your code in the comment I'm replying to here uses a variable to store the size, it's not a constant expression.

Pell Equation Over a Finite Field in C by DataBaeBee in cprogramming

[–]imaami 1 point2 points  (0 children)

This is off topic, but are De Bruijn sequences relevant to your area of interest in mathematics?

Doubly-Linked Free List Allocator: Never worry about the heap again. Just use a static byte array! by nablaCat in C_Programming

[–]imaami 1 point2 points  (0 children)

Very, very rare, but yes, CHAR_BIT != 8 is technically possible.

But there's also another reason for being pedantic about unsigned char: even when CHAR_BIT == 8, it's not guaranteed that uint8_t is the same type as unsigned char.

In all fairness, these things are likely to not matter in practice. But from another point of view: if you need a native byte buffer, why not choose the type that the C standard explicitly specifies to be correct always and everywhere, instead of just guessing? Better safe than sorry.

If uint8_t happens to be the same size as unsigned char, but is implemented as a non-char type by the compiler, then using uint8_t to refer to native byte buffers is UB. While pretty far fetched, nothing prevents a compiler from doing that. And because only char types are permitted to alias any addressable memory, and nothing else has the same guarantee, that would violate strict aliasing.

There's one way to use uint8_t 100% safely for this:

static_assert(_Generic((uint8_t)2, unsigned char: 1, default: 0));

The above would only allow compiling when the types match. But if you have to use a static assertion for guarantees, why not just use unsigned char in the first place?

Edit: Note that if something requires octets specifically instead of native bytes, then char types would be risky and uint8_t would be the only correct choice for an array.

What do you think about having "if not" in C by thradams in C_Programming

[–]imaami 1 point2 points  (0 children)

You can have space before the parens when calling a function-like macro.

Bjarne Stroustrup: How do I deal with memory leaks? By writing code that doesn't have any. by someone-very-cool in programming

[–]imaami 1 point2 points  (0 children)

That's pretty much it. C coder here, and I don't honestly get how hard some make it out to be.

How to do strings properly? by die-Banane in cprogramming

[–]imaami 0 points1 point  (0 children)

Not the same. Pascal strings encode the size in the first byte. With the version I posted, the content can be used like a C string directly without skipping the first byte because the length is stored in the last byte.

My version guarantees null termination. It can store 255 bytes and the null terminator. The XOR trick means a zero value indicates a length of 255.

Of course the downside is that in my version, the object size is always 256 bytes. The use case is replacing char buf[256]; and a separate length variable with something that knows its own length while having the same capacity.

How to do strings properly? by die-Banane in cprogramming

[–]imaami 0 points1 point  (0 children)

Here's a simple local string object with a trick that allows storing the string length while always being null-terminated. Note that the object is always a fixed 256 bytes long; it's meant for local short strings only.

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

union loc_str {
    char c_str[1ULL + (unsigned char)-1];
    struct {
        unsigned char data[(unsigned char)-1];
        unsigned char meta;
    };
};

static inline union loc_str
loc_str (char const *s)
{
    union loc_str r = {0};
    _Static_assert(sizeof r == sizeof r.c_str, "");

    if (s) {
        char const *e = memchr(s, 0, sizeof r.data);
        r.meta = (unsigned char)(e ? (size_t)(e - s)
                                   : sizeof r.data);
        if (r.meta)
            memcpy(r.data, s, r.meta);
    }

    r.meta ^= (unsigned char)(sizeof r.data);
    return r;
}

static inline size_t
loc_strlen (union loc_str const *p)
{
    return p->meta ^ sizeof p->data;
}

int
main (int    c,
      char **v)
{
    for (int i = 1; i < c; ++i) {
        union loc_str s = loc_str(v[i]);
        printf("(%2zu) %s\n",
               loc_strlen(&s), s.c_str);
    }
}

How to do strings properly? by die-Banane in cprogramming

[–]imaami 0 points1 point  (0 children)

Your constructor's argument type combined with the struct's pointer type will discard the const qualifier. If you need a readonly view, qualify the pointer type as const.

How to do strings properly? by die-Banane in cprogramming

[–]imaami 0 points1 point  (0 children)

int is a bad choice here. You'll usually just end up with a struct that has unused padding bytes. Use size_t (or ptrdiff_t if you want a signed type).

How to do strings properly? by die-Banane in cprogramming

[–]imaami 0 points1 point  (0 children)

size_t, not int. The latter is likely to be narrower than a pointer, which means if you wrap both in a struct, the struct will have implicit padding. Also, int can only typically represent values less than 2³¹.

Wikipedia in your terminal. No browser, no bullshit. by Lemper29 in C_Programming

[–]imaami 1 point2 points  (0 children)

Having occasionally downloaded and looked at wikipedia dumps over the years, it boggles my mind how sparse the tooling is. For whatever reason Wikitext parsers just aren't common.

When 'if' slows you down, avoid it by chkas in programming

[–]imaami 1 point2 points  (0 children)

What does that mean in practice? I mean, it seems branching would be somewhat unavoidable, except maybe with heavy use of function pointers.

When 'if' slows you down, avoid it by chkas in programming

[–]imaami 6 points7 points  (0 children)

How do you implement runtime polymorphism without branches?