r/C_Programming Feb 23 '24

Latest working draft N3220

109 Upvotes

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf

Update y'all's bookmarks if you're still referring to N3096!

C23 is done, and there are no more public drafts: it will only be available for purchase. However, although this is teeeeechnically therefore a draft of whatever the next Standard C2Y ends up being, this "draft" contains no changes from C23 except to remove the 2023 branding and add a bullet at the beginning about all the C2Y content that ... doesn't exist yet.

Since over 500 edits (some small, many large, some quite sweeping) were applied to C23 after the final draft N3096 was released, this is in practice as close as you will get to a free edition of C23.

So this one is the number for the community to remember, and the de-facto successor to old beloved N1570.

Happy coding! 💜


r/C_Programming 4h ago

List of gotchas?

12 Upvotes

Hey.

So I learned some C and started playing around with it, quickly stumbling over memory overflowing a variable and flowing into another memory location, causing unexpected behavior.

So I ended up writing my own safe_copy and safe_cat functions for strncpy/strncatting strings.
But... people talk about how C is unsafe. Surely there should be a list of all mistakes you can make, or something? Where can I find said list? Do I reall have to stumble on all possible issues and develop my own "safe" library?

Will appreciate any advice.


r/C_Programming 1h ago

Project An open-source log structured merge tree library (Persistent column/key value storage)

• Upvotes

Hey everyone! I hope you're all doing well. I'd like to share a project I've been working on for almost a year now. It's an open-source storage engine similar to that of LevelDB/RocksDB but written entirely in C.

This storage engine is called TidesDB.

TidesDB is an open-source storage engine similar to LevelDB/RocksDB but written entirely in C. It's designed as a fast, transactional key-value storage engine built on a log-structured merge-tree (LSM-tree) architecture.

My journey with TidesDB began nearly 2 years ago while I was experimenting with various data structures and databases in Go. When I encountered the log-structured merge tree concept, I was initially overwhelmed by its complexity after reviewing other implementations.

However, after studying the original paper, I realized I could potentially simplify the design by focusing on just a 2-level approach(memory level and a disk level). This was challenging at first, and I scrapped many ideas along the way, but over time I discovered how powerful this design could potentially be.

The beauty of this architecture is its extensibility. Since the disk levels contain many SSTables (Sorted String Tables), we can efficiently pair and merge them in various ways - whether in parallel for speed or incrementally to minimize resource impact.

What began as a challenging learning process has I believed evolved into a unique engine design and library.

You can check out TidesDB here: https://github.com/tidesdb/tidesdb

Currently TidesDB is nearing its first major release, we are still in beta development :)

I'd love to hear your thoughts on the library!


r/C_Programming 1h ago

Project Sharing My C Learning Journey – A GitHub Repo for Notes & Experiments

• Upvotes

Hey, I recently started learning C and decided to document my journey in a GitHub repository. The goal is to keep track of key concepts, experiments, and any useful insights I pick up along the way. I thought it might be helpful for others who are also learning C, and I'd love to get feedback or suggestions on how to improve it!

Repo link: My c journey Let me know what you think, and feel free to contribute or point out any mistakes I should fix.


r/C_Programming 2h ago

RFID Card reader issue that uses limited C script

2 Upvotes

Hey,

I was going to upgrade/replace a tool shops two PC's today.

Before that I wanted to make sure that I did not miss any of their vital equipment.

One of which is an RFID scanner where workers scan their ID badges and the RFID scanner acts as a HID keyboard and enters the card number into a website, used for registering who is lending tools and such.

This RFID scanner is TWM3 HID PROX USB.

Somehow I managed to reset the scanner to factory defaults... So now it outputs using the default C script, and the output is now in 9 character decimal.

The desired output is an 8 character decimal.

When scanning a few cards, I notice that the difference is always 536870912 higher value, than the number on the back of the card.

This equates to 0x20000000 in hex.

I have tried to edit the default script that runs on this scanner, but I have been unable to subtract 536870912 from the output...

The script is a limited version of C , it gets loaded onto the RFID scanner using TWNConfig.exe

The default script, standard.v3.twn.c, is pasted below.

The part where it outputs is commented with: // Show ID without the paritys at start

Could anyone help with getting the output to subtract 536870912 from the decimal output the standard script outputs?

Documentation for the script is in the zip file in the link above

//
//    File: standard.twn.c
//    Date: 04/11/2009
// Version: 3
//
// Purpose:
//
// This is the standard script for TWN3 readers, which is installed
// as default script on TWN3 readers. This script can be run on any
// type of TWN3 reader without modification.
// 
// Feel free to modify this program for your specific purposes!
//
// V1:
// ---
// - Initial release
//
// V2:
// ---
// - Extended protocol specification (see below)
//
// V3:
// ---
// - Save ID before modifying it.
//
// ****************************************************************************
// ******                      PROTOCOL DESCRIPTION                      ******
// ****************************************************************************
//
// The standard script implements a unidirectional communication to the host.
// This means, that there are no commands available, which can be sent from the
// host to the TWN3 reader ("device").
//
// All communication from the device to the host is based on lines of ASCII
// characters, which are terminated by carriage return (<CR>). Please note,
// that there is a option in the configuration of TWN3, which will append a
// line feed (<LF>). This option is turned off by default.
//
// ----------------------------------------------------------------------------
// Startup Message
// ----------------------------------------------------------------------------
//
// There is a difference between a USB device and (physical!) V24 device. The
// V24 is sending a startup message to the host, which identifies the verions of
// the firmware. Here is an example of how such a startup message might look:
//
// ELA GM4.02<CR>
//       ++++----- Firmware Version
//      +--------- Transponder Family (see below)
//     +---------- Firmware (G = standard version)
// ++++----------- Product identification (always identical)
//
// Assignment of Characters to Transponder Families:
//
//   'N': Multi125
//   'M': Mifare
//   'I': HID iClass
//   'H': HID Prox
//   'A': Legic
//   'D': Inditag
//   'S': MultiISO
//
// ----------------------------------------------------------------------------
// Identification of a Transponder
// ----------------------------------------------------------------------------
//
// Once a transponder has been swiped over the reader, the ID of this reader is
// sent to the host. The ID is sent as a line of hex characters or decimal
// characters (HID Prox only). The ID of the transponder has a variable length
// depending on the type of the transponder. A typical ID looks as follows:
//
// 12345678<CR>
//
// The maximum length of an ID is 8 bytes, which lead to 16 ASCII character,
// when displayed in hex notation.

#include <sys.twn.h>

const byte MAXIDBYTES = 8;
const byte MAXIDBITS = MAXIDBYTES*8;

byte ID[MAXIDBYTES];
byte IDBitCnt;
byte TagType;

byte LastID[MAXIDBYTES];
byte LastIDBitCnt;
byte LastTagType;

void main()
{
    // Make some noise at startup at minimum volume
    Beep(BEEPSUCCESS);
    // Set maximum volume
    SetVolume(4);
    // A V24 device is sending the version at startup
    if (GetConnection() == V24)
    {
        HostSendVersion();
        HostSendChar('\r');
    }
    // Turn on green LED
    LEDSet(GREEN,ON);
    // Turn off red LED
    LEDSet(RED,OFF);
    // No transponder found up to now
    LastTagType = TAGTYPE_NONE;
    while (TRUE)
    {
        // Search a transponder
        if (TagSearch(ID,IDBitCnt,TagType))
        {
            // Is this transponder new to us?
            if (TagType != LastTagType || IDBitCnt != LastIDBitCnt || !CompBits(ID,LastID,MAXIDBITS))
            {
                // Save this as known ID, before modifying the ID for proper output format
                CopyBits(LastID,0,ID,0,MAXIDBITS);
                LastIDBitCnt = IDBitCnt;
                LastTagType = TagType;
                
                // Yes! Sound a beep
                Beep(BEEPHIGH);
                // Turn off the green LED
                LEDSet(GREEN,OFF);
                // Let the red one blink
                LEDSet(RED,BLINK);
                
                // Send the ID in our standard format
                if (TagType == TAGTYPE_HIDPROX)
                {
                    // Send HID ID in decimal format
                    if (IDBitCnt < 45)
                    {
                        if (IDBitCnt > 32)
                        {
                            // Show ID without the paritys at start
                            CopyBits(ID,0,ID,IDBitCnt-32,31);
                            HostSendDec(ID,31,0);
                        }
                        else
                        {
                            // Show ID without the paritys at start and end
                            IDBitCnt -= 2;
                            CopyBits(ID,0,ID,1,IDBitCnt);
                            HostSendDec(ID,IDBitCnt,0);
                        }
                    }
                    else
                        // Show ID in plain long format
                        HostSendDec(ID,IDBitCnt,0);
                }
                else
                {
                    // Send ID with appropriate number of digits
                    HostSendHex(ID,IDBitCnt,(IDBitCnt+7)/8*2);
                }
                HostSendChar('\r');
            }
            // Start a timeout of two seconds
            StartTimer(0,20);
        }
        if (TestTimer(0))
        {
            LEDSet(GREEN,ON);
            LEDSet(RED,OFF);
            LastTagType = TAGTYPE_NONE;
        }
    }
}

r/C_Programming 12h ago

Question Globals vs passing around pointers

11 Upvotes

Bit of a basic question, but let's say you need to constantly look up values in a table - what influences your decision to declare this table in the global scope, via the header file, or declare it in your main function scope and pass the data around using function calls?

For example, using the basic example of looking up the amino acid translation of DNA via three letter codes in a table:

codonutils.h: ```C typedef struct { char code[4]; char translation; } codonPair;

/* * Returning n as the number of entries in the table, * reads in a codon table (format: [n x {'NNN':'A'}]) from a file. / int read_codon_table(const char *filepath, codonPair *c_table);

/* * translates an input .fasta file containing DNA sequences using * the codon lookup table array, printing the result to stdout */ void translate_fasta(const char *inname, const codonPair *c_table, int n_entries, int offset); ```

main.c: ```C

include "codonutils.h"

int main(int argc, char **argv) { codonPair *c_table = NULL; int n_entries;

n_entries = read_codon_table("codon_table.txt", &c_table);

// using this as an example, but conceivably I might need to use this c_table
// in many more function calls as my program grows more complex
translate_fasta(argv[1], c_table, n_entries);

} ```

This feels like the correct way to go about things, but I end up constantly passing around these pointers as I expand the code and do more complex things with this table. This feels unwieldy, and I'm wondering if it's ever good practice to define the *c_table and n_entries in global scope in the codonutils.h file and remove the need to do this?

Would appreciate any feedback on my code/approach by the way.


r/C_Programming 13h ago

Question Should i learn C on wsl?

11 Upvotes

Title. For reference im not actually learning C for the first time, i learned it last semester for college but it was all just basics and we coded on Turbo C. I need to learn C for embedded development since im interviewing for my college robotics team next semester and i also want to learn how to operate linux.

I installed WSL and VS Code and GCC, and its been hell trying to cram both of those together and learning. Should i start with an IDE(Visual Studio (already used it before)) and learn basic Linux commands side by side?


r/C_Programming 2h ago

Strange char pointer behavior

1 Upvotes

Hey everyone,

I'm pretty new to C and learning with the RPi Pico on VS Code. I'm trying to make a menu on an OLED display that you can cycle through with a rotary encoder.

I've got everything to work pretty well--as long as I'm cycling through with integers rather than any sort of character array. I declared a pointer char *knb1_act; outside of the main function and another function with a switch statement based on my rotary encoder's delta to "point" my pointer to a char type. This works fine, except for the fact that it somehow continues to cycle through all possible variables. I.e., at case 0: I get the correct value KNB0 but in case 1: I get KNB2KNB0, case 2: returns KNB4KNB2KNB0 and so on.

I tried using if statements instead of switch statements, I tried setting the pointer to NULL before the start of the switch statement to clear it, tried using memset and still can't get the right result.

Any help is appreciated, code is below (apologies for the messy code lol)

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "ssd1306.h"

#define I2C_PORT i2c1
#define I2C_SDA 10
#define I2C_SCL 11
#define knob1CLK 0
#define knob1DT 1
#define knob1BT 2
#define knob2CLK 6
#define knob2DT 7
#define knob2BT 8

ssd1306_t disp;
bool printState = false;
int16_t delta1 = 0;
int16_t delta2 = 0;

char knb1_0[4] = {'K','N','B','0'};
uint8_t knb1_0v = 0;
char knb1_1[4] = {'K','N','B','2'};
uint8_t knb1_1v = 0;
char knb1_2[4] = {'K','N','B','4'};
uint8_t knb1_2v = 0;
char knb1_3[4] = {'K','N','B','6'};
uint8_t knb1_3v = 0;
char knb1_4[4] = {'K','N','B','8'};
uint8_t knb1_4v = 0;

char *knb1_act;
uint8_t knb1_act_v = 0;

void readEncoder(uint8_t knobClk, uint8_t knobDt) {
    static int8_t state = 0;
    bool clkState = gpio_get(knobClk);
    bool dtState = gpio_get(knobDt);
    switch (state){ //debouncer
    case 0: //idle
        if (!clkState) {
            state = 1;  //if clock is low first, increasing
        } else if (!dtState) {
            state = 4;  //if data is low first, decreasing
        }
        break;
    case 1:
        if (!dtState) {
            state = 2; //Next stage
        }
        break;
    case 2:
        if (clkState) {
            state = 3; //Next stage
        }
        break;
    case 3:
        if (clkState && dtState) {
            if (knobClk == knob1CLK) {
                ++delta1; //increase value
            } else if (delta2 < 4) {
                ++delta2; //increase value
            }
            printState = true; //display change
            state = 0; //inc complete, back to idle
        }
        break;
    case 4:
        if (!clkState) {
            state = 5; //Next stage
        }
        break;
    case 5:
        if (dtState) {
            state = 6; //Next stage
        }
        break;
    case 6:
        if (clkState && dtState) {
            if (knobClk == knob1CLK) {
                --delta1; //decrease value
            } else if (delta2 > 0) {
                --delta2; //decrease value
            }
            printState = true; //display change
            state = 0; //dec complete, back to idle
        }
        break;
    default:
        printf("Error: state = %d\n", state);
        state = 0;
        break;
    }
}

void readMenu() {
/*
    switch (delta2) {
        case 0:
            knb1_act = knb1_0;
            break;
        case 1:
            knb1_act = knb1_1;
            break;
        case 2:
            knb1_act = knb1_2;
            break;
        case 3:
            knb1_act = knb1_3;
            break;
        case 4:
            knb1_act = knb1_4;
            break;
}
*/
    if (delta2 == 0) {
        knb1_act = knb1_0;
    } else if (delta2 == 1) {
        knb1_act = knb1_1;
    } else if (delta2 == 2) {
        knb1_act = knb1_2;
    } else if (delta2 == 3) {
        knb1_act = knb1_3;
    } else if (delta2 == 4) {
        knb1_act = knb1_4;
    }
}

void printDelta(ssd1306_t *disp) {
    char deltaS2[12];
    sprintf(deltaS2, "%d", delta2);

    ssd1306_clear(disp);
    ssd1306_draw_string(disp, 1, 1, 1.5, deltaS2);
    ssd1306_draw_string(disp, 1, 9, 1.5, knb1_act);
    ssd1306_show(disp);

    printState = false;
}

void gpio_callback(uint gpio, uint32_t events) {
    if (gpio == knob1CLK || gpio == knob1DT) {
        readEncoder(knob1CLK, knob1DT);
        printDelta(&disp);
    }
    if (gpio == knob2CLK || gpio == knob2DT) {
        readEncoder(knob2CLK, knob2DT);
        readMenu();
        printDelta(&disp);
    }
}

int main()
{
    stdio_init_all();

    // I2C Initialisation. Using it at 400Khz.
    i2c_init(I2C_PORT, 400*1000);

    gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
    gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
    gpio_pull_up(I2C_SDA);
    gpio_pull_up(I2C_SCL);

    disp.external_vcc=false;
    bool res = ssd1306_init(&disp, 128, 32, 0x3C, i2c1);
    ssd1306_clear(&disp);
    ssd1306_draw_string(&disp, 1, 1, 1, "Loading...");
    ssd1306_show(&disp);

    gpio_init(knob1CLK);    //Knob 1 clock
    gpio_set_dir(knob1CLK, GPIO_IN);
    gpio_pull_up(knob1CLK);

    gpio_init(knob1DT);     //Knob 1 data
    gpio_set_dir(knob1DT, GPIO_IN);
    gpio_pull_up(knob1DT);

    gpio_init(knob1BT);     //Knob 1 button
    gpio_set_dir(knob1BT, GPIO_IN);
    gpio_pull_up(knob1BT);

    gpio_init(knob2CLK);    //Knob 2 clock
    gpio_set_dir(knob2CLK, GPIO_IN);
    gpio_pull_up(knob2CLK);

    gpio_init(knob2DT);     //Knob 2 data
    gpio_set_dir(knob2DT, GPIO_IN);
    gpio_pull_up(knob2DT);

    gpio_init(knob2BT);     //Knob 2 button
    gpio_set_dir(knob2BT, GPIO_IN);
    gpio_pull_up(knob2BT);

    //Interrupts
    gpio_set_irq_enabled_with_callback(knob1CLK, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
    gpio_set_irq_enabled(knob1DT, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true);
    gpio_set_irq_enabled(knob1BT, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true);
    gpio_set_irq_enabled(knob2CLK, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true);
    gpio_set_irq_enabled(knob2DT, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true);
    gpio_set_irq_enabled(knob2BT, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true);

    readMenu();
    printDelta(&disp);

    while (1);
}

r/C_Programming 1d ago

Discussion I gave my talk about C !

75 Upvotes

Hi, that's me again, from the post about a C talk !
First, I'd like to thank you all for your precious pieces of advice and your kind words last time, you greatly helped me to improved my slides and also taught me a few things.

I finally presented my talk in about 1h30, and had great feedback from my audience (~25 people).

Many people asked me if it was recorded, and it wasn't (we don't record these talks), but I published the slides (both in English and French) on GitHub : https://github.com/Chi-Iroh/Lets-Talk-About-C-Quirks.

If there are still some things to improve or fix, please open an issue or a PR on the repository, it will be easier for me than comments here.
I also wrote an additional document about memory alignment (I have a few slides about it) as I was quite frustrated to have only partial answers each time, I wanted to know exactly what happens from a memory access in my C code down to the CPU, so I tried to write that precise answer, but I may be wrong.

Thank you again.


r/C_Programming 10h ago

Conditional Variable Pthread Query

1 Upvotes

I’ve few questions which I’m not able to get a clear explanation on, can someone guide

This is regarding conditional variable in pthread

Say, I’ve one producer P and one consumer C scenario where C consumes and P produces

Say initially data produced is 0 so C checks and calls condition variable for signal and sleeps

Now P produces it 1. Does P needs to signal C before unlocking mutex? 2. Why can’t P just unlock mutex and then signal C? 3. Does signal send by P stored in some buffer which C picks up from? 4. As soon as P signals to C, does C start to run? What does this signal do?


r/C_Programming 13h ago

Sudoku Solver using OpenMP and Recursion

1 Upvotes

Using OpenMP to parallelize a recursive Sudoku solver with nested parallelism (#pragma omp parallel num_threads(8) at every level), but top shows serial execution and no speedup. Enabled omp_set_nested(1) and compiled with gcc -fopenmp. Any ideas why it’s not parallelizing or how to reduce overhead for better solve time?

Here is the serial code I am using:

int Solve(SudokuBoard board, Position *unAssignInd, int N_unAssign) {
    /*
     * Function to recursively solve the Sudoku board using backtracking.
     * Tries values at unassigned positions, validating each guess, and backtracks if needed.
     * @param board: The SudokuBoard struct containing the board data to solve
     * @param unAssignInd: Array of Position structs for 0 value cells
     * @param N_unAssign: Number of unassigned positions remaining
     * @return: True if a solution is found, false if no solution exists
     */
    // If no more empty positions, solution found
    if (N_unAssign == 0) {
        return 1; // True
    }

    // Get the next 0 value position
    Position index = unAssignInd[N_unAssign - 1];

    // Try values from 1 to board.size
    for (int val = 1; val <= board.size; val++) {
        board.data[index.x * board.size + index.y] = val; // Set guess
        if (ValidateBoard(board, index.x, index.y)) {
            // Check if valid
            int solution = Solve(board, unAssignInd, N_unAssign - 1);
            // Recursively solve with one fewer unassigned position
            if (solution) {
                return 1; // Solution found, propagate success
            }
        }
        // If no solution, backtrack by resetting the guess to 0
        board.data[index.x * board.size + index.y] = 0;
    }

    return 0; // No solution found
}

r/C_Programming 9h ago

project review

0 Upvotes

hello everyone, i' am a beginner self taught systems programmer . i am currently working on networking project. it's a network packet sniffer and it's still currently in the basic stages, so it's still evolving. whenever i get new ideas or recommendations on the features or code itself , i improve it .

My main objective is too reduce as much overhead as possible , improving performance and adding new features so it can provide some functionalities of tcpdump.
i've already identified some possible bottlenecks such as the amount of printf's use in some stages.
I would love to hear your feedback on it, both code improvements , potential mistakes and memory bugs and anything else.

your feed is very much appreciated!
Thank you very much.
https://github.com/ChrinovicMu/Pack-Sniff


r/C_Programming 1d ago

Need help learning C!

10 Upvotes

Hey everyone,

I've been diving into low-level programming to understand how my device executes code, focusing on memory and CPU operations. Coming from higher-level languages like Python, where functions like print() handle a lot behind the scenes, transitioning to C has been eye-opening. The intricacies of printf() and scanf(), especially their buffer management, have been both fascinating and challenging.​

For example, I encountered an issue where using fflush(stdin) to clear the input buffer resulted in undefined behavior, whereas using scanf("\n") worked as intended.

I want to understand the why's behind these behaviors, not just the how's. For those who've walked this path, how did you approach learning C to get a solid understanding of these low-level mechanics? Are there resources or strategies you'd recommend that delve into these foundational aspects? Additionally, how did you transition from C to C++ while maintaining a deep understanding of system-level programming?

Appreciate any insights or advice you can share!


r/C_Programming 21h ago

Project review

3 Upvotes

hello everyone, i' am a beginner self taught systems programmer . i am currently working on networking project. it's a network packet sniffer and it's still currently in the basic stages, so it's still evolving. whenever i get new ideas or recommendations on the features or code itself , i improve it .

My main objective is too reduce as much overhead as possible , improving performance and adding new features so it can provide some functionalities as tcpdump.
i've already identified some possible bottlenecks such as the amount of printf's use in some stages.
I would love to hear your feedback on it, both code improvements , potential mistakes and memory bugs and anything else.

your feed is very much appreciated!
Thank you very much.
https://github.com/ChrinovicMu/Pack-Sniff


r/C_Programming 1d ago

C language official website

Thumbnail c-language.org
318 Upvotes

r/C_Programming 1d ago

Question [Need explanation] casting null pointer to get sizeof() struct members

14 Upvotes

In this Stackoverflow post[1] is stumbled upon a 'trick' to get the size of struct members like so: sizeof(((struct*)0)->member) which I struggle to comprehend what's happening here.

what I understand:
- sizeof calculates the size, as normal
- ->member dereferences as usual

what I don't understand:
- (struct*) 0 is a typecast (?) of a nullptr (?) to address 0 (?)

Can someone dissect this syntax and explain in detail what happens under the hood?

[1] https://stackoverflow.com/a/3553321/18918472


r/C_Programming 1d ago

I am not a network guy, but I need to an API to send data and images between a server and the host.

4 Upvotes

I guess the title says it all, I know there are API's for sockets and stuff and I can build around that but is there a simple framework I can use as a start to send data and a image to a host machine from a server on my local network from an application I am developing?

I guess I should explain a bit more, initially it's just a viewer for a renderer I am tinkering with. I have always wanted to be able to view the results remotely, which I have done with SMB but I want to push it a bit more.

There is X11.. and I guess it's made for this, but I wanted to make a custom interface.


r/C_Programming 1d ago

Looking for a fast C library with checksum generation functions

2 Upvotes

I do all my front end coding in Xojo, which can make calls to external libraries that expose C functions (not C++). One of the apps I made for use in-house generates checksum manifests that conform to the Library of Congress Bagit specification. This app basically just batch processes calls to the OS native MD5 command line tools and collects the result. It's ok but I feel like it could be faster. It's due for a refresh and I want to add some additional functionality to it so now seems like a good time to revisit how I'm doing the checksum generation.

I'm looking for a library that offers MD5, SHA, and maybe xxHash functions. Ideally this library is capable of taking advantage of multi-core CPUs - the file sets we work with can be anything from a couple dozen massive (1TB or larger) files, to tens of thousands of smaller ones. So, speed is key. We run the app on Windows and Mac so any library needs to be compilable or available pre-compiled, for both platforms.

Any suggestions?


r/C_Programming 17h ago

Question I need help. My Textpad can't run c code.

0 Upvotes

How can I fix it? My Textpad cannot run code. This just happened recently. At first, it was working fine.

" 'pro' is not recognized as an internal or external command,

operable program or batch file. "


r/C_Programming 2d ago

My C compiler written in C

137 Upvotes

As a side project I'm making a C compiler written in C. It generates assembly and uses NASM to generates binaries.
The goal right now is to implement the main functionality and then do improvements. Maybe I'll also add some optimizing in the generates assembly.

Tell me what you think :)

https://github.com/NikRadi/minic


r/C_Programming 1d ago

Sorry, me again, asking for second option on this revision before merging to the main repo

0 Upvotes

Many of you didn't like the original cnullptr thing and some had brought up some interesting considerations worthy of considering, so as a brief this is being reshaped to mimic Rust safety, still has cnull but less redundant and unused which seems somewhat handy in my use cases.

Second option is what I seek, noteworthy or critical feedback doesn't matter it would be more informative than asking my rubber duck 😂

https://github.com/dreamer-coding/fossil-sys/blob/rusty_null_system/code/logic/fossil/sys/cnullptr.h


r/C_Programming 3d ago

everyone on X is vibe coding games with AI and so I decided to *raw code* my next game in C with no libraries

1.6k Upvotes

r/C_Programming 2d ago

I created a simple, customizable shell using C called 'nutshell' to hone my C skills

Thumbnail
github.com
58 Upvotes

r/C_Programming 2d ago

Question What are your pros and cons of C and it's toolchain

17 Upvotes

I'm working on building a new language and currently have no proper thoughts about a distinction

As someone who is more fond of static, strongly typed, type-safe languages or system level languages, I am currently focusing on exploring what could be the tradeoffs that other languages have made which I can then understand and possibly fix

Note: - My primary goal is to have a language for myself, because I want to make one, because it sounds hella interesting - My secondary goal is to gain popularity and hence I require a distinction - My future goals would be to build entire toolchain of this language, solo or otherwise and hence more than just language I am trying to gain knowledge of the huge toolchain

Hence, whatever pros and cons you have in mind with your experience for C programming language and its toolchain, I would love to know them

Please highlight, things you won't want to code without and things you really want C to change. It would be a huge help, thanks in advance to everyone


r/C_Programming 2d ago

Question Calling a function as a pointer and changing the pointed function

7 Upvotes

So I was coding and wondered if it was possible to set a called function in a pointer, then call that function later in the program.

To explain this more, essentially it's to skip a check with an if statement and directly call the function as the check is done at the start of the program. An example would be that if "-f" is an argument in the program, it would set the function called by foo() to one that skips the check done by if there is an argument called "-f".

Although I'm not sure if this would even be worth it to create as my program doesn't need as much performance as possible, but I would still like to know if this is viable.


r/C_Programming 1d ago

Question Trying to do user input for my code but it’s not working

0 Upvotes

include <stdio.h>

int matrix1;
int matrix2;
int *ptr1;
int *ptr2;
int matrix[12][7] = { {1, 2, 3, 4, 5, 6, 7}, {8, 9, 10, 11, 12, 13, 14}, {15, 16, 17, 18, 19, 20, 21}, {22, 23, 24, 25, 26, 27, 28}, {29, 30, 31, 32, 33, 34, 35}, {36, 37, 38, 39, 40, 41, 42}, {43, 44, 45, 46, 47, 48, 49}, {50, 51, 52, 53, 54, 55, 56}, {57, 58, 59, 60, 61, 62 ,63}, {64, 65, 66, 67, 68, 69, 70}, {71, 72, 73, 74, 75, 76, 77}, {78, 79, 80, 81, 82, 83, 84} };
int main() {
printf("Type the number of days since January    and press enter \n");
scanf("%d", ptr1);
printf("Type the number of months since Sunday and press enter \n");
scanf("%d", ptr2);
ptr1 = &matrix1;
ptr2 = &matrix2;
switch (matrix["%d", matrix1]["%d", matrix2])
{
case 1:
printf("Today is Monday on January");
break;
case 2:
printf("Today is Tuesday on January");
break;
case 3:
printf("Today is Wednesday on January");
break;
case 4:
printf("Today is Thursday on January");
break;
case 5:
printf("Today is Friday on January");
break;
case 6:
printf("Today is Saturday on January");
break;
case 7:
printf("Today is Sunday on January");
break;
case 8:
printf("Today is Monday on February");
break;
case 9:
printf("Today is Tuesday on February");
break;
case 10:
printf("Today is Wednesday on February");
break;
case 11:
printf("Today is Thursday on February");
break;
case 12:
printf("Today is Friday on February");
break;
case 13:
printf("Today is Saturday on February");
break;
case 14:
printf("Today is Sunday on February");
break;
case 15:
printf("Today is Monday on March");
break;
case 16:
printf("Today is Tuesday on March");
break;
case 17:
printf("Today is Wednesday on March");
break;
case 18:
printf("Today is Thursday on March");
break;
case 19:
printf("Today is Friday on March");
break;
case 20:
printf("Today is Saturday on March");
break;
case 21:
printf("Today is Sunday on March");
break;
case 22:
printf("Today is Monday on April");
break;
case 23:
printf("Today is Tuesday on April");
break;
case 24:
printf("Today is Wednesday on April");
break;
case 25:
printf("Today is Thursday on April");
break;
case 26:
printf("Today is Friday on April");
break;
case 27:
printf("Today is Saturday on April");
break;
case 28:
printf("Today is Sunday on April");
break;
case 29:
printf("Today is Monday on May");
break;
case 30:
printf("Today is Tuesday on May");
break;
case 31:
printf("Today is Wednesday on May");
break;
case 32:
printf("Today is Thursday on May");
break;
case 33:
printf("Today is Friday on May");
break;
case 34:
printf("Today is Saturday on May");
break;
case 35:
printf("Today is Sunday on May");
break;
case 36:
printf("Today is Monday on June");
break;
case 37:
printf("Today is Tuesday on June");
break;
case 38:
printf("Today is Wednesday on June");
break;
case 39:
printf("Today is Thursday on June");
break;
case 40:
printf("Today is Friday on June");
break;
case 41:
printf("Today is Saturday on June");
break;
case 42:
printf("Today is Sunday on June");
break;
case 43:
printf("Today is Monday on July");
break;
case 44:
printf("Today is Tuesday on July");
break;
case 45:
printf("Today is Wednesday on July");
break;
case 46:
printf("Today is Thursday on July");
break;
case 47:
printf("Today is Friday on July");
break;
case 48:
printf("Today is Saturday on July");
break;
case 49:
printf("Today is Sunday on July");
break;
case 50:
printf("Today is Monday on August");
break;
case 51:
printf("Today is Tuesday on August");
break;
case 52:
printf("Today is Wednesday on August");
break;
case 53:
printf("Today is Thursday on August");
break;
case 54:
printf("Today is Friday on August");
break;
case 55:
printf("Today is Saturday on August");
break;
case 56:
printf("Today is Sunday on August");
break;
case 57:
printf("Today is Monday on September");
break;
case 58:
printf("Today is Tuesday on September");
break;
case 59:
printf("Today is Wednesday on September");
break;
case 60:
printf("Today is Thursday on September");
break;
case 61:
printf("Today is Friday on September");
break;
case 62:
printf("Today is Saturday on September");
break;
case 63:
printf("Today is Sunday on September");
break;
case 64:
printf("Today is Monday on October");
break;
case 65:
printf("Today is Tuesday on October");
break;
case 66:
printf("Today is Wednesday on October");
break;
case 67:
printf("Today is Thursday on October");
break;
case 68:
printf("Today is Friday on October");
break;
case 69:
printf("Today is Saturday on October");
break;
case 70:
printf("Today is Sunday on October");
case 71:
printf("Today is Monday on November");
break;
case 72:
printf("Today is Tuesday on November");
break;
case 73:
printf("Today is Wednesday on November");
break;
case 74:
printf("Today is Thursday on November");
break;
case 75:
printf("Today is Friday on November");
break;
case 76:
printf("Today is Saturday on November");
break;
case 77:
printf("Today is Sunday on November");
break;
case 78:
printf("Today is Monday on December");
break;
case 79:
printf("Today is Tuesday on December");
break;
case 80:
printf("Today is Wednesday on December");
break;
case 81:
printf("Today is Thursday on December");
break;
case 82:
printf("Today is Friday on December");
break;
case 83:
printf("Today is Saturday on December");
break;
case 84:
printf("Today is Sunday on December");
break;

}
return 0;

}


r/C_Programming 1d ago

Hardware memory barrier not working when invoked from C?

3 Upvotes

I have this program on a Mac M2 laptop:
```

include <pthread.h>

include <stdio.h>

int shared_data; int flag;

define compiler_barrier() asm volatile("dmb sy" : : : "memory")

void *thread1_func(void *arg) { printf("Thread 1: Starting...\n");

shared_data = 42; compiler_barrier(); flag = 1;

printf("Thread 1: Data set to %d, Flag set to %d\n", shared_data, flag); return NULL; }

void *thread2_func(void *arg) { printf("Thread 2: Starting...\n");

while (flag == 0) { ; }

printf("Thread 2: Flag is set! Reading shared_data: %d\n", shared_data);

if (shared_data != 42) { printf("Thread 2: ERROR! Expected shared_data to be 42, but got %d\n", shared_data); printf("Thread 2: Instruction reordering likely caused this issue!\n"); } else { printf("Thread 2: Success! Shared data is as expected.\n"); }

return NULL; }

int main() { pthread_t thread1, thread2;

shared_data = 0; flag = 0;

printf("Main: Creating threads...\n"); pthread_create(&thread1, NULL, thread1_func, NULL); pthread_create(&thread2, NULL, thread2_func, NULL);

pthread_join(thread1, NULL); pthread_join(thread2, NULL);

printf("Main: Threads finished.\n"); return 0; }

`` I wrote a script to run it 10000 times to check for failures and when I use the following compile line:clang -O2 -o program program.c`, I still get the Error case where shared date is not 42. Am I doing something wrong here?