r/C_Programming

Does alignment padding applies only to structs?

I know depending on the order of variables in struct can have different size but is this the case only for structs or it's also true in other cases? Like will something like this

int main(){

float a ;
char b;
float c;
char d;

return 0;
}

take up more memory than if I grouped it?

float a ;
float c;
char b;
char d;
reddit.com
u/Dragonaax — 10 hours ago

A compilation of many quirks of C?

Every language has tons of "quirks". By quirks, I mean small or hidden unusual behavior or scenarios you don't normally think about. C has lots of such quirks. For example, I just discovered sizeof('a') returns 4 not 1. 'a' defaults to an int. There are so many such quirks I have found but I can't even recall them now. Struct padding, signed overflow UB but unsigned wrap works, string pooling, char array allocates on the stack but char pointer allocates the string in read only memory, and so many more.

I would like a compilation if exists, of all such quirks. This would actually help in MCQ tests.

I have seen that in interviews, they can as the output of - printf("%d", printf("hello"));. Now I know what printf() returns, but most students don't go their way learning this and most institutions don't teach this thoroughly. I don't think this can be classified as a quirk but good to take a look at.

reddit.com
u/noobdainsane — 15 hours ago

Checking inputs efficiently in C

im trying to check inputs in a command line program, using windows api here (runs on command prompt or windows powershell)

if (GetAsyncKeyState(VK_UP))

playerY -= moveSpeed;

else if (GetAsyncKeyState(VK_DOWN))

playerY += moveSpeed;

else if (GetAsyncKeyState(VK_LEFT))

playerX -= moveSpeed;

else if (GetAsyncKeyState(VK_RIGHT))

playerX += moveSpeed;

but is there any way to make it more efficient, 4 system level calls for checking something this trivial is very inefficient? i tried using getkeyboardstate(), but it doesnt work in c. Tried the event driven approach, but it says that it goes through more layers and data structures which brings it back to square one even with low syscalls, im sort of confused

need help pls

reddit.com
u/AskComprehensive7867 — 15 hours ago

How to re-learn C?

Hey guys, I'm a graduate now. Just completed my B.Tech in CSE. Had a c language course in my first semester. I always liked c but couldn't move out of dsa and see how it is used in daily life. Then I later got to know there are complete operating systems running on just c. I later got curious and wanted to read the code and contribute to it. But the major issue is it feels like a xomplete different world when compared to the c I was introduced to. So wanted to ask the community, How to re-learn C?

Please suggest books or lectures or tutorials that let me understand the c we use to build things.

Thanks in advance.

reddit.com
u/seeder1694 — 13 hours ago
▲ 3 r/C_Programming+2 crossposts

I built a DSA library in C and it got selected for an open-source program, looking for contributors

I built C_DSA_interactive_suite, a fully modular, console-based DSA library written entirely in pure C11. No frameworks, no abstractions. Just raw C, manual memory management and real implementations built from scratch. The codebase has a clean modular architecture with one .h/.c pair per module, reusable APIs across modules. A single interactive executable as the entry point, Valgrind-clean memory, CI/CD on every push, and .clang-format enforced style throughout. The project just got selected in SSOC, an open-source program similar to GSoC and I am the project admin, which means this summer, project is open for contributiors! If you've been wanting to:

  • Start your Open Source journey
  • Contribute to a real C codebase with proper architecture and planning
  • Implement something like AVL trees, heaps, priority queues, tries, Dijkstra, or DP
  • Get your hands dirty with actual C, not school level C
  • Have your contribution acknowledged by a reputable community

This is your shot. Everybody else is doing MERN. Come touch some real memory. I'm available to walk anyone through the codebase, clear doubts, explain concepts, or help you get your first PR merged. No gatekeeping. Register as contributor for SSOC. Only 5 days left - https://www.socialsummerofcode.com/ GitHub: https://github.com/darshan2456/C_DSA_interactive_suite Drop a comment or open an issue if you're interested. Let's build something worth putting on a resume.

hows this?

u/Straight_Coffee2028 — 19 hours ago

Can/are Integers still be used as Bools.

This is just for a question I am not gonna switch to ints for bool. But I was wondering if using ints as boolens is reliable ethical and what not.

Example:

int main()
{
    int isRunning = 1;
    while (isRunning != 0)
    {
        {...}
    }
}

Again this is all for questions I am not actually gonna go out of my way to use it.

reddit.com
u/ShizamDaGeek — 24 hours ago

Why learning the C programming is still a good idea

Sharing this short YT video from Salvatore Sanfilippo (creator of Redis) on why learning C is still valuable nowadays. The video is from a year and a half ago. I’m sharing it as source of motivation for anyone learning C right now:) Happy learning!

edit: grammar

youtu.be
u/onceagainagainagain — 15 hours ago

Why does GCC on Windows allocate non-adjacent stack slots for local variables unless & or volatile is used?

#include <stdio.h>

void test01(){
    int b = 0x00454647;
     /* E F G */
    int a = 0x41424344;
     /* A B C D */

    // printf("%p %p\n", &b, &a);   // commented
    // volatile int b = ...;        // or this

    char *p1 = (char *)&a;
    printf("%s\n", p1);
}

Hi everyone,

I'm learning C on Windows using GCC (MinGW), and I noticed a strange behavior about stack layout.

Observation:

  • When I don't take the address of b (&b) and don't use volatile, the variables a and b are not adjacent in memory. When I print the string from &a, I get DCBA followed by garbage.
  • As soon as I add printf("%p", &b); or declare b as volatile, a and b become adjacent (differ by exactly 4 bytes), and I get DCBAGEF as expected.

Interestingly:

  • Clang (on Windows) allocates them adjacent even without & or volatile.
  • GCC on Linux also tends to put them next to each other by default.

Only GCC on Windows (MinGW) shows this "non-adjacent unless address is taken" behavior.

Questions:

  1. What exactly is GCC doing during stack slot allocation in this case?
  2. Why does taking the address (&) or using volatile change the layout so dramatically?
  3. Is this related to some Windows ABI / MinGW specific stack alignment or optimization pass?
  4. Is there any flag (besides -O0) that can make GCC behave more like Clang in terms of stack layout predictability?

I know that the C standard doesn't guarantee stack layout or variable order, but I'm curious about the implementation difference between GCC (Windows) vs Clang/GCC (Linux).

Any insight into GCC's internals (especially stack slot allocation, assign_stack_local, reload pass, etc.) would be greatly appreciated!

Thanks!

reddit.com
u/Sad-Finish2729 — 20 hours ago

gcc unable to create the executable

Hi y'all, I've been trying to learn C and I installed mingw using msys2.

I'm trying to compile the following code:

// hello.c
#include <stdio.h>

int main(void)
{
    printf("Hello, Windows!\n");
    return 0;
}

When running gcc hello.c -o hello.exe, I don't get any executable. I've tried reinstalling mingw, and I've also checked that I'm running the command on the same directory where the file. I also added the particular folder to Windows Defender Exclusion list but still can't get anything done. What am I doing wrong?

Edit: Got it to work by changing my terminal from Powershell to Git Bash.

reddit.com
u/IndoRexian2 — 21 hours ago

Why do very few C tutorials focus on windows platforms?

Hey all! For awhile I have been interested in taking a crack at recreating some C run time libraries on Windows, and I wanted to start by trying to re create Malloc sometime soon. I have however noticed in my endeavors to look at videos and read blogs/articles about people re creating malloc, or other C runtime library functionalities, Everything online I find covering such a topic is always targeting Unix based systems. I would imagine the lack of windows targeted content on re creating these things is a sign that windows does not make it easy to do something like re create the C runtime libraries. Wanted to ask a question here to see if I'm missing something

reddit.com
u/True_Efficiency7329 — 1 day ago

How to read/write a struct into a binary file?

I've tried to follow this answer on SO: https://stackoverflow.com/a/16997175/1984657

However I'm not able to load my character successfully. I do get something back, but when I try to print the name I get a string of unrecognizable characters.

My struct is:

struct Character
{
    char name[8];
    enum CharClass charClass;
    short level;
};

My logic to load or create the character:

#include <stdio.h>
#include <string.h>
#include "character.h"
#include "save_file_manager.h"


struct Character *startup()
{
    struct Character *loadedCharacter = loadPlayerCharacter();

    if (loadedCharacter != NULL)
    {
        printf("Welcome back, %s the %s\n", loadedCharacter->name, getClassString(loadedCharacter->charClass));
        
        return loadedCharacter;
    }


    struct Character createdCharacter;
    struct Character *createdCharacterPtr = &createdCharacter;
    char name[NAME_LENGTH]; 
    int charClass;

    // logic to get name and charClass from user input

    strcpy(createdCharacterPtr->name, name);
    createdCharacterPtr->charClass = charClass;
    createdCharacterPtr->level = 1;
    return createdCharacterPtr;
}

And my save, load and prompt to save functions are:

#include "save_file_manager.h"

#include <stdio.h>
#include <stdlib.h>
#include "character.h"


const char *SAVE_FILE_NAME = "./textrpg.sav";

int savePlayerCharacter(struct Character *character)
{
    FILE *fptr;
    fptr = fopen(SAVE_FILE_NAME, "wb");

    fwrite(character, sizeof(struct Character), 1, fptr);
    fclose(fptr);

    return 0;
}


struct Character *loadPlayerCharacter()
{
    FILE *fptr;


    fptr = fopen(SAVE_FILE_NAME, "rb");


    if (fptr == NULL)
    {
        return NULL;
    }

    struct Character *character = malloc(sizeof(struct Character));
    int amountRead = fread(character, sizeof(struct Character), 1, fptr);

    if (amountRead != 1)
    {
        return NULL;
    }


    fclose(fptr);

    return character;
}

int promptSave(struct Character *playerCharacter)
{
    printf("Would you like to save your character? (y/n)\n");

    char save;
    scanf(" %c", &save);

    if (save == 'y')
    {
        savePlayerCharacter(playerCharacter);
    }


    return 0;
}

I probably missed something obvious, but I don't see it. What am I doing wrong?

Solution: I'm allocating heap memory to the created character in startup now:

struct Character *createdCharacterPtr = malloc(sizeof(struct Character));

Thank you everyone for your help.

u/HouseMFD — 1 day ago

Why Don't Double void Pointers Match Like Single void Pointers?

In the following code, calling test1 doesn't provide a warning, but calling test2 does. Is there a specific reason for this behavior?

void test1(void* x);
void test2(void** x);

int main() {
    int* x1;
    int** x2;

    test1(x1); // ok
    test2(x2); // warning "incompatible pointer type"
}

Edit: I think some people don't understand. I'm asking why void** doesn't match with other x**, not why it doesn't work exactly the same as void*.

reddit.com
u/SeaInformation8764 — 2 days ago
▲ 0 r/C_Programming+1 crossposts

LightBase: Lightweight API & Database Desktop Client

🚀 LightBase

Ultra-performance, bare-metal local development runtime bridge and persistence engine built for high-compute applications.

LightBase decouples heavy disk and outbound network I/O into a standalone, multi-threaded C background daemon, communicating asynchronously with an API gateway over high-speed Linux Unix Domain Sockets (UDS).

🏗️ Architecture Layout

LightBase eliminates high-level framework overhead, garbage collection cycles, and process-blocking runtime constraints by decoupling tasks into independent layer boundaries.

graph TD
    UI[HTML5 Control Center UI] <--> PY[Python Gateway Bridge Server]
    PY -- "Binary TLV Frame Stream (/tmp/lightbase.sock)" --> CORE[C-CORE ASYNC THREAD POOL]
    
    subgraph "C-CORE (libcore.so)"
    CORE --> R1[Arena-Powered SQL Engine]
    CORE --> R2[Stack-Isolated OpenSSL TLS]
    CORE --> R3[Kernel /proc Ring Log Storage]
    CORE --> R4[Database Catalog Scanner]
    end

Layer Responsibilities

  • Frontend UI Layer: A lightweight development client executing async network operations back and forth.
  • API Gateway Layer: A zero-dependency Python routing engine acting as an IPC proxy gateway.
  • Native Systems Core: A high-speed, bare-metal C shared engine processing dynamic allocations, filesystem transactions, and socket forging loops on detached POSIX background threads.

🚀 Core Studio Module Suite

🌐 Module 1: Bare-Metal Environment Manager

Tracks application environments (Development, Staging, and Production) dynamically inside isolated runtime boundaries.

  • Atomic Remapping Swaps: Eliminates sluggish filesystem configuration lookups by pre-allocating an EnvironmentBlock structure directly within a dedicated MemoryArena. Context switches occur in under 1μs via thread-safe atomic pointer reassignments.
  • Fallback Safety Paths: System state transitions are fully guarded against uninitialized pointer exceptions, ensuring backup file parameters handle initial transaction states safely.

🧪 Module 2: Cryptographic API Testing Studio

Provides bare-metal HTTP engine request assembly and transaction benchmarking.

  • Wire Packet Serialization: Leverages stack-allocated sequence spaces to assemble raw wire payloads (GET, POST, PUT, DELETE) with exact specification alignment.
  • Memory Security: Replaces vulnerable variable concatenation with explicit length-bounded tracking (strncat), preventing string overflows when importing large custom data tokens.

🗄️ Module 3: Log-Structured Database Explorer

Powers interactive sidebar schema catalog visualizers and data grids.

  • Catalog Data Harvesting: Bypasses table-scanning bottlenecks by executing targeted schema scans directly against the internal engine catalog (sqlite_master).
  • Tele-Profiling: Measures precise VM bytecode query times using high-resolution monotonic hardware timers (clock_gettime).

🗄️ Append-Only Ring Buffer Telemetry Storage

Ensures high-throughput execution tracking without destroying flash storage sectors.

  • Static File Sizing: Pre-allocates a fixed array block file footprint on disk exactly once during system boot, guaranteeing predictable allocation.
  • Wrap-Around Bit Algebra: Sequences incoming snapshots using sliding timestamp indexes. When the tracking pointer reaches limits (1024 slots), it wraps back to slot 0 instantly.

📊 Performance Benchmarks

LightBase delivers sub-millisecond core processing speeds by bypassing the local network routing stack:

  • Local Database Transaction: ~990.20 μs ($< 1\text{ ms}$ bare-metal execution)
  • Total IPC Roundtrip Gateway Latency: ~1.203 ms (Inclusive of Python decoding and HTTP transport)
  • Outbound HTTP Network Socket Request: Variable based on distance, wrapped with microsecond-accurate tracking via CLOCK_MONOTONIC.

🛠️ Compilation & Installation

Prerequisites

Ensure your host machine runs a modern Linux kernel with cmake, gcc, and uv:

sudo apt update &amp;&amp; sudo apt install cmake build-essential

1. Build the Production Core Library

LightBase employs an out-of-source CMake build pipeline with Link-Time Optimizations (-O3 -march=native -flto -s):

cd core
mkdir -p build_release &amp;&amp; cd build_release

# Configure and build the target layout
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --target install

Assets generated:

  • Public Header: dist/include/engine.h
  • Shared Binary: dist/lib/libcore.so

2. Boot the Intermediary Python Gateway

cd ../../bridge
/usr/bin/uv run python python_bridge.py

The C-Core instantly carves out a high-speed memory socket at /tmp/lightbase.sock upon initialization.

🧠 Memory Design & Safety Assertions

  • Header Symbol Ordering: Enforces a strict structure order: macro directives first, raw packed structural records second, and export function interfaces last to ensure top-down layout translation.
  • Translation Scope Reductions: Centralizes cross-module variables within a shared master header file to keep dependencies clear.
  • Thread Race Protection: Active server file descriptors pass explicitly into separate heap memory pools (malloc) at worker thread creation, isolating context pointers from stack invalidation faults.

📄 License

Licensed under Apache License 2.0

github.com
u/Ok_Sky3062 — 2 days ago

Are missed peephole/canonicalization optimizations worth reporting to GCC/Clang?

I’ve been comparing GCC 15/trunk and Clang on small 32-bit bit-vector expressions, and I’ve found a few proven equivalences where one compiler canonicalizes a pattern while the other does not. The optimized forms typically yield modest scalar speed improvements.

Two examples:

uint32_t is_nonzero = (x | (0u - x)) &gt;&gt; 31;

Clang folds this to `x != 0`, producing a clean `test` / `setne` sequence on x86. GCC, including trunk, currently emits a more literal `neg/or/shr`-style sequence.

uint32_t carry64 = (uint32_t)((((uint64_t)x) + y) &gt;&gt; 32);

uint32_t carrycmp = (x + y) &lt; y; // or &lt; x

return carry64 == carrycmp;

This is mathematically always true for 32-bit unsigned `x` and `y`.

Clang folds the `(x + y) < x` spelling to a constant true result, but not the `(x + y) < y` spelling on the targets I tested. GCC currently does not fold either spelling.

My questions are:

- Do maintainers generally appreciate reports for small peephole/canonicalization misses like these?

- Is there a rough threshold where a pattern is considered too niche to justify the compile-time cost or added middle-end complexity?

- Is it better to file these as separate issues, or group related identities into one report?

I can provide minimal reproducers, Z3 proofs, and benchmark data if useful.

Note: I used AI to clean up the wording of this post. The compiler testing, proofs, and benchmark data were generated by my own scripts.

reddit.com
u/MindlessPapaya8463 — 2 days ago

My own bare-bones dynamic array

About a month ago, somebody posted asking for design advice for a dynamic array. My then advice was to treat the element type as an opaque type T.

I've had my own implementation of such a dynamic array lying around for a while, but finally had a use for it, so I gave it a bit of polish and it's here:

If you wanted it to be even more bare-bones, you could keep only the regular (bounds-checking) functions or the no-check (_nc) functions, whichever you prefer.

u/pjl1967 — 2 days ago

Any Recommendations on C resources for Learning Vulkan?

I was following this tutorial, which is supposed to be "modern" with "up to date" features and practices.

However, I very quickly stumbled upon this piece of code:

auto unsupportedLayerIt = std::ranges::find_if(requiredLayers,
                                               [&amp;layerProperties](auto const &amp;requiredLayer) {
                                               return std::ranges::none_of(layerProperties,
                                                                           [requiredLayer](auto const &amp;layerProperty) { return strcmp(layerProperty.layerName, requiredLayer) == 0; });
                                               });

I'm just stunned. I can't believe cpp people actually write code like this? This just seems insane to me and I kind of hate it.

So I have 2 questions:

  1. Am I in the wrong here? Should I just accept that this is normal and the industry standard and get over it? Or is it just absurd?
  2. If it IS absurd, does anyone have any recommendations for other resources I could learn Vulkan from? I'd prefer if it was just straight up in C or at least very basic features of C++?
reddit.com
u/Undeniable_Dilemma_ — 2 days ago
▲ 141 r/C_Programming+1 crossposts

I love C but I dont like libc that much

I love C, but I don't like its standard library having tons of hidden states (like errno) and error values baked into their returns. A lot of times I have to stop and check the function's documentation just to know which value is actually the error value. It makes me tired.

So, I have spent some of my time making a custom C runtime and libc from scratch in C89. I know it might be bad or wrong in some places, but at least I understand how it all works under the hood now.

Thing i have done so far are: Explicit Allocator - No Hidden State - Builtin Some Basic types

There are still a lot of things that need to be implemented, and currently, it only supports x86_64 Linux.

I would love to hear feedback!

Repo: https://codeberg.org/fanes/flibc

Edit: Added a GitHub mirror for convenience (and in case Codeberg is having downtime!):
https://github.com/byfanes/flibc

u/ByMeno — 3 days ago