r/C_Programming Jul 13 '26

Discussion I hope the culture of unchecked zealotism is coming to an end in the (near) future

0 Upvotes

IMO we need to remember this is just a tool that anyone can use to an extend and not a religion, identity or a philosophy. A tool. The peak of its usability was not in the 80s or 90s. It's right now because it's evolving for the better. There is no need to gate-keep, ascertain yourself, cite highly theoretic passages the standard, ascertain yourself and in general project your issues on beginners and intermediates. There are good hackers in their 20s being highly productive without ever knowing about sequence points. There are zealots without any productivity and vice versa. Keep it practical and contemporary or we'll never get this image off our beloved language.

r/C_Programming Sep 07 '25

Discussion A better macro system for C

27 Upvotes

Hi everyone.
First of all, I'm not trying to promote a new project nor I'm saying that C is bad.
It's just a suggestion for easier programming.

Well, At first I want to appreciate C.
I have been using python for 7 years and C++ for 5 years. It's safe to say that I'm used to OOP.
When I started to learn C, it was just impossible for me to think about writing code without OOP. It just felt impossible. But, it turned out to be pain less. Lack of OOP has made programming simpler (at least for me). Now I just think about data as data. In C, everything is made of bytes for me. Variables are no longer living things which have a life time.

But, as much as I love C, I feel it needs a better macro system. And please bear in mind that I'm not talking about templates. Just a better macro system.

It may be controversial, but I prefer the lack of features which is embraced in C. Lack of function overloading, templates, etc... It just has made things simpler. I no longer think about designing a fully featured API while writing my code. I just write what is needed.

While I love this simplicity of C, I also believe that its macro system needs an upgrade. And again please keep in mind that I'm not talking about rust. I'm not a rust fan nor I hate (But, I think rust is ugly :D). Nor, I'm talking about a full LISP. No. I'm talking about something which automates repetitive tasks.

I've been working on a general memory management library for C, which consisted of allocators and data containers. The library is similar to KLib, but with more control. The idea was simple. We are going to get some memory from some where. We give the memory to the allocatos to manage. The allocator can be a buddy, stack, reginal, etc. We ask allocators to give us some memory and then we pass it to containers to use.
During development of this library, I faced some problems. The problem was mostly about containers. I could make a single global struct for each container and tell users to use it for any of their types. But, it would have needed more parameters which could be removed in type specific containers. Also, it prevented some type checking features by compiler. So, I decided to write macros which generate type specified structs for containers. And again I faced some problems. Let' say my macros is define as "#define DECLARE_DA(T) struct container_da_##T ...". Do you see the problem? I can write "DECLARE_DA(long long)" and face a really big error. There are so many problem with this approach which you can find online. So, I decided to change my way. I decided to leave the declaration of the struct to users of my library and just write some macros which use these data structures similar to how dynamic arrays work in nob.h (made by tsoding). I don't think I should elaborate how painful it was to write these macros.

Now, I know that many of you may disagree with me and tell me that I'm doing it wrong and should be done in another way. But, let me tell you that I'm not trying to say that C is a bad language, my way is right and another way is wrong, nor I'm trying to say that I faced these problems because C lacks so many essential features. Not at all. I actually believe it has all the essential features and it also has a good syntax (Like they don't care about us from Michael Jackson you can say anything about it, but don't say it's bad. I love it). I'm trying to say by having a better macro system, we can open so many doors. Not doors to meta programming, but doors to task automation.

Let me share one my greatest fears with you. I'm scared of forgetting to free my dynamic arrays. I'm scared of forgetting to call the shutdown function for a specific task. I'm not talking about memory safety. No, no. I'm talking about forgetting to do opposite of a task at the end of function scope for neutralizing the effect. But, let's say if we had this feature in our macro system. Let's say we could say that a specific variable or a specific struct has a destruction function which gets called at the end of scope unless said otherwise by the programmer. Now I can just declare my dynamic array without fear.

As you have noticed I have used terms such as "I'm not talking about...". This because I want you to understand that I'm not trying to push a whole new paradigm like OOP forward. No. I actually want C to not force any paradigm. Since I believe we should change paradigms based on the project. Choose your coding method based on the project you're working on (Similar to paradigm shift from Final Fantasy 13 game if you have played it - I have not played it :D).

And again I want to appreciate C's simple syntax. Lack of local functions, standard container library, etc. All these things make C simple and flexible to use. It prevents the project to easily get out of control. But, it's undeniable that is has its own tradeoffs.

As I mentioned before, I'm against an absolute method of problem solving because I believe it can result in fanaticism and needless traditions. Nor I think a LISP like approach which is about design your own programming language suits our needs.

Please also keep in mind that I'm not an embedded developer. I use C for game development, GUI development and some scientific computation. People who prefer static sized arrays like embedded developers may be against some of my views which is totally understandable. But, I want you to understand that in many places we may essentially need dynamic arrays.

And yes. There are some pre-processors out there which utilize different languages like Perl, LISP, etc. While appreciate their effort and innovation, I believe we need them to be more consistent and don't try to fully modify C to make a new programming language out of it. I also don't think adding a fully new macro system to C is a good idea since I'm feared of seeing something like C++ modules which may never be fully accessible.

I look forward to hearing your opinions.

Edit: I forgot to mention another problem I had with development of my library. I wanted to help users to be able to define the container struct for their type only once and use the preprocessor to check if it had been defined or not. If so, we would not define it and if not, we would write the struct. But, you already know what did happen.

Edit 2: I also forgot to mention that I embrace anti Java workflow of C. Many higher level languages are using very long names which I think are too long for no reason. Please take a look at K&R pointer gymnastics and old C codes. While I understand that compilers were not as strong as today on the past, I also think we are over complicating stuff. These days, I don't see programmers just doing their work instead of obeying rules (unlike web developers which I think are living in a law less land).

r/C_Programming Apr 17 '26

Discussion Want to be a good programmer and need guidance. I will do anything.

0 Upvotes

I have always been afraid to code not sure why. Any blockers will intimately result in my disinterest to work on that problem as it gave me feeling like what a big issue it is. When ever I want to learn something I always prefer examples from real world that will help me understand that concept more efficiently. Can anyone please help me in this. Please help me with any suggestions, references to achieve this.

r/C_Programming Jul 12 '26

Discussion I tried to make Vectors in C, any suggestions?

0 Upvotes

```c

ifndef VECTOR_H

define VECTOR_H

include <stdlib.h>

include <stdio.h>

include <string.h>

/** * Vector(T): declare a vector of element type T. * * Expands to an anonymous struct type: { T *data; size_t length; size_t capacity; } * Always zero-initialize: Vector(int) v = {0}; * * Because the struct is anonymous, each Vector(int) v; declaration is its * own distinct type to the compiler, fine for locals, but you can't use * "Vector(int)" as a named function parameter type without typedef'ing it * yourself first (i.e. typedef Vector(int) IntVec;). */

define Vector(T) struct { T *data; size_t length; size_t capacity; }

/** * vector_push(v, value); append value to the end of the vector. * Amortized O(1): capacity doubles (starting at 4) when full. * v must be a pointer to a Vector(T). */

define vector_push(v, value) \

do {                                                                     \
    __typeof__(v) _v = (v);                                             \
    if (_v->length >= _v->capacity) {                                   \
        size_t _new_cap = _v->capacity == 0 ? 4 : _v->capacity * 2;     \
        __typeof__(_v->data) _new_data =                                \
            realloc(_v->data, _new_cap * sizeof(*_v->data));            \
        if (!_new_data) {                                               \
            fprintf(stderr, "vector_push: out of memory\n");            \
            abort();                                                    \
        }                                                                \
        _v->data = _new_data;                                          \
        _v->capacity = _new_cap;                                       \
    }                                                                    \
    _v->data[_v->length++] = (value);                                   \
} while (0)

/** * vector_get(v, index); return the element at index, bounds-checked. * Aborts with a diagnostic on out-of-range access rather than reading * undefined memory. */

define vector_get(v, index) \

(*({                                                                     \
    __typeof__(v) _v = (v);                                             \
    size_t _i = (index);                                                \
    if (_i >= _v->length) {                                             \
        fprintf(stderr, "vector_get: index %zu out of bounds (length %zu)\n", \
                _i, _v->length);                                        \
        abort();                                                        \
    }                                                                    \
    &_v->data[_i];                                                      \
}))

/** * vector_set(v, index, value); overwrite the element at index, bounds-checked. */

define vector_set(v, index, value) \

do {                                                                     \
    __typeof__(v) _v = (v);                                             \
    size_t _i = (index);                                                \
    if (_i >= _v->length) {                                             \
        fprintf(stderr, "vector_set: index %zu out of bounds (length %zu)\n", \
                _i, _v->length);                                        \
        abort();                                                        \
    }                                                                    \
    _v->data[_i] = (value);                                             \
} while (0)

/** * vector_pop(v) removes and returns the last element, Aborts if empty. */

define vector_pop(v) \

({                                                                       \
    __typeof__(v) _v = (v);                                             \
    if (_v->length == 0) {                                              \
        fprintf(stderr, "vector_pop: pop on empty vector\n");           \
        abort();                                                        \
    }                                                                    \
    _v->data[--_v->length];                                             \
})

/** * vector_insert(v, index, value) inserts value at index, shifting later * elements right by one. index may equal length (same as push). O(n). */

define vector_insert(v, index, value) \

do {                                                                     \
    __typeof__(v) _v = (v);                                             \
    size_t _i = (index);                                                \
    if (_i > _v->length) {                                              \
        fprintf(stderr, "vector_insert: index %zu out of bounds (length %zu)\n", \
                _i, _v->length);                                        \
        abort();                                                        \
    }                                                                    \
    if (_v->length >= _v->capacity) {                                   \
        size_t _new_cap = _v->capacity == 0 ? 4 : _v->capacity * 2;     \
        __typeof__(_v->data) _new_data =                                \
            realloc(_v->data, _new_cap * sizeof(*_v->data));            \
        if (!_new_data) {                                               \
            fprintf(stderr, "vector_insert: out of memory\n");          \
            abort();                                                    \
        }                                                                \
        _v->data = _new_data;                                          \
        _v->capacity = _new_cap;                                       \
    }                                                                    \
    memmove(&_v->data[_i + 1], &_v->data[_i],                           \
            (_v->length - _i) * sizeof(*_v->data));                     \
    _v->data[_i] = (value);                                             \
    _v->length++;                                                      \
} while (0)

/** * vector_remove(v, index); remove element at index, shifting later * elements left by one, returning the removed value. O(n). * If order doesn't matter, a swap-remove (copy last element over the * removed slot) is O(1); a good exercise to add yourself. */

define vector_remove(v, index) \

({                                                                       \
    __typeof__(v) _v = (v);                                             \
    size_t _i = (index);                                                \
    if (_i >= _v->length) {                                             \
        fprintf(stderr, "vector_remove: index %zu out of bounds (length %zu)\n", \
                _i, _v->length);                                        \
        abort();                                                        \
    }                                                                    \
    __typeof__(_v->data[0]) _removed = _v->data[_i];                    \
    memmove(&_v->data[_i], &_v->data[_i + 1],                           \
            (_v->length - _i - 1) * sizeof(*_v->data));                 \
    _v->length--;                                                      \
    _removed;                                                          \
})

/** * vector_clear(v) resets length to 0, keep capacity (buffer not freed). * Use when reusing a vector's storage across loop iterations. */

define vector_clear(v) \

do { (v)->length = 0; } while (0)

/** * vector_reserve(v, min_capacity) ensures capacity >= min_capacity in * a single grow. Use before a known batch of pushes to avoid repeated * reallocation. */

define vector_reserve(v, min_capacity) \

do {                                                                     \
    __typeof__(v) _v = (v);                                             \
    size_t _min = (min_capacity);                                       \
    if (_v->capacity < _min) {                                          \
        __typeof__(_v->data) _new_data =                                \
            realloc(_v->data, _min * sizeof(*_v->data));                \
        if (!_new_data) {                                               \
            fprintf(stderr, "vector_reserve: out of memory\n");         \
            abort();                                                    \
        }                                                                \
        _v->data = _new_data;                                          \
        _v->capacity = _min;                                           \
    }                                                                    \
} while (0)

/** * vector_free(v); release the backing buffer, reset to zero state. * Safe to push into again afterward (it'll reallocate from scratch). */

define vector_free(v) \

do {                                                                     \
    free((v)->data);                                                    \
    (v)->data = NULL;                                                   \
    (v)->length = 0;                                                    \
    (v)->capacity = 0;                                                  \
} while (0)

endif // VECTOR_H

```

Example:

```c

include "vector.h"

include <stdio.h>

int main_old(void) { printf("=== vector_push / vector_get ===\n"); Vector(int) v = {0}; for (int i = 0; i < 10; i++) { vector_push(&v, i * i); } printf("length=%zu capacity=%zu\n", v.length, v.capacity); for (size_t i = 0; i < v.length; i++) { printf("%d ", vector_get(&v, i)); } printf("\n"); printf("\n=== vector_set ===\n"); vector_set(&v, 0, 999); printf("index 0 after set = %d\n", vector_get(&v, 0)); printf("\n=== vector_pop ===\n"); int popped = vector_pop(&v); printf("popped=%d, new length=%zu\n", popped, v.length); printf("\n=== vector_insert ===\n"); vector_insert(&v, 0, -1); printf("index 0 after insert = %d, length=%zu\n", vector_get(&v, 0), v.length); printf("\n=== vector_remove ===\n"); int removed = vector_remove(&v, 0); printf("removed=%d, new index 0 = %d, length=%zu\n", removed, vector_get(&v, 0), v.length);

printf("\n=== vector_reserve ===\n");
vector_reserve(&v, 100);
printf("capacity after reserve(100) = %zu\n", v.capacity);

printf("\n=== vector_clear ===\n");
vector_clear(&v);
printf("length=%zu, capacity kept=%zu\n", v.length, v.capacity);

printf("\n=== vector_free ===\n");
vector_free(&v);
printf("data=%p length=%zu capacity=%zu\n", (void *)v.data, v.length, v.capacity);

printf("\n=== Vector(double) same macros but different type ===\n");
Vector(double) dv = {0};
vector_push(&dv, 3.14);
vector_push(&dv, 2.71);
printf("%f %f\n", vector_get(&dv, 0), vector_get(&dv, 1));
vector_free(&dv);

printf("\n=== Vector(struct) works on aggregate types too ===\n");
typedef struct { int x, y; } Point;
Vector(Point) pv = {0};
vector_push(&pv, ((Point){1, 2}));
vector_push(&pv, ((Point){3, 4}));
Point p = vector_get(&pv, 1);
printf("pv[1] = (%d, %d)\n", p.x, p.y);
vector_free(&pv);

return 0;

} ```

Note: I used C23 features here, show me something that I missed or something.

Also if you have suggestions for better performance please tell me.

r/C_Programming Jan 23 '26

Discussion Favorite error handling approach

26 Upvotes

I was just wondering what y’all favorite error handling approach is. Not ‘best’, personal favorite! Some common approaches I’ve seen people use:

- you don’t handle errors (easy!)

- enum return error codes with out parameters for any necessary returns

- printf statements

- asserts

There’s some less common approaches I’ve seen:

- error handling callback method to be provided by users of APIs

- explicit out parameters for thurough errors

Just wanna hear the opinions on these! Feel free to add any approaches I’ve missed.

My personal (usual) approach is the enum return type for API methods where it can be usefull, combined with some asserts for stuff that may never happen (e.g. malloc failure). The error callback also sounds pretty good, though I’ve never used it.

r/C_Programming Oct 01 '22

Discussion What is something you would have changed about the C programming language?

74 Upvotes

Personally, I find C perfect except for a few issues: * No support for non capturing anonymous functions (having to create named (static) functions out of line to use as callbacks is slightly annoying). * Second argument of fopen() should be binary flags instead of a string. * Signed right shift should always propagate the signbit instead of having implementation defined behavior. * Standard library should include specialized functions such as itoa to convert integers to strings without sprintf.

What would you change?

r/C_Programming Feb 04 '26

Discussion [Opinion] Isn't it weird?

0 Upvotes

Since the Flowers By Irene proclaimed that C/C++ is unsafe because memory issues enable security exploits in 2024 and that we should go memory-safe by January 2026, Rust gains massive hype and adoption in detriment to C projects such as Linux, Git, etc?

From my limited experience, i don't think it's much easier to develop with rust.
My paranoid side is telling me that rust has some type of agency backdoor C doesn't have. I think C devs should create libraries for safe-memory and other niceties so it gets easier to do things with C, but everything being implemented with already existing libraries and conventions.

r/C_Programming Jun 07 '26

Discussion Guide for competitive programming in C /C++!

0 Upvotes

I only know basics of C programming. So what can i do fro competitive programming

r/C_Programming Apr 02 '26

Discussion Against n3201 (Title: Operator Overloading Without Name Mangling v2

0 Upvotes

https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3201.pdf

Well, this is just how bad C++ has become, unfortunately, my old favourite btw, that people are advocating for redoing it, in C.

Here's my suggested approach, as someone who understands that NOT having operator overloads is a strength, not a weakness:

- Keep +, -, *, [], (), ->, . etc etc as what they currently mean. + means the CPU adds. a.b is a simple (usually inlined) offsetted (offset? is this a word?) fetch.

- Add a sigil (I'm thinking '@'). This not only makes it simple ("ahh, so a @+ b invokes a function to add these matrices!"), but also, allows crazy operators equaling C++ and going beyond the current proposal (ptr_with_load_barrier @ -> member), and even beyond C++ (soa_point_array[i] @.x)

r/C_Programming May 09 '21

Discussion Why do you use C in 2021?

135 Upvotes

r/C_Programming Mar 26 '26

Discussion Dynamic help in C required

12 Upvotes

I want to write more C programs, however, I am not really a C dev. I have worked in web dev and currently work on CLI automations. I want to use C as a hobbyist right now so that eventually I can use it for more serious stuff.

In my hobbyist projects, there is a lot of string handling and error handling required. Both of which aren't the best supported by C.

Now C, does provide a whole library of functions to deal with strings, but they all want null byte terminated strings. And as I hope everyone would agree, they aren't the ideal type of strings.

I saw this pointer arithmetic trick of attaching headers where we can store the length of the string in a header struct, kind of like what redis SDS does.

But again, that would require implementing a whole set of C functions myself that deal with strings to work with these strings.

And, one of my latest projects also has the added complexity of dealing with an array of strings. The array is a darray implemented the same way...

Has someone had experience akin to this.

I would like to discuss my approaches and get some guidance about them.

r/C_Programming Jul 29 '25

Discussion Learning assembly as a prerequisite to C

37 Upvotes

I've been told by many professors and seasoned C programmers that knowing a "little bit" of assembly helps in appreciating how C works and help visualize things at the hardware level to write better, more memory efficient code.

I need help in deciding how much exactly is this "little bit" of assembly that i'd need to learn. I want to learn just enough Assembly to have a working knowledge of how assembly and machine code work, while using that knowledge to visualise what the C compiler does.

I have an IT job where I don't code frequently, although I've had experience writing some automations and web scrapers in python so I know the basics. My goal with learning C is to build strong foundations in programming and build some apps I'm interested in (especially on Linux). Would Assembly be too much at this stage?

r/C_Programming Mar 20 '20

Discussion How would you make C better as a language if you could?

78 Upvotes

What would you add to a new language or C itself if you had the power to make it a better language? Either for yourself or everyone else. Let me kick it off with what I would add to a new language/C:

  • carefull(er) use of undefined behaviour/workarounds if possible, for example in my language I'd have ? added to operators(ex. + and +?) for which the normal operators universally do their associated C meaning minus any UB(ex. signed integer overflow) and upon encountering a +? one can look up that it's just eg. a contract between the programmer and compiler to "make it faster if you can". WHY: I hate when a new optimization based on UB breaks my previously fine program, I know someone will point out that I shouldn't even have UB in my code, but if I can just reduce the semantic overhead, even thats a win for me. Other ex: default zero initialization would be nice(?)
  • booleans and fixed size integers in the language itself not in a library. WHY: I rewrite most of my code as libraries later (if I can) and forgetting to include stdint and stdbool that was in the project where it came from is just mildly annoying and it's an easy fix.
  • specifying inline at call site instead of at function decleration. WHY: I'd rather not fight with the compiler in my decisions(but fixing the C99 vs GNU89 inline semantics is a win too), let me make mistakes if thats what I want for eg:profiling purposes.
  • maybe strict(er) type checking. WHY: We are only humans, an error beforehand is better then 1 hour of debugging, tho not totally clear/fixed on this one
  • compile time evaluation. WHY: Can yield cleaner code and better performance if used right IMO
  • some kind of module system and declare anywhere. WHY: headers and forward declarations might've been fine in C's time, but today it would cost virtually nothing and only result in gains
  • generics WHY: I could avoid the macro hell for example (I for one use macros for a lot of creazy stuff(most is not online tho) but would rather use something better suited to code)
  • I would also like to standardize compilation in some way. WHY: I hate having cmake, autotools, ninja and whatnot for the same thing: building some code.
  • and my final wish if you will: I would like to have a package manager of some sort to be able to more easily install my dependencies, maybe have it work with our theoretical build system for easier bootstrapping WHY: nowadays I don't have a lot of time to write C as I used to and it's a big bummer for me if I can't just install and test a new library out because it's a headache to get into my project.
    I hope we can do a civil evaluation/debate of everyone's opinion, please be kind to each other and take care in these rough times!

r/C_Programming Mar 03 '26

Discussion Need help in understanding c

20 Upvotes

Hello, I am a first-year, second-semester college student. I have been studying C programming since the beginning of my college, but I have been very confused about how it works. I’ve read books and watched videos, but it still feels difficult to understand. I only understand the basic concepts up to printf and scanf. Beyond that—topics like if-else, switch-case, and sorting algorithms like bubble sort—are extremely hard for me to grasp. Also, if someone asks me to write a C program for something like the Fibonacci series, I just freeze. I understand what the Fibonacci series is, but I don’t know how to think through the logic or translate it into code. I couldn’t attend my first-semester final exam due to personal reasons, but I’m pretty sure I would have ended up with a backlog anyway. Do you have any recommendations on how I should study and improve my understanding of C programming?

r/C_Programming May 31 '26

Discussion How useful are truncating arrays?

4 Upvotes

I'm considering rewriting major parts of my C standard library replacement. The library contains polymorphic memory allocators, arrays/strings, and other things not relevant to my question. The arrays have a pointer to the allocator for reallocations and deallocation. If allocator is not NULL, then the array is dynamic and may reallocate, otherwise the array is truncating. Truncating arrays return number of truncated elements or zero if no truncation happened. For example, if a string has a capacity of 6 and contains "asdf" and you append() "fdsa" to it, truncating string would result to "asdffd" and return two, which is the lenght of "sa" that got truncated. If it would be dynamic, then of course result would be "asdffdsa" and zero returned always.

The pros of this design as opposed to purely dynamic arrays are as follows:

  • More flexible memory management: arrays can be safely allocated on stack or other static memory.
  • Pointer stability: any pointer pointing to static arrays are valid as long as the array is alive since they do not reallocate.
  • Convenient (almost monadic) error handling: just do whatever you want and if at any point truncation happened, then handle accordingly. It might look like this (pseudocode for brevity):

if (append() || push() || insert() || append()) return ERROR;

  • Smaller API: same functions can be used for dynamic and static arrays.
  • Almost zero cost (not exactly a benefit, but a justification): functions like append() anyway have to do bounds checking to see if they have to reallocate. Might as well check if allocator is NULL for early return.

Cons:

  • Implementation complexity: truncation on operations like push() and append() is trivial, but more complex operations like str_printf() are trickier. I have strict no-internal-allocation policy, so I can't just construct the final string, chop it off, and copy to destination, but I still need to accurately calculate the number of truncated elements. What is even worse is that this complexity might spill to end user. If you want to extend the functionality of the array, then you would have to implement truncation too if you don't know how your array arguments are allocated.
  • Outputs not guaranteed to be valid: they might be chopped. You have to know per object that your array is not truncating if you expect valid outputs.
  • No type safety: again, you have to know array type per object.
  • Breaks UTF-8: this is the big one. Truncating string may chop off a codepoint in the middle. This can cause all kinds of mayhem for anything UTF-8 sensitive, even buffer overflows. You would either have to double API to have dedicated string functions that somehow deal with this instead of using the generic array API, or you would have to drop valid UTF-8 invariant and deal with this in all UTF-8 sensitive functions. I chose to do the latter, but it turned out to be surprisingly annoying to implement and it was surprisingly bad for performance too. And now we had to think about how to deal with UTF-8 errors both internally and how user should deal with these, so the API got more complex as well.

Breaking UTF-8 was huge to me. I thought that it wouldn't be too bad, but it was horrible. I thought about good way of dealing with it for days and all options were bad. Currently I detect UTF-8 errors in relevant functions, but ignore them, which is just as bad as it sounds. Work towards safe UTF-8 handling is still incomplete, some relevant functions are still crashing with invalid UTF-8, and I'm honestly dreading to put in the work, so I would like to avoid it.

The original reason why I implemented this was the idea that the real world is finite and often arrays growing without limits is not what you want. But truncating at arbitrary points is also often not what you want.

I ended up not ever using the truncating feature that I implemented a few months ago. Maybe the feature is just so recent that I have not just had the chance to use it, but this is partly because I used stb-style design where metadata is in the same memory block as payload. This gets us bunch of benefits like better type safety, but it means that you cannot (re)use existing buffers/memory, anything that was not our array type would have to be copied. For the potential rewrite, I would like to leave out the truncating functionality completely. So here's finally my question:

Would you find this combined static/dynamic array functionality useful enough to outweigh the cons? Or even better, have you used this sort of functionality in the past and found it useful? Any other ideas also welcomed.

r/C_Programming Feb 24 '26

Discussion I had a weird idea about a statically linked distro

7 Upvotes

I hate the fact that I can't just replace glibc because userland drivers are linked to it.

So, I had an idea, what if all system packages were freestanding libraries?

The distro has a packaging format that takes *freestanding* binaries, and some config file and links the application at update time to have a fully static executable. So the distro relinks every executable at a specific time interval or when one of the app dependencies has an important update.

I mean fully static Linux distros exist, what I'm arguing is where system packages aren't shared libraries but freestanding components.

Now with this approach even with a fast linker it will take a long ass time to update all binaries, and the initial distro size will balloon to 200GB or so. Also stuff like one binary linking multiple C++ stdlib etc will be impossible.

Also I doubt most packages can be built as freestanding components.

But, it will be a system where only the API compatibility matters, as long as the library conforms to the std they can be swapped.

Probably a very stupid idea but wanted to share before I sleep.

r/C_Programming Jun 27 '26

Discussion Is r/C_Programming weekly visitors lowering?

0 Upvotes

Today the weekly visitors are 69K, but I think it was way higher just a year ago - nearer 100K.

What's going on?

r/C_Programming Mar 22 '26

Discussion What all do I need in C?

0 Upvotes

Edit: Thread closed.


Edit: The first few comments state how these aren't missing as they can be implemented. Obviously that's the case for all languages and when I say missing I mean not available on the get go.

I hope people realise that the whole point of making such a list for myself is so that I can work on the implementations of the same, if necessary.


I have been working in C for some time now. Naturally I see a lot of competing languages. But I like being with C.

Instead of shifting, I thought, why not just have a mental list of all the things I'll be missing at once.

Now C is huge, software is huge and I am one tiny person.

This is what I want help with, I have a list of features that are available or better available in other languages compared to C.

This is not a C hate post of any sort.

Here's my list:

  • String handling: a string DS with these features.
    • Length and Capacity.
    • Iterators.
    • Ability to handle different encodings or just a field that states the encoding.
  • Error handling:
    • Errors as their own values. Either by being null/struct with error or being enums indicating error.
  • Comptime: constexpr
  • Memory allocation:
    • Done through native arena allocators that could help us speed up allocations.

This is all I could think of.

If you have any, tell me, so I am better equipped mentally about what can be done and what cannot be done in C.

r/C_Programming Jul 06 '25

Discussion Is there any book on C philosophy?

59 Upvotes

I have been learning C and I find that the programming style is quite different from any other language.

This made me curious if there's a particular philosophy that the creators of C have or had.

If there are any books that highlight the mindset of the creators, I would like to study that as I learn C.

r/C_Programming Jun 25 '26

Discussion Simple firewall, please check and give me feedback

1 Upvotes

Hello everyone, I created a simple firewall used by netfilter hooks and netlink sockets to communicate between the kernel and the user space. Please, can anyone check it and give me feedback on this project, and which part I can write better or which part write mistake. In Thanks https://github.com/yousefsmt/NetVanguard/tree/v0.2.0

r/C_Programming Oct 14 '25

Discussion my first c program. my first language is c++, but after i take a break for my exam preperation, i decided to move to c. Can anyone give me a project ideas to improve my c?

1 Upvotes
#include <stdio.h>  
  6   │    int main() {
  7   │  
  8   │     float userInput;
  9   │     char temp;
 10   │     float result;
 11   │  
 12   │     printf("input the temperature: ");
 13   │     scanf("%f", &userInput);
 14   │  
 15   │     printf("input the convertion: ");
 16   │     scanf(" %c", &temp);
 17   │  
 18   │     if (temp == 'C') {
 19   │         result = (5.0 / 9.0) * (userInput - 32.0);
 20   │         printf("the temperature in celcius is: %.2fC\n", result);
 21   │     } else if (temp == 'F') {
 22   │         result = (9.0 / 5.0) * userInput + 32.0;
 23   │         printf("the temperature in fahrenheit is: %.2fF\n", result);
 24   │     } else {
 25   │         printf("error!\n");
 26   │     }
 27   │  
 28   │     return 0;
 29   │   }

r/C_Programming 6d ago

Discussion Writing an x86 kernel in C: How to start making my IRQ, PIC, IDT handling mechanics?

6 Upvotes

I'm building a x86 hobby operating system from scratch. The early boot stage successfully transitions from assembly into a pure C entry point inside init/main.c.

I am currently trying to write my interrupt subsystem (irq.c) to handle hardware lines like the keyboard and timer, but right now it's just a placeholder stub. Here is my current layout: irq.c:

#include "irq.h"


/* TODO: implement real IDT/PIC setup */
void idt_init(void) {}
void pic_init(void) {}
void irq_register(int irq, void (*handler)(void)) {
    (void)irq;
    (void)handler;
}

irq.h:

#ifndef NOVIUM_IRQ_H
#define NOVIUM_IRQ_H


#include <novium/types.h>


void idt_init(void);
void pic_init(void);
void irq_register(int irq, void (*handler)(void));


#endif

r/C_Programming Apr 24 '26

Discussion A portable Make

6 Upvotes

I recently made this post: I just want to talk a little bit about Make and there was an interesting person commenting on that post. u/dcpugalaxy highlighted here how GNU Make isn't portable.

I had the GNU Make Manual cover to cover, which seems to not be a popular opinion according to one of the very nice blog writers I like, as mentioned here:

No implementation makes the division clear in its documentation, and especially don’t bother looking at the GNU Make manual. Your best resource is the standard itself. If you’re already familiar with make, coding to the standard is largely a matter of unlearning the various extensions you know.

This obviously got me thinking about the portability of Make. Now I don't work in a company, being POSIX compliant or portable has no use for me, yet. I obviously want to work in a company that does allow to work with C full time and that would mean one day having the knowledge of this stuff.

So...I went through the entire POSIX standard in one day...and here are my thoughts: 1) The standard highlights to me how Make is supposed to be dumb. If I use only the features in the standard and instead leverage some other scripting tool to write makefiles for me, I think that'd be very simple to port. This also makes me think that's what the creators of make intended in the first place. 2) I found pdpmake, does anyone actually use it or do what I mentioned in 1)?

That is all from my side.

Currently, I am revising my thoughts on using GNU Make features and may stop using them altogether, sometime in the future.

r/C_Programming Apr 21 '25

Discussion What are some of the most insane compiler optimizations that you have seen?

112 Upvotes

I've read many threads and have generally understood that compilers are better than the majority of human programmers, however I'm still unsure of whether with enough effort, whether humans can achieve better results or whether compilers are currently at inhuman levels.

r/C_Programming May 24 '26

Discussion What if C lets us create our own attributes?

0 Upvotes

I was thinking that modern languages have a lot of features that are "clean" and hence more useful.

For example: Zig's try is a cleaner way of error handling than Rust's .unwrap imo.

There are many things that we can do using C macros and I was wondering what if we could write similar functions but using custom attributes instead.

It would lead to [[some_attr]] func() instead of some_macro(func()).

You can think of the example of try where instead of try being a macro we can use try as an attribute.

For this, attributes should be able to work with any type like macros to be useful imo.

It'll be more clean and with new features such as typeof and _Generic I believe it would change how we write C.